我需要生成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

你知道如何有效地做到这一点吗?

最佳答案

一般来说,如果在给定的范围内均匀随机地选择单元,就不可能解决这个问题。
例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]之间均匀分布是完全不同的。
基本思想是,在每个阶段,进一步限制您的范围,如下所示:
范围的开始应该是以下两个量中的较大者:pmin[i]或s-smax[i]-p,其中smax[i]是pmax[i+1]+…+pmax[n]和p是p[0]+…+P[I]。这保证了你选择的数字足够大,最终可以工作。
范围的终点应为以下两个量中的较小者:
pmax[i]或s-smin[i]-p,其中smin[i]是pmin[i+1]+…+pmin[n]和p和以前一样。这保证了你选择的数字足够小,最终可以工作。
如果你在选择每一个p[i]时都能遵守这些规则,那么就有一个解决方案,你会随机找到一个。否则,就没有解决办法。
请注意,要使这个选择的解实际上是随机的,最好是洗牌索引,执行这个算法,然后重新排列序列,使其按正确的顺序排列。您可以在o(n)中乱序,执行此算法(这里建议使用动态编程,因为您可以自下而上构建解决方案),然后通过“取消对结果序列的乱序”来抛出序列。

关于algorithm - 生成实数值列表,这些实数值总计为固定值并满足一些约束,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14755366/

10-12 14:10