让列表 l 由 n 元素组成,其中
示例:
Given n = 5, r = 4, m = 10
l = [4, 3, 2, 0, 1]
很容易实现规则(1),但我想知道是否有任何好主意/算法来实现这两个规则?
答案 0 :(得分:0)
合理的解释是(i)查找并统计满足规则的所有唯一清单; (ii)以相同的概率随机选择其中一个列表。这种方法的问题在于编码列表列表很复杂。
更简单的方法(更少的代码)是将每个正确的列表暴露给被挑选的相同概率。该算法是:
m<=nr
如果没有,请返回“无”或引发错误。注意:此处对较少代码的权衡可能会延长执行时间。如果r很大,或者m是不可能的总和,这可能需要一段时间。我们可以通过检查答案只能是零或r-1
的限制来缓解这一点。
from numpy.random import randint
def known_sum_random_list(size,limitint,knownsum):
if knownsum>size*(limitint-1):
return None
if knownsum==size*(limitint-1):
return size*[limitint-1]
s=0
l = size*[0]
while (s!=knownsum):
l = randint(0,limitint,size)
s = sum(l)
return l
for t in xrange(10):
print known_sum_random_list(5,4,10)
输出:
[3 2 1 2 2]
[1 1 2 3 3]
[3 0 3 1 3]
[3 2 0 3 2]
[2 2 0 3 3]
[1 3 2 3 1]
[3 3 0 3 1]
[2 0 2 3 3]
[3 1 2 3 1]
[3 2 0 3 2]
答案 1 :(得分:0)
这是一个简单的蛮力解决方案。基本上,您希望生成小于r
的随机整数的样本。不符合标准的样本(总和为m
)将被拒绝。
import numpy as np
def rand_with_rules(n, r, m):
if n*(r-1) < m:
raise ValueError
while True:
l = np.random.randint(0, r, size=(n))
if l.sum() == m:
return l
请注意,拒绝样本必然会使您的“随机”数字产生偏差。由于你的限制,你不能拥有一套纯粹的随机性,而某些人往往会过度或不足。
例如,情况n,r,m = 2,3,4。符合此标准的唯一系列是(2,2),因此绘制2的可能性为100%,其他为0%值。
从本质上讲,这个解决方案表明你没有先验知道哪些整数最有可能。但是,通过约束,你对数字的后验知识几乎不会真正统一。
对于给定此约束的整数分布,可能有一个聪明的分析解决方案,您可以使用它来生成样本。但我不知道它是什么!
答案 2 :(得分:0)
如果没有验证可以立即满足所有规则,我建议遵循解决方案
import random
def dis(n,m,r):
l = [0] * n
for inc in range(1,m):
l.sort()
for ind_less_r, less_r in enumerate(l):
if less_r > r:
break
l[random.randint(0,ind_less_r-1)] += 1
random.shuffle(l)
return l
for i in range(1,10):
print dis(10,50,9)
结果是
[7, 7, 6, 1, 6, 3, 5, 4, 4, 6]
[5, 6, 7, 5, 4, 7, 4, 4, 4, 3]
[4, 3, 2, 4, 7, 7, 5, 7, 5, 5]
[4, 4, 5, 6, 4, 6, 6, 4, 5, 5]
[6, 6, 4, 6, 5, 6, 2, 5, 4, 5]
[2, 8, 4, 2, 6, 5, 4, 4, 6, 8]
[6, 6, 3, 4, 5, 5, 5, 5, 6, 4]
[6, 4, 5, 6, 7, 3, 1, 5, 6, 6]
[4, 5, 4, 7, 6, 6, 3, 2, 6, 6]
答案 3 :(得分:0)
由于您在评论中回复说它可以有很多0并且数字可以重复,我推断它不一定是随机的。考虑到这一点,这是一个没有任何循环或包含的基本解决方案。它假定n
,r
和m
具有有效的值和类型。但是这样的检查很简单,我可以根据要求进行编辑。
def create_list(n, r, m):
output = [r] * (m/r)
remainder = m - r * len(output)
if remainder != 0:
output += [m - r * len(output)]
output += [0] * (n - len(output))
return output
output = create_list(5, 4, 10) # gives [4, 4, 2, 0, 0]
output = create_list(5, 2, 10) # gives [2, 2, 2, 2, 2]
P.S。 - 请求的值小于 r
,但示例显示的值等于r
,所以这是通过示例