Sum*_*mit 3 python random probability
我试图k在范围内找到随机数,1..n使得没有k数字是连续的.我想出的代码是
def noncontiguoussample(n,k):
import random
numbers = range(n)
samples = []
for _ in range(k):
v = random.choice(numbers)
samples.append(v)
for v in range(v-1, v+2):
try:
numbers.remove(v)
except ValueError:
pass
return samples
Run Code Online (Sandbox Code Playgroud)
更新:我知道这个函数不会以均匀的概率返回样本.基于我的有限测试,下面的Amber解决方案满足条件(a)样本的各个元素是非连续的,以及(b)以均匀概率生成所有可能的k个样本(来自1 ... n).
如果你使用a,代码会更简单set.
import random
def noncontiguoussample(n,k):
numbers = set(range(1,n+1))
samples = []
for _ in range(k):
v = random.choice(list(numbers))
samples.append(v)
numbers -= set([v-1, v, v+1])
return samples
Run Code Online (Sandbox Code Playgroud)
然而,正如迈克尔安德森在评论中指出的那样,这种算法有时会失败n < 3*k.
一个更好的算法,不能失败(也更快!)可能看起来像这样:
import random
def noncontiguoussample(n,k):
# How many numbers we're not picking
total_skips = n - k
# Distribute the additional skips across the range
skip_cutoffs = random.sample(range(total_skips+1), k)
skip_cutoffs.sort()
# Construct the final set of numbers based on our skip distribution
samples = []
for index, skip_spot in enumerate(skip_cutoffs):
# This is just some math-fu that translates indices within the
# skips to values in the overall result.
samples.append(1 + index + skip_spot)
return samples
Run Code Online (Sandbox Code Playgroud)
最后的数学是这样的:
index),以计算所选号码因此,对于循环中的每次迭代,结果将总是增加至少2.