我在网上搜索了如何生成随机数矩阵的各种解决方案,其总和是常数。我的问题略有不同。我想生成一个详尽的整数列表的NX4矩阵,使得行中所有数字的总和正好为100.并且整数的范围为[0,100]。我希望整数顺序递增而不是随机。我怎么能用Python做到这一点?
谢谢。
答案 0 :(得分:2)
product
是一种生成组合的便捷方式
In [774]: from itertools import product
In [775]: [x for x in product(range(10),range(10)) if sum(x)==10]
Out[775]: [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5), (6, 4), (7, 3), (8, 2), (9, 1)]
元组总和为10,并按顺序步进(至少在第一个值中)。
我可以将它推广到3个元组,它仍然运行得非常快。
In [778]: len([x for x in product(range(100),range(100),range(100)) if sum(x)==100])
Out[778]: 5148
长度为4个元组需要更长时间(在旧机器上),
In [780]: len([x for x in product(range(100),range(100),range(100),range(100)) if sum(x)==100])
Out[780]: 176847
因此,可能需要逐步解决这个问题。
[x for x in product(range(100),range(100),range(100)) if sum(x)<=100]
运行得更快,产生相同数量的3个元组(在1或2之内)。第4个值可以推导出x
。
In [790]: timeit len([x+(100-sum(x),) for x in product(range(100),range(100),range(100)) if sum(x)<=100])
1 loops, best of 3: 444 ms per loop
答案 1 :(得分:0)
import itertools
import random
def makerow(L, T, R):
# make a row of size L and sum T, with the integers from 0-R, in ascending
answer = []
pool = list(itertools.takewhile(lambda x: x<T, range(R+1)))
for i in range(L-1):
answer.append(random.choice(pool))
T -= answer[-1]
pool = list(itertools.takewhile(lambda x: x<T, range(R+1)))
answer.append(T)
answer.sort()
return answer
def makematrix(M, N, T, R):
# make a matrix of M rows and N columns per row
# each row adds up to T
# using the numbers between 0-R
return [makerow(N, T, R) for _ in range(M)]