我需要生成满足以下约束条件的n个随机实数值P [0],P [1],...,P [n-1]:
Pmin[0] <= P[0] <= Pmax[0]
Pmin[1] <= P[1] <= Pmax[1]
...
Pmin[n-1] <= P[n-1] <= Pmax[n-1]
P[0] + P[1] + ... + P[n-1] = S
知道如何有效地做到这一点吗?
答案 0 :(得分:1)
通常,如果从给定范围中随机均匀地选择元素,则无法解决此问题。
示例1:假设Pmin [i] = 0且Pmax [i] = 1.假设n = 10且S = 100.则没有解,因为最大可能总和为10.
示例2:假设Pmin [i] = 0且Pmax [i] = 1.假设n = 10且S = 10.那么只有一个解决方案:选择P [i] = 1.
可以编写一种算法,使得从可能的解集中随机均匀地选择结果序列;这与说P [i]在Pmin [i]和Pmax [i]之间均匀分布完全不同。
基本思路是在每个阶段进一步限制你的范围,如下所示:
如果你在挑选每个P [i]时能够遵守这些规则,那么就有一个解决方案,你会随机找到一个。否则,没有解决方案。
请注意,要实际制作随机选择解决方案,最好是对索引进行随机播放,执行此算法,然后重新排列序列,使其处于正确的顺序。您可以在O(n)中进行随机播放,执行此算法(建议在此处进行动态编程,因为您可以自下而上构建解决方案),然后通过“取消预设”生成的序列来吐出序列。
答案 1 :(得分:0)
For every i, assign P[i] := Pmin[i]
Compute the sum
If sum>S, then stop (it's impossible)
For every i:
If P[i]+S-sum <= Pmax[i]
P[i] = P[i]+S-sum
Stop (it's done :-)
sum = sum+Pmax[i]-P[i]
P[i] = Pmax[i]
Go for next i
Stop (it's impossible)
哎呀,对不起,你说随机......这不是那么微不足道。让我考虑一下......
运行上一个算法以获得起点。现在计算上下的总保证金。上面的余量是每个i的个别边界Pmax [i] -P [i]的总和。下面的边距是每个i的单个边距P [i] -Pmin [i]的总和。
以随机顺序遍历所有元素但一个,只访问其中的每一个元素。对于他们每个人:
然后调整剩余元素以适合总和S.
关于随机顺序的遍历,请参阅Knuth shuffles。