lea*_*ner 5 python random sample integer-overflow python-3.x
我正在运行一段简单的代码来返回和batch之间的整数数量(无需替换)。02**63
from random import sample
batch = 1000
n = 63
rand_nos = sample(range(2**n), batch)
Run Code Online (Sandbox Code Playgroud)
我收到错误
Python int too large to convert to C ssize_t
Run Code Online (Sandbox Code Playgroud)
random.sample我认为这与函数内部将范围长度转换为值有关int。但我找不到任何可以设置的参数,要求函数使用更大范围的数据类型。我该怎么办?谢谢。
好的,您可以尝试使用Linear Congruential Generator,它有一些有趣的属性 - 通过良好的常量选择,它将覆盖整个范围 [0...2 n ) 一次,在到达周期之前不会重复。因此,它基本上相当于无放回抽样。
n=64 的代码,如果您正好需要 63,我可以找出一组常数,只需询问即可。
Python 3.9.1、Win10 x64
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')
seed = np.uint64(1)
rng64 = LCG(seed, np.uint64(6364136223846793005), np.uint64(1))
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())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
698 次 |
| 最近记录: |