随机问题。
我正在尝试创建一个可以生成伪随机分布的程序。我正在尝试找到适合我的需求的伪随机算法。这些是我的担忧:
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;
}
Run Code Online (Sandbox Code Playgroud)
并将结果乘以 29^3200。它满足要求 1-3,但不满足 4。并且它仅对于单个整数是可逆的,而不是序列(因为并非所有序列都可以由它产生)。我正在 C++ 中工作,使用 boost 多精度。
有人可以给我任何关于生成满足这些要求的随机分布的方法的建议,或者只是一类值得为此目的研究的算法,我将不胜感激。预先感谢您考虑我的问题。
- - 更新 - -
由于多个评论者都关注相关数字的大小,我只是想明确表示,我认识到使用此类集合所带来的实际问题,但在提出这个问题时,我只对理论或概念方法感兴趣问题 - 例如,想象一下使用更小的整数集(如 0 到 99),以及 10 个输出序列的排列。您将如何设计一个算法来满足这五个条件 - 1)输入是确定性的,2)看起来是随机的(至少对于人眼来说),3)范围内的每个整数都是可能的输出,4)不仅仅是所有值,而且值序列的所有排列都是可能的输出,5)函数是可逆的。
---第二次更新---
非常感谢@Severin Pappadeux,我能够反转 lcg。我想我应该添加一些关于我所做的事情,希望能让将来看到这一点的人更容易。首先,这些是关于反模函数的优秀资源:
我正在使用Collections.shuffle(list);
洗牌列表,但我不知道如何取消洗牌?我正在考虑在洗牌之前保存列表然后将其洗牌以便维护备份并且可以在需要时重新恢复,但这似乎效率低下这样做的方式,将占用时间和记忆....如果你知道一个更合乎逻辑的方式,你能详细说明吗?顺便说一句,这是我的应用程序的样子:D


我知道如何获得0到零之间的一系列随机数.
但我想知道的是,由于随机数生成器不是真正随机的,并且遵循特定的算法,例如,如果传递20的种子,那么它将始终生成相同的数字序列:17,292,0 ,9.
所以我明白了.由于它遵循特定的算法,有没有办法可以强制生成器始终从零或任何其他数字开始?
但在我的情况下特别为零.