What is the algorithm used by php shuffle function or where can i get its code. I have to implement it in C language. I have implemented fisher yates algo in C but not good results as showed by php shuffle function.
1条回答 默认 最新
- dtihe8614 2010-11-12 07:39关注
What exactly constitutes "not good results"?
The Fisher-Yates shuffle will produce all permutations with equal probability, but only if you generate your random numbers correctly. There's three issues to be aware of here. First, you need a good pseudorandom number generator. The C standard library
rand
usually is not a good PRNG (though it depends on your C library implementation). If you're on a POSIX platform, consider usinglrand48
instead. Your system may have other RNGs. If you don't have anything on your platform, a pretty good RNG in very little code is G. Marsaglias KISS generator - you can find the code here. Second, if you still decide to userand
, be aware that it will generate random numbers between 0 andRAND_MAX
. For lots of implementations,RAND_MAX
is only 32767, so the usualrand() % count
will have a very obvious and bad bias ifcount
is larger than 32768. Third,rand() % count
(orlrand48() % count
or anything similar) is actually a bad idea too, because it too introduces a bias. Ifcount
isn't a power of 2, some numbers will have a higher probability than others. Also, in a lot of generators, the low-order bits are a lot less random than the high-order bits. You can try to work around this by using(long long) rand() * count / RAND_MAX
or something similar, but really you're better of using a good RNG instead.The proper way to generate unbiased random numbers between 0 (inclusive) and
k
(exclusive) is this: First, get a proper PRNG that gives you a large-enough random number (say 32 random bits). Then reduce to the next power of 2 larger thank
. Finally, if the value is greater than or equal tok
, try again. This is a completely unbiased method, and will give results that are as good as your PRNG can make them. The code looks something like this:static unsigned int random(unsigned int k) { // You can get rid of this loop using bit tricks, but I keep it for clarity unsigned int n, nextpow2 = 1; while (nextpow2 < k) nextpow2 *= 2; do { n = random32() & (nextpow2 - 1); // random32 is your 32-bit RNG } while (n >= k); return n; }
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 孟德尔随机化结果不一致
- ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
- ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
- ¥15 谁有desed数据集呀
- ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
- ¥15 关于#hadoop#的问题
- ¥15 (标签-Python|关键词-socket)
- ¥15 keil里为什么main.c定义的函数在it.c调用不了
- ¥50 切换TabTip键盘的输入法
- ¥15 可否在不同线程中调用封装数据库操作的类