3

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

例如,我想象的可能应用程序是像素交叉淡入淡出图形例程之一,您可以将屏幕上的旧图片逐个像素地替换为新图片。坐标应随机选择,一旦像素被替换,不应再次寻址(无重复)。所有这些自然而然地通过一个基于数学的小型、快速和高效的函数(使用内存很容易实现,但这不是我想要的)。

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

你能帮忙吗?

4

4 回答 4

3

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

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

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

对于您的要求,这可能看起来足够随机。

于 2012-08-02T10:05:36.443 回答
1

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

于 2012-08-02T12:27:33.937 回答
0

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

于 2012-08-02T09:59:38.357 回答
0

rand()功能已经这样做了。虽然,它不是从输入中获取数字,而是获取一个存储值,该值由srand()每次调用初始化并更改rand()

您可以查看实现rand()以获得您的功能,或研究更多关于随机数生成

这里有一个提示:

首先,了解什么是模运算

现在想象以下序列:

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给定和b对于给定的一个好的选择m,你可以获得看起来有点随机的数字。

这样,您的功能需要做的就是(a * argument + b) % m.

于 2012-08-02T10:00:13.973 回答