普通C中的快速随机shuffle函数

时间:2012-08-02 09:56:16

标签: c function random shuffle

多年来我一直在考虑这个问题,但从未设法实现过。我在谈论一个快速,高效的C函数,它接受输入中的整数数值(例如16位),并在输出中给出完全不同数量的相同位大小,但“考虑”所有的数字已经给出了,虽然不是通过使用真实记忆,而是通过数学魔术。对不起,英语不是我的母语,我的意思是该函数应该随机地一对一映射,但没有任何重复。

我想象的可能的应用程序是例如像素交叉淡入淡出图形例程之一,用一个像素逐像素替换屏幕上的旧图片。应该随机选择坐标,一旦替换了一个像素,就不应再次对它进行处理(不重复)。所有这一切自然地通过一个小的,快速和有效的函数基于数学(使用内存很容易实现它,但它不是我想要的)。

显然,“位反转”解决方案不起作用,因为它看起来不随机。甚至交换,例如第3位与第11位等等。创造更多“混乱”,反转一些比特等等。看起来并不好看,所以我正在寻找一个纯粹的数学,真正随意的功能,能够至少16位,并使用尽可能少的内存(没有预先计算的表,因为我最终使用它的第一个应用程序是在微控制器系统上使用公共域硬件和软件制作旧式游戏)。

你能帮帮忙吗?

4 个答案:

答案 0 :(得分:3)

您正在寻找的是基本上与您想要交叉淡入淡出的像素数对应的组的循环生成器。在最一般的情况下,这是你团体规模的任何互质。通过以你的像素数为模的所有计算方式,你得到随机性的外观,而不是实际上是随机的。

假设您有一个大小为32的域,并以5的种子开头。通过不断添加15的互质,您将得到

的序列
  

(5,20,3,18,1,16,31,14,29,12,27,10,25,8,23,4 ......)

根据您的要求,这似乎是随机的。

答案 1 :(得分:1)

另一种选择是使用加密。由于加密是可逆的,因此每种加密都是唯一的。对于64位数,请使用DES。对于16位或32位数字,请使用Hasty Pudding Cipher。您也可以将Hasty Pudding用于任何所需的范围,而不仅仅是2的幂。

答案 2 :(得分:0)

你先生非常需要哈希函数。试试例如a =(a * 31)%0xffff;对于一个穷人。

答案 3 :(得分:0)

rand()功能已经执行此操作。虽然不是从输入中获取数字,但它会使用srand()初始化的存储值,并在每次调用rand()时更改。

您可以查看rand()的实施情况以获取您的功能,也可以在random number generation上了解更多信息。

这是一个提示:

首先,了解什么是modular arithmetic

现在想象以下序列:

m = 13
a = 7
b = 0

s = 5     s = (a*s + b) % m
s = 9     s = (a*s + b) % m
s = 11    s = (a*s + b) % m
s = 12    s = (a*s + b) % m
s = 6     s = (a*s + b) % m
s = 3     s = (a*s + b) % m
s = 8     s = (a*s + b) % m
s = 4     s = (a*s + b) % m
s = 2     s = (a*s + b) % m
s = 1     s = (a*s + b) % m
s = 7     s = (a*s + b) % m
s = 10    s = (a*s + b) % m
s = 5     s = (a*s + b) % m

请注意,在这种情况下,我将b=0设置为更容易找到序列。然而,这个例子并不是很好,但你得到了要点。如果给定a选择bm,您可以获得有点随机的数字。

这样,您的所有功能都需要(a * argument + b) % m