找到最少使用的排列

时间:2011-09-22 15:05:25

标签: c# algorithm permutation

我需要根据历史数据随时间均匀分布一组数据,以使每个数字在每个位置随时间呈现相等(或接近相等)的次数。问题是,给定过去使用的排序列表,看起来像这样(但可以有任意数量的元素):

1,2,5,3,4
4,1,5,2,3
1,3,5,2,4
4,1,2,3,5
2,4,1,3,5
5,1,4,3,2
1,5,3,2,4
5,1,3,2,4
3,2,5,4,1
4,3,1,5,2

如何找到最少使用的值的排序,并将导致“更平衡”的排序集。显而易见的答案是我可以分组并计算它们并选择最少使用的一个,但问题是可能从未使用过的最少使用的排列,例如这里,排序“1,2,3,4,5”是最少使用的候选人,因为它根本没有出现。

简单的答案似乎是确定哪个位置“1”出现在最不频繁的位置,并将该位置设置为“1”,依此类推每个数字。我怀疑它有效,但我觉得有一个更优雅的解决方案,我没有考虑过交叉连接,所以包括所有可能的组合。

任何想法?

3 个答案:

答案 0 :(得分:1)

这里有一个直方图调平问题。

从这个角度考虑问题:你有一组N个直方图,它们代表在离散范围{1..N}上出现值N值的频率。你想要做的是为你的数据填充添加一组新的值,使所有直方图更接近水平。鉴于问题的性质,我们知道每个值总体上看起来与其他每个值的次数相同。

这样做的一种方法是在任意位置中找出N具有最低出现频率的值 - 并为其分配该位置。接下来,在剩余的直方图中,找到在任何位置具有最低出现频率的下一个值,并将该值分配给该位置。继续重复此过程,直到为所有值分配了唯一的位置。这为您提供了下一组值。您现在可以迭代地重复此操作以继续生成新的值集,这些值将尝试在每次迭代时重新平衡值的分布。

如果在分配值时保持直方图,这将成为一种相对有效的操作(您不必经常重新扫描数据集)。

但请记住,对于任何足够小的价值观,你在某种程度上总会“失去平衡”。没有办法解决这个问题。

答案 1 :(得分:0)

我假设您有办法生成随机排列(例如Most efficient way to randomly "sort" (Shuffle) a list of integers in C#)。鉴于此,生成单个新排序的一个建议如下:

1)产生两个随机的渗透

2)保持他们中的任何一个最能平衡失衡。

衡量平衡的一个方法是将每个位置的所有数字频率计数列表视为向量,在完美平衡的情况下,每个元素的每个元素都相同。然后,不平衡将是通过减去该完美向量得到的向量的长度。通过在两个随机排列之间进行选择,您将从分布中选择一个排列,该分布的平均向量指向与当前不平衡相反的方向,因此您应该倾向于纠正它,同时仍然产生随机排列的排列。

答案 2 :(得分:0)

如果组合的总数足够小,我很久以前就采用了类似问题的方法:

保持定期补充的一系列选择。

在您的示例中,您有120种可能的排列。创建一个包含120个元素的数组,为每个元素分配一个5的初始值。当您需要从该池中选择一个随机值时,bin中的数字是给该bin的权重。 (在开始时,箱子总和为600.从1到600选择一个随机,从中减去箱子直到< = 0.你刚刚减去的箱子是你的结果。)当一个箱子被选中时,减去箱子一个。一旦你从桩中抽取120次,每个箱子加1。

显然,如果可能性的总数太高,这就变得不切实际了。