繁体   English   中英

生成具有被n整除的随机数列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM