如何(有效地)生成不相交的集合,同时只使用一对元素?

mez*_*ano 6 algorithm solver combinatorics constraint-programming disjoint-sets

我想要做的是将一组(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的工作,他在论文中讨论了几种方法(然后继续提出一个非常好的算法).如果有人遇到类似的问题,强烈建议这样做!

Dav*_*tat 8

这个问题是在社交高尔夫球手问题的名义下研究的.文献具有重要的规模,但有三种主要方法:

  1. 本地搜索方法,可以处理不存在多对的情况.

  2. 完整的搜索方法,如缩小到精确的封面.根据我的记忆,这里的研究围绕着对称性破坏的有效方法,其中你修复第一行的想法可能是最简单的.

  3. 数学结构.当q是一个主要的权力时,有q个q组的构造涉及有限的仿射平面,这些并不太难实现.除此之外,还有很多一次性的结构.组合设计手册可能是您总结已知内容的最佳选择.