我想做的是将一组(n)项分成相等大小的组(m),并且为了简单起见,假设没有剩余,即n可被m整除。多次这样做,我想确保没有一对物品两次在同一组中。
为了让这个问题更具体化,在六个项目A..F中构建两个组,可以使用不同的方式将集合分区五次:
- (A, B), (C, D), (E, F) - (A, C), (B, E), (D, F) - (A, D), (B, F), (C, E) - (A, E), (B, D), (C, F) - (A, F), (B, C), (D, E)
我的问题是:有没有一种高效的方法来完成这个任务?有什么技巧可以加快生成这些集合的速度?
到目前为止,我一直将其视为一个精确覆盖问题,并使用回溯算法(DLX的变体)来解决它。对于成对的情况,这种方法非常有效,但随着组的规模变大,算法需要考虑的可能性数量激增,处理起来非常棘手。
我正在寻找加速处理的技巧。任何想法都非常受欢迎,特别是(但不限于):
为了让这个问题更具体化,在六个项目A..F中构建两个组,可以使用不同的方式将集合分区五次:
- (A, B), (C, D), (E, F) - (A, C), (B, E), (D, F) - (A, D), (B, F), (C, E) - (A, E), (B, D), (C, F) - (A, F), (B, C), (D, E)
同一组物品只能被分成三组,且不重叠:
(A, B, C)
,(D, E, F)
(正如@DavidHammen在下面指出的那样,这个例子有不同的分割方式。然而,一旦进行了划分,就再也没有另一个第二次划分可以使所有物品对保持分开。这很好——我的应用程序不需要生成全局所有可能的划分方式,符合约束条件的一个解决方案就可以)
我的问题是:有没有一种高效的方法来完成这个任务?有什么技巧可以加快生成这些集合的速度?
到目前为止,我一直将其视为一个精确覆盖问题,并使用回溯算法(DLX的变体)来解决它。对于成对的情况,这种方法非常有效,但随着组的规模变大,算法需要考虑的可能性数量激增,处理起来非常棘手。
我正在寻找加速处理的技巧。任何想法都非常受欢迎,特别是(但不限于):
- 优化和启发式算法,以减少在解决之前需要考虑的可能性数量(例如,从上面的示例中可以清楚地看出,第一个分割可以简单地任意选择,并且每个分区的第一组[上面的第一列]可以自动生成)。
- 是否有backtracking的变体可以处理大量的候选项?(即不需要预先生成所有可能性)
- 我应该考虑其他算法、方法或数学概念吗?
欢迎提出任何想法和建议。非常感谢您的考虑!
更新
好的,这已经有一段时间了,但我花了更多的时间在这上面,并想要回复你。@david-eisenstat 给了我正确的搜索词(非常感谢!)——我后来阅读了很多关于社交高尔夫问题的内容。
其中我发现的最好的资源之一是Markus Triska的作品,他在论文中讨论了几种方法(然后继续介绍了一个非常好的算法)。如果有人遇到类似的问题,强烈推荐阅读!
((A B D), (C E F))
和((A B E) (C D F))
还有至少六个组合为什么不行?问题陈述并没有明确说明你为什么排除了那些组合。 - David Hammen