随机问题。
我正在尝试创建一个程序,该程序将生成伪随机分布。我正在尝试找到适合我需要的正确的伪随机算法。这些是我的担忧:
1)我需要一个输入才能在每次使用时生成相同的输出。
2)必须足够随机,以便查看输入1的输出的人看不到它与输入2的输出(等等)之间的联系,但是不需要密码安全或真正随机。
3)其输出应为0到(29 ^ 3200)-1之间的数字,并且该范围内的每个可能整数都可能是一个相等(或接近它)的可能输出。
4)我希望能够保证410个输出的序列的每个可能排列也是连续输入的潜在输出。换句话说,0和(29 ^ 3200)-1之间的410个整数的所有可能的分组应该是顺序输入的潜在输出。
5)我希望函数是可逆的,这样我可以采用一个整数或一系列整数,并说出哪个输入或一系列输入将产生该结果。
到目前为止,我开发的方法是通过简单的halson序列运行输入:
boost::multiprecision::mpz_int denominator = 1; boost::multiprecision::mpz_int numerator = 0; while (input>0) { denominator *=3; numerator = numerator * 3 + (input%3); input = input/3; }
并将结果乘以29 ^ 3200。它满足1-3的要求,但不满足4。并且它仅对单个整数是可逆的,对于序列是不可逆的(因为不是所有序列都可以由它产生)。我正在使用Boost multiprecision在C ++中工作。
有人可以给我关于生成满足这些要求的随机分布的任何建议,或者仅仅是一类值得为此目的进行研究的算法,我将不胜感激。预先感谢您考虑我的问题。
-—更新----
由于多个评论者都集中在所讨论数字的大小上,我只是想表明我已经意识到使用此类集合所带来的实际问题,但是在提出这个问题时,我只对解决问题的理论或概念方法感兴趣。问题- 例如,想象一下使用更小的整数集(例如0到99)以及10个输出序列的集合的排列。您如何设计一种算法来满足这五个条件-1)输入是确定性的,2)出现随机的(至少对人眼而言),3)范围内的每个整数都是可能的输出,4)不仅所有值,而且值序列的所有排列都是可能的输出,5)函数是可逆的。
-第二次更新-
非常感谢@Severin Pappadeux,我能够反转lcg。我以为我会做些什么,希望将来使任何人看到它都更容易。首先,这些是反转模块化功能的绝佳资源:
https://www.khanacademy.org/computing/computer- science/cryptography/modarithmetic/a/modular- inverses
https://www.khanacademy.org/computer-programming/discrete-reciprocal- mod-m/6253215254052864
如果采用等式next = ax + c%m,则将以下代码与a和m的值一起使用将打印出您需要找到反值以及反值的欧几里得方程:
int qarray[12]; qarray[0]=0; qarray[1]=1; int i =2; int reset = m; while (m % a >0) { int remainder=m%a; int quotient=m/a; std::cout << m << " = " << quotient << "*" << a << " + " << remainder << "\n"; qarray[i] =qarray[i-2]-(qarray[i-1]*quotient); m=a; a=remainder; i++; } if (qarray[i-1]<0) {qarray[i-1]+=reset;} std::cout << qarray[i-1] << "\n";
我花了一段时间才弄清楚的另一件事是,如果得到否定的结果,则应在其上加上m。您应该在新方程式中添加一个类似的术语:
prev = (ainverse(next-c))%m; if (prev<0) {prev+=m;}
我希望这对将来冒险的人有所帮助。
好的,我不确定是否有一个一般性的答案,所以我将专注于具有例如64位内部状态/种子,产生64位输出并具有2 ^ 64-1周期的随机数生成器。我特别要看一下线性同余生成器(又名LCG),其形式为
next = (a * prev + c) mod m
在哪里a和m彼此互质
a
m
所以:
1)检查
2)检查
3)检查(当然,要保留64位空间)
4)检查(同样,我相信除了0以外,但64位的每个排列都是从LCG的某些种子开始输出的)
5)检查。LCG是可逆的,即可以
prev = (next - c) * a_inv mod m
其中a_inv可以从计算a,m使用Euclid算法
好吧,如果您觉得还可以,则可以尝试在15546位空间中实现LCG
更新
快速搜索在此处显示可逆的LCG讨论/代码