[英]Generate list of random number with the sum divisible by n
我關心的是生成10到15個數字列表的好方法,這些數字的總和總是被n整除。
輸出應為
-8378302799
這是我到目前為止所獲得的,但是它還不能正常工作。
import random
import numpy as np
def get_num(x, y, n):
return [random.choice(range(x, y, n)) if x % n != 0 else random.choice(range(x - (x % n) + n, y, n)) for x in x]
def get_list():
numb = get_num(0, 9, 2)
return ''.join(np.random.multinomial(numb, [1/10], size=1))
while True:
amount = int(input("How many Do you want to generate?" + "\n"))
for i in range(1,amount):
get_list()
@Samer Ayoub,答案就是我所需要的,只是添加了sep ='',所以就如我所料。
import random
n, m, k= 3, 9, 14
lis = [random.choice(range(0, m)) for i in range(k)]
tot = sum(lis)
print(*lis, sep = '')
while tot%n != 0:
tot -= lis.pop()
last = random.choice(range(0, m))
lis.append(last)
tot += last
也許有點古怪,但是如果將來有人讀這個書,有一個概率分布問題很重要的用例,他們應該意識到,隨機選擇除最后一個數字之外的所有數字,然后選擇最后一個數字的算法為了滿足約束條件,在最后一個數字中引入了偏差。 作為概念證明:
import random, math
def f(k,a,b):
"""generates k random integers in a,b which sum to an even number"""
start = [random.randint(a,b) for _ in range(k-1)]
if sum(start) % 2 == 0:
#pick an even number
start.append(2*random.randint(math.ceil(a/2),math.floor(b/2)))
else:
#pick an off number
start.append(1 + 2*random.randint(math.ceil((a-1)/2),math.floor((b-1)/2)))
return start
例如,典型的f(3,1,5)
運行產生了[1, 5, 2]
f(3,1,5)
[1, 5, 2]
。
但:
trials = [f(3,1,5) for _ in range(10000)]
print(sum(trial[0]%2 == 0 for trial in trials)/10000) #percentage of first nums which are even
print(sum(trial[2]%2 == 0 for trial in trials)/10000) #percentage of last nums which are even
典型輸出:
0.3996
0.5198
這顯示出明顯的偏見。
完全生成您的列表,檢查總和是否可被n整除,如果不替換最后一個元素,直到它起作用:
import random
n, m, k= 3, 9, 15
lis = [random.choice(range(0, m)) for i in range(k)]
tot = sum(lis)
while tot%n != 0:
tot -= lis.pop()
last = random.choice(range(0, m))
lis.append(last)
tot += last
使用numpy
對@SamerAyoub的改進:
import numpy as np
n, m, k= 3, 9, 15
arr = np.empty(k, dtype = int)
arr[1:] = np.random.choice(np.arange(0, m), k-1)
rem = arr[1:].sum() % n
arr[0] = np.random.choice(np.arange(n - rem, m, n))
print(''.join([str(i) for i in arr]))
print(arr.sum()%n == 0)
374564205252063
True
還有一種(不能保證特別快,特別是如果n
大的話)蠻力方法,至少可以保證沒有偏差(但不保證永遠精加工):
def slow_way(n, m, k):
arr = np.empty(k)
while arr.sum() % n != 0:
arr = np.random.choice(np.arange(0, m), k)
return arr
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.