Python 均匀生成不同整数的随机对 任务: 生成一对随机数(i,j)(顺序无关紧要:(i,j)相当于(j,i)) 该对必须由两个不同的值组成:i!=j 线对必须均匀分布。换句话说,所有可能的对的概率都是相同的 在固定的时间内这样做 第一次尝试

Python 均匀生成不同整数的随机对 任务: 生成一对随机数(i,j)(顺序无关紧要:(i,j)相当于(j,i)) 该对必须由两个不同的值组成:i!=j 线对必须均匀分布。换句话说,所有可能的对的概率都是相同的 在固定的时间内这样做 第一次尝试,python,numpy,random,probability,Python,Numpy,Random,Probability,恒定时间是。均匀分布否 x = np.random.randint(low=0, high=10 - 1) y = np.random.randint(low=x + 1, high=10) 可视化样本(忽略顺序): 您可以很容易地将y限制为大于x的效果,这意味着更高的对具有更高的概率(此处不透明度表示密度) 第二次尝试 恒定时间否。均匀分布是 x = np.random.randint(low=0, high=nbr_values) y = np.random.randint(low=0,

恒定时间。均匀分布

x = np.random.randint(low=0, high=10 - 1)
y = np.random.randint(low=x + 1, high=10)
可视化样本(忽略顺序):

您可以很容易地将
y
限制为大于
x
的效果,这意味着更高的对具有更高的概率(此处不透明度表示密度)

第二次尝试 恒定时间。均匀分布

x = np.random.randint(low=0, high=nbr_values)
y = np.random.randint(low=0, high=nbr_values)

while x == y:
  y = np.random.randint(low=0, high=nbr_values)
可视化样本:

PS:这不是家庭作业,我正在试验随机优化技术,使用交换操作生成随机邻居。

这个怎么样

x = np.random.randint(low=0, high=nbr_values)
y = np.random.randint(low=0, high=nbr_values - 1)
if y == x:
    y = nbr_values
x
的值均匀分布在所有可能的值中,
y
的值均匀分布在所有剩余的值中,
x
的当前值作为最大值(也可以是最小值,在这种情况下只需使用
low=1

图形近似:

range                 0 - - - - - - - - - - - - - MAX
distribution for x    + + + + + + + + + + + + + + +
random value for x                x
distribution for y    + + + + + +   + + + + + + + +
                                  \-------------->
范围
0..5
1000000对的随机分布

0       33425   33147   33411   33340   33365
33206   0       33537   33568   33679   33317
33307   33284   0       33423   33121   33189
33235   33303   32970   0       33347   33316
33233   33946   33257   33272   0       33504
33517   33203   33394   33221   32963   0

如果
y>=x
,我们也可以移动
y
的所有值,而不是用
max
交换
x
,即
如果y>=x:y+=1
,得到相同的分布。这样,通过将当前值与所有以前的值进行比较并相应地向上移动,也可以将上述值概括为两个以上的值。不过,这需要对绘制的值进行排序,因此复杂性稍高,大约为O(k²logk)

low
high
以及1000000次迭代使用较小的值再次进行测试,结果看起来是正确的


或者,你可以用它。我不知道这是如何实现的,但它非常快,即使对于上限的大值和接近最大值的
k

我将上面的@tobias_k方法扩展到
k

def uni_repl(n, k, s = 1000):
    x = np.empty((k, s), dtype = int)
    for i in range(k):
        x[i] = np.random.randint(low = 0, high = n - k + i + 1, size = s)
    for i in range(1, k):
        x[:i][x[:i] == x[i]] = n - k + i
    return x
测试:

test = np.zeros((5,5,5))

np.add.at(test, list(uni_repl(5, 3)), 1)

test
Out[85]: 
array([[[     0.,      0.,      0.,      0.,      0.],
        [     0.,      0.,  16304.,  16767.,  16622.],
        [     0.,  16418.,      0.,  16631.,  16517.],
        [     0.,  16688.,  16607.,      0.,  16495.],
        [     0.,  16663.,  16544.,  16877.,      0.]],

       [[     0.,      0.,  16736.,  16767.,  16668.],
        [     0.,      0.,      0.,      0.,      0.],
        [ 16862.,      0.,      0.,  16634.,  16632.],
        [ 16791.,      0.,  16689.,      0.,  16557.],
        [ 16566.,      0.,  16843.,  16864.,      0.]],

       [[     0.,  16737.,      0.,  16638.,  16437.],
        [ 16741.,      0.,      0.,  16545.,  16617.],
        [     0.,      0.,      0.,      0.,      0.],
        [ 16804.,  16923.,      0.,      0.,  16598.],
        [ 16756.,  16850.,      0.,  16778.,      0.]],

       [[     0.,  16777.,  16675.,      0.,  16760.],
        [ 16454.,      0.,  16792.,      0.,  16669.],
        [ 16476.,  16709.,      0.,      0.,  16677.],
        [     0.,      0.,      0.,      0.,      0.],
        [ 16680.,  16863.,  16640.,      0.,      0.]],

       [[     0.,  16459.,  16446.,  16756.,      0.],
        [ 16637.,      0.,  16626.,  16756.,      0.],
        [ 16481.,  16773.,      0.,  16762.,      0.],
        [ 16754.,  16531.,  16681.,      0.,      0.],
        [     0.,      0.,      0.,      0.,      0.]]])
与使用
np.argpartition
的方法相比,只要
k<0.4*n

def uni_part(n, k, s = 1000):
    x = np.random.rand(n, s)
    return np.argpartition(x, k, axis = 0)[:k]

%timeit uni_part(100, 40)
100 loops, best of 3: 3.93 ms per loop

%timeit uni_repl(100, 40)
100 loops, best of 3: 3.76 ms per loop

%timeit uni_part(100, 10)
100 loops, best of 3: 3.55 ms per loop

%timeit uni_repl(100, 10)
1000 loops, best of 3: 425 µs per loop

%timeit uni_part(100, 50)
100 loops, best of 3: 4.08 ms per loop

%timeit uni_repl(100, 50)
100 loops, best of 3: 4.89 ms per loop

从Numpy 1.7.0开始,您可以使用
np.choice
replace=False

np.random.choice(10, 2, replace=False)
array([2, 6])
以下是10000个样本的分布情况:


在第一个示例中,如果随机选择将边界定义为小于或大于最初拾取的值,则会有恒定的时间。而不是假设它大于。如果在它们相等时再次生成它们会发生什么?考虑到0到9范围,如所公布的数据所示。wlog,假设第一个数字是5。对于第二个数字,我们滚动一个D9,编号为0-8。。。但是我们将
5
(已经选择的数字)映射到
9
。第二个数字是均匀平衡的。我不认为它偏向于最后一项,它实际上是在删除
x
后重建索引列表。@roganjosh是的,对于
x!=y
y
保证不会是
9
y
成为
9
的概率与任何其他允许值的概率完全相同。我现在看到了,羞愧地低下头:P@PaulPanzer我现在还为我的方法添加了一个泛化,但是你也可以只使用
random.sample
范围
…找不到错误(除非k相当大)。@PaulPanzer,是的,我检查了速度,它似乎比
argpartition
快,只要k<.4n
np.random.choice(10, 2, replace=False)
array([2, 6])