我正在尝试构建一对生成器。它需要六个名称的列表,并生成一周(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个非唯一的对。一周中的每一天都被覆盖,但我们会复制。
有没有办法更有效地做到这一点/避免复制?
答案 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.