我在这里读了几篇关于生成没有重复的随机序列的帖子(例如Create Random Number Sequence with No Repeats),并决定根据自己的需要实现它
实际上,这是一种算法,它使用当前计数器的某些位来应用一些非破坏性(可逆)操作,以便获得一个只应出现一次的伪随机数。由于操作是可逆的,因此不同的源编号将给出不同的结果编号。
至少有几种操作可能,例如交换两位,反转一位,循环移位。如果我们只使用上面提到的那些,那么序列的质量将不会很好,因为附近的计数器将产生具有相似数量的零和1的结果。真正的游戏改变者是xor一点一点。现在序列看起来好多了,但问题是:
更新:正如我在此处发表的评论中所述,已经存在这样的生成器:AES加密,但不幸的是它只能用于128位范围。
由于
最高
答案 0 :(得分:2)
<强>问题:强>
生成1到N之间的唯一随机整数列表。
<强>解决方案:强>
在Matlab中:
z = rand( [N 1] );
[dummy iz] = sort(z);
%iz是你的清单。
答案 1 :(得分:1)
除非你有充分的理由,否则你不想重新发明伪随机生成。很可能会出错。我建议从A [i] = i
的数组开始然后这样做:
for (i=0; i< n; i++) {
j = random_number_between(i,n-1);
swap(A[i],A[j]);
}
修改强> 这是对以下评论的回应:
您希望序列的随机性如何。注意,随机选择的排列中的固有信息是log(n!),其接近n / e位。因此,您确实需要生成许多随机位。既然你想要在我认为的任何地方存储这些许多随机比特(更像是一种直觉而不是数学证据),如果没有那么多的存储,就很难做出真正的随机排列。
但是如果你只想要一个不容易逆向工程的序列,你可以一个接一个地连接多个1:1函数。 我想到两件事: - 保持计数器i的顺序为0到N-1。
在i上执行log_2(N / 2)位翻转,当你开始序列时,随机选择要翻转的位。
使用上述方法在序列开头的log_2(N)位上生成随机置换,然后交换上面结果中的位。
求一个随机数r1,它是n at的相对素数,另一个是0和n-1之间的随机数r2。你的第i个数字是= r2 ^ r%n。
这些的一些组合应该给你一个难以逆向工程序列。关键是你注入的随机位越多,就越难以进行逆向工程。
我想到的一件事是,如果您的范围是0..N-1,只需找到一个大数P,它是N的相对素数并选择另一个随机数