试图创建一对生成器

时间:2015-09-08 17:48:16

标签: ruby algorithm math combinations permutation

我正在尝试构建一对生成器。它需要六个名称的列表,并生成一周(5天)的对,尽可能少的重复。

我得到的复制对的最小值是2(所以我找到了5天的对,即总共15对,只有2组相同)。

我的方法:

# Start with individuals in an array
[1, 2, 3, 4, 5, 6]
# Bisect the array
[1, 2, 3]
[4, 5, 6] => yields pair combinations [1, 4], [2, 5], [3, 6]
# Move the lower of the bisected arrays along
[1, 2, 3]
[6, 4, 5] => yields pair combinations [1, 6], [2, 4], [3, 5]
# Move along once more
[1, 2, 3]
[5, 6, 4] => yields pair combinations [1, 5], [2, 6], [3, 4]
# Since there are no more unique pair combinations, bisect each array again
(Array 1) [1, 2]
(Array 1) [3] => yields pair combination [1, 3] with 2 'spare'
(Array 2) [4, 5]
(Array 2) [6] => yields pair combination [4, 6] with 6 'spare'
=> 'spare' pair combination [2, 6] is a replication
# Move the lower of the bisected arrays along
(Array 1) [1, 2]
(Array 1)    [3] => yields pair combination [2, 3] with 1 'spare'
(Array 2) [4, 5]
(Array 2)    [6] => yields pair combination [5, 6] with 4 'spare'
=> 'spare' pair combination [1, 4] is a replication

上面的这个过程为我们提供了13个唯一的对,然后是2个非唯一的对。一周中的每一天都被覆盖,但我们会复制。

有没有办法更有效地做到这一点/避免复制?

3 个答案:

答案 0 :(得分:2)

这是一场循环赛,每位玩家都会扮演其他玩家。如下所示排列玩家以形成对4 4 2,5 5和3 6:

123
456

修正玩家1,旋转其余玩家:

<强> 1 42
563

生产对1 5,4 6和2 3.保持旋转:

<强> 1 54
632

<强> 1 65
324

<强> 1 36
 245

答案 1 :(得分:1)

认为您只需在返回枚举器的内置combination方法之后。您可以使用.to_a将其转换为一系列独特的组合。

[1, 2, 3, 4, 5, 6].combination(2).to_a
# => [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 3], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6], [4, 5], [4, 6], [5, 6]]

答案 2 :(得分:1)

这称为1-factorization。 6个顶点{0,1,2,3,4,oo}上的完整图的一个1因子分解是让第i天的时间表为{{oo,i},{i + 1,i + 4}, {i + 2,i + 3}}其中所有数字i + j都减少了mod 5.