有像 FisherYates 这样的洗牌算法。他们接受一个数组并以随机顺序返回一个元素。这在 O(n) 中运行。
我正在尝试做的是实现一个优先的 left-shuffle algorithm。这意味着什么?
- Prioritized:它不采用值数组。它需要一组价值-概率对。例如
[ (1, 60), (2, 10), (3, 10), (4, 20) ]
。值 1 有 60%,值 2 有 10%,... - left-shuffle:一个值的概率越高,它在数组左侧的机会就越大。
我们以这个例子为例[ (1, 10), (2, 10), (3, 60), (4, 20) ]
。最可能的结果应该是[ 3, 4, 1, 2 ]
或[ 3, 4, 2, 1 ]
。
我尝试实现这一点,但在 O(n) 中没有找到任何解决方案。
基于 FisherYates 的伪代码中的 O(n^2):
sum = 100 #100%
for i = 0 to n-2:
r = random value between 0 and sum
localsum = 0
for j = i to n-1:
localsum = localsum + pair[j].Probability
if localsum >= r + 1:
swap(i, j)
break
sum = sum - pair[i].Probability
什么可能会改善这一点:在一开始就按概率对元素进行排序,以最小化交换次数和内部循环中的迭代。
有没有更好的解决方案(甚至可能在 O(n) 中)?