我尚未对此进行测试,因此它并不是真正的答案,只是尝试的时间太长,无法放入评论中。从一个满足前两个条件的数组开始,然后继续使用它,以便它仍然满足前两个条件,但是随机性更高。
有没有一种有效的方法来生成N个整数的随机组合,使得-
min
,max
],]中>mean
(或N * mean
的和,]]我知道可以通过以下方式解决此问题:
[[Use the algorithm在Smith和Tromble中给出(“从单位单纯形抽样”,2004年),以生成总和为N * mean - N * min
的N个随机非负整数。
向以此方式生成的每个数字添加min
。
max
,请转到步骤1。但是,如果max
远小于N * mean
,则此算法速度较慢。例如,根据我的测试,该算法平均拒绝-
N = 7, min = 3, max = 10, mean = 6
时,约为1.6个样本,但N = 20, min = 3, max = 10, mean = 6
时,约为30.6个样本。是否有一种方法可以修改此算法以使其对大N有效,同时仍满足上述要求?
以下代码示例在Ruby中给出,但我的问题与编程语言无关:
def posintwithsum(n, total) raise if n <= 0 or total <=0 ls = [0] ret = [] while ls.length < n c = 1+rand(total-1) found = false for j in 1...ls.length if ls[j] == c found = true break end end if found == false;ls.push(c);end end ls.sort! ls.push(total) for i in 1...ls.length ret.push(ls[i] - ls[i - 1]) end return ret end Def integersWithSum(n, total) raise if n <= 0 or total <=0 ret = posintwithsum(n, total + n) for I in 0, ret.length ret[i] = ret[i] - 1 end return ret end # Generate 100 combinations mn=3 mx=10 mean=6 n=7 100. Times { while true pp=integersWithSum(n,n*mean-n*mn).map{|x| x+mn } if !pp.find{|x| x>mx } p pp; break # Output the sample and break end end }
是否有一种有效的方法来生成N个整数的随机组合,从而使-每个整数在[min,max]区间内,整数的组合具有均值的平均值(或N * ...的和)。 >
我尚未对此进行测试,因此它并不是真正的答案,只是尝试的时间太长,无法放入评论中。从一个满足前两个条件的数组开始,然后继续使用它,以便它仍然满足前两个条件,但是随机性更高。
如果均值是整数,则您的初始数组可以是[4,4,4,... ... 4],也可以是[3,4,5,3,4,5,... 5,8,0 ]或类似的简单内容。平均为4.5,请尝试[4,5,4,5,... 4,5]。
接下来选择数组中的一对数字num1
和num2
。可能应该按照顺序选择第一个数字,就像使用Fisher-Yates混洗一样,应该随机选择第二个数字。按顺序排列第一个数字可确保每个数字至少被选择一次。
现在计算max-num1
和num2-min
。这些是从两个数字到max
和min
边界的距离。将limit
设置为两个距离中较小的一个。这是允许的最大更改,不会将一个或另一个数字超出允许的限制。如果limit
为零,则跳过该对。
选择[1,limit
范围内的随机整数]:将其命名为change
。我在可选取范围内省略了0,因为它没有作用。测试可能表明,通过包含随机性,您可以获得更好的随机性;我不确定。
现在设置num1 <- num1 + change
和num2 <- num2 - change
。这不会影响平均值,并且数组的所有元素仍在所需的边界内。
您将需要至少遍历整个数组一次。测试应该显示您是否需要多次进行操作才能获得足够随机的内容。
我尚未对此进行测试,因此它并不是真正的答案,只是尝试的时间太长,无法放入评论中。从一个满足前两个条件的数组开始,然后继续使用它,以便它仍然满足前两个条件,但是随机性更高。