我想做的是将一组 ( 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)
同一组项目只能被划分为三个一组,而不会重叠:
(A, B, C)
,(D, E, F)
(正如@DavidHammen 在下面指出的那样,在此示例中创建分区有不同的方法。但是,一旦创建了分区,就再也没有第二个分割将所有成对的项目分开了。这很好 - 我的应用程序没有'不需要生成所有可能的全局分区方法,满足约束的解决方案就可以了)
我现在的问题是:有没有办法有效地做到这一点?有没有加快生成这些集合的技巧?
因此,到目前为止,我一直将其视为一个精确覆盖问题,并使用回溯算法(DLX 的一种变体)来解决它。这对配对非常有效,但随着组变得更大,算法必须考虑的可能性数量会激增,并且处理变得非常笨拙。
我正在寻找的是加快速度的技巧。任何想法都非常受欢迎,特别是(但不限于):
- 优化和启发式方法以减少在求解之前需要考虑的可能性数量(例如,从上面的示例中可以清楚地看出,第一次拆分可以简单地任意进行,并且每个分区的第一组 [上面的第一列] 可以自动生成)。
- 是否有可以应对大量候选人的回溯变体?(即不需要预先产生所有的可能性)
- 我应该考虑的其他算法、方法或数学概念?
非常欢迎任何想法和建议。非常感谢您考虑这一点!
更新
好的,这已经有一段时间了,但我在这上面花了很多时间,想回复你。@david-eisenstat 通过给我正确的搜索词(非常感谢!)让我走上了正确的道路——我已经阅读了很多关于社交高尔夫球手问题的文章。
我发现的最好的资源之一,我想在这里分享,是Markus Triska的工作,他在他的论文中讨论了几种方法(然后继续提出一个非常好的算法)。如果有人遇到类似问题,强烈建议这样做!