- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我可以使用两种方法中的一种来创建具有两个重要特征的伪随机数序列 - (1) 它可以在不同的机器上重现,并且 (2) 该序列从不重复范围内的数字,直到所有数字都被发出.
我的问题是 - 这些方法中的任何一种在可移植性(操作系统、Python 版本等)方面是否存在潜在问题?例如,有谁知道当 XXX 为真时我是否会在一个系统上获得一组结果而在另一个系统上获得不同的结果?
我并不是真的征求关于使用哪种方法本身的建议,只是当 Z 为真时我应该注意 Y 系统上的 X。
我试过几个 Linux 版本,都是 64 位的,它们看起来一致,但我无法轻松访问 Windows 或 32 位版本。
请注意,它们不会产生彼此相同的范围,但这对我来说没问题。这些数字只需要在人眼看来是随机的。
方法 1
使用 native Python 库函数从一个范围内生成一个随机样本。如果我使用大范围(10m 或更大),它会很慢,但对于相对较小的范围来说还可以,并且对于没有数学学位的人来说更容易理解:
import random
random.seed(5)
x = random.sample(range(10000,99999),89999)
for i in range(10):
print(x[i])
方法 2
使用的算法不是来自 Python 库:
( https://en.wikipedia.org/wiki/Linear_congruential_generator )
即使对于大范围,它也非常快,但更难理解,因此发现潜在问题:
def lcg(modulus, a, c, seed):
while True:
seed = (a * seed + c) % modulus
yield seed
m = 10000019
c = int(m/2)
a = 5653
s = a
g = lcg(m,a,c,s)
for _ in range(10):
print(next(g))
请注意,我对其他选择持开放态度;最初的问题是在这里提出的:https://math.stackexchange.com/questions/3289084/generate-a-pseudo-random-predictable-non-repeating-integer-sequence-purely-math
最佳答案
大多数便携版本,IMO,将是周期等于机器自然字大小的 LCG。它为模块使用寄存器溢出,使其更快。你必须使用 NumPy 数据类型来做到这一点,这里是简单的代码,常量 a、c 取自表 4 here
import numpy as np
def LCG(seed: np.uint64, a: np.uint64, c: np.uint64) -> np.uint64:
with np.errstate(over='ignore'):
while True:
seed = (a * seed + c)
yield seed
a = np.uint64(2862933555777941757)
c = np.uint64(1)
rng64 = LCG(np.uint64(17), a, c)
print(next(rng64))
print(next(rng64))
print(next(rng64))
Linux x64 和 Windows x64 以及 OS X VM 的工作方式完全相同。
关于可重复性,唯一的好处是存储前几个数字并在应用程序初始化阶段将它们与 LCG 输出进行比较 - 如果它们没问题,您可以继续进行。
我喜欢 LCG 的另一个特点是它能够在 log2(N) 时间内向前跳跃,其中 N 是跳跃次数。我可以为您提供代码来做到这一点。使用 jump ahead 可以确保并行独立随机流的非重叠序列
更新
这里是我的 C 代码到 Python/NumPy 的翻译,似乎有效。它可以在对数时间向前和向后跳跃。
import numpy as np
class LCG(object):
UZERO: np.uint64 = np.uint64(0)
UONE : np.uint64 = np.uint64(1)
def __init__(self, seed: np.uint64, a: np.uint64, c: np.uint64) -> None:
self._seed: np.uint64 = np.uint64(seed)
self._a : np.uint64 = np.uint64(a)
self._c : np.uint64 = np.uint64(c)
def next(self) -> np.uint64:
self._seed = self._a * self._seed + self._c
return self._seed
def seed(self) -> np.uint64:
return self._seed
def set_seed(self, seed: np.uint64) -> np.uint64:
self._seed = seed
def skip(self, ns: np.int64) -> None:
"""
Signed argument - skip forward as well as backward
The algorithm here to determine the parameters used to skip ahead is
described in the paper F. Brown, "Random Number Generation with Arbitrary Stride,"
Trans. Am. Nucl. Soc. (Nov. 1994). This algorithm is able to skip ahead in
O(log2(N)) operations instead of O(N). It computes parameters
A and C which can then be used to find x_N = A*x_0 + C mod 2^M.
"""
nskip: np.uint64 = np.uint64(ns)
a: np.uint64 = self._a
c: np.uint64 = self._c
a_next: np.uint64 = LCG.UONE
c_next: np.uint64 = LCG.UZERO
while nskip > LCG.UZERO:
if (nskip & LCG.UONE) != LCG.UZERO:
a_next = a_next * a
c_next = c_next * a + c
c = (a + LCG.UONE) * c
a = a * a
nskip = nskip >> LCG.UONE
self._seed = a_next * self._seed + c_next
np.seterr(over='ignore')
a = np.uint64(2862933555777941757)
c = np.uint64(1)
seed = np.uint64(1)
rng64 = LCG(seed, a, c) # initialization
print(rng64.next())
print(rng64.next())
print(rng64.next())
rng64.skip(-3) # back by 3
print(rng64.next())
print(rng64.next())
print(rng64.next())
rng64.skip(-3) # back by 3
rng64.skip(2) # forward by 2
print(rng64.next())
无论如何,LCG RNG 的总结:
关于python - RNG 技术的便携性和可重复性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56983355/
我开发了一个 RNG 算法并生成随机数,现在我想测试生成的输出的随机性。我从 nist(sts) 下载了一个测试套件。有一个选项可以提供输入二进制文件来测试随机性。但我不知道如何生成这些二进制文件。我
因此,我编写了一个函数(以及一个 RNG 函数,上述函数调用该函数)来将随机数量的星号打印到控制台窗口,直到达到 90 个空格。星号代表汽车的运动,90个空格是轨道的长度。下面我包含的代码打印随机数量
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我正在尝试为我的模拟器重现一些行为。 我有一个百分比支票,从 30% 到 70% 不等。问题是它不是严格随机的。这是我提取的实时数据: https://docs.google.com/spreadsh
这个问题在这里已经有了答案: How to generate a random integer in the range [0,n] from a stream of random bits wit
我目前正在实现一个代表 52 张牌的牌组的 Deck 类。它使用 boost Random 库来洗牌代表卡片的整数。 #include #include #include "constants.h
在本文的最后一个示例 (http://www.daniweb.com/software-development/cpp/threads/1769/c-random-numbers) 中,作者声称这是一
我想使用 在我的 C++ 应用程序中使用多个 RNG .播种它们的最佳方法是什么?我担心当使用来自单个 RNG 的随机数为每个 RNG 播种时,来自不同 RNG 的随机数会过于相关。 最佳答案 如果
现在我正在使用 Mersenne Twister RNG 并执行 Fisher-Yates 洗牌算法 100 次: std::vector shufCards; for(int i =
我正在开发一款纸牌游戏,我需要洗牌算法来做得很好,并且每次游戏运行时都不同,并且没有可预测的纸牌序列。 我正在使用 Mersenne twister 算法,但它仍然需要一个种子,所以实际上,虽然它产生
我可以使用两种方法中的一种来创建具有两个重要特征的伪随机数序列 - (1) 它可以在不同的机器上重现,并且 (2) 该序列从不重复范围内的数字,直到所有数字都被发出. 我的问题是 - 这些方法中的任何
我有一段冗长而复杂的源代码,它使用带有修复种子的随机数生成器。 这段代码是一个模拟器,这个模拟器的参数就是这个RNG给出的随机值。当我在同一台机器上执行代码时,无论我尝试多少次,输出都是一样的。但是当
我在想这个问题。我听说全局变量不好,它们会损害代码的可维护性、可用性、可重用性等。但在这种情况下,我还能做什么呢?也就是说,我有一个“伪随机数生成器”(PRNG),正如人们所知,它们涉及一种内部状态,
回复 this question我运行了以下 VBA 实验: Sub Test() Dim i As Long, A As Variant Dim count1 As Long, co
我知道我可以用例如设置 RNGversion RNGversion("3.5.2") 但是是否可以查询我当前使用的 R 版本? 编辑: 我的问题是版本 3.6.0 发生了一些变化,这在 RNGkind
我今天刚开始学习JavaScript,这个很简单的问题给我带来了麻烦。这只是较大代码段的一部分,但我将其隔离以尝试修复它。这是: document.write(blarg()); func
我制作了一个随机数生成器,如果有人在没有数字的情况下使用它,它会崩溃如何确保用户输入是否是字符串,它不会崩溃,而是说“无效参数”? static int random; static String s
好吧,我正在编写一个与 cpu 对抗的程序,但每次它都会先失败然后致命,我会分解我的代码,以便让你们更容易提供帮助。 进口: import javax.swing.JOptionPane; impor
我的问题是http://rcpp-devel.r-forge.r-project.narkive.com/qJMEsvOK/setting-the-r-random-seed-from-rcpp的后续
作为一个学习 Haskell 的 Java 人,我已经习惯了思考一切的新方法,但我花了半天时间尝试用简单的 RNG 实现一些东西,但一无所获。在 Java 中,我可以创建一个静态 RNG 并使用 Cl
我是一名优秀的程序员,十分优秀!