从选项列表列表中查找相互兼容的选项

时间:2014-09-02 11:40:17

标签: algorithm search computer-science

出于这个问题的目的,让我们调用“OptionS”的互不兼容的选项列表。我有一个这样的OptionS列表,其中每个Option除了取消其自己的OptionS列表中的所有其他选项外,还取消了其他OptionS列表中的一些选项。这些规则是对称的,所以如果A禁止B,B禁止A。

我想从每个列表中选择一个选项,这样任何选项都不会相互取消资格。有太多的选项(和OptionS),并且每一步都有太少的取消资格来强制推迟回溯解决方案。

它提醒有点数独,但它不是一个确切的模拟。从某些外部因素来看,我很可能选择不同的选项,或者至少是一个排序。

这个问题有更好的解决方案吗?是NP吗?

目前,我计划通过解决方案空间随机选择“路径”,并按可能性加权。一种模拟退火。

编辑 - 澄清

  • 我有一个数字,比如5到500之间的矢量。
  • 每个向量包含一个数字,介于10到10000之间的元素
  • 每个元素排除了其他向量中的许多元素
  • 这种关系是对称的
  • 我想从每个向量中选择一个元素,其方式是没有元素相互取消

如果无法从每个向量中选择一个,我想至少选择尽可能多的向量。数据的性质总是至少有一个(并且最多只有几个)解决方案(或几乎解决方案 - 只有几个未命中)。

我无法共享真实数据,但一个例子是元素是1到10e9之间的整数,并且只允许成对和具有多于P个素数因子的元素。有些数字比其他数字更有可能“适应”其他数字,因为较大的数字往往有更多的因素,这使得某些选择更像是真正的选择。

根据需要选择P和矢量的大小和数量,以使其具有适当的挑战性:)。

我天真的解决方案:

  • 我按照他们排除的其他元素排序元素,并尝试先排除少数元素的元素(因为这样可以让你有更大的机会从每个元素中选择一个)。
  • 然后我按照“最佳”元素排除的元素数量来排序向量。首先排除许多其他元素的向量。因此,首先尝试最受约束的向量,即使首先尝试该向量的最小约束元素。
  • 然后我先搜索深度

这种方法的问题在于,如果第一个选择是错误的,那么深度优先搜索将永远没有时间到达下一个选择。

我尝试在下面的评论中解释的一种更好的方法是根据您选择的数量和剩余的元素对元素的每个部分选择(搜索树中的节点)进行评分。然后我可以在每一步的最高得分节点中更深入地看,因此第一选择不那么严格。

类似的方式,我可能首先尝试,因为它稍微容易一点,就是做模拟退火并采用随机路径,根据它们在树下保留的可能性加权。

2 个答案:

答案 0 :(得分:1)

我的第一个建议是找到现成的约束求解器并尝试(请求以对数似然作为权重的最大权重解决方案),但如果您决定从头开始实现求解器,那么我建议你从WalkSAT开始。总结您问题语言中的链接:始终保留选项列表(每个选项列表中的一个,不一定兼容)和冲突列表(即一组索引到列表中选项列表)。随机地反复选择冲突并通过为冲突的一半或另一半(大部分时间)选择不同的方式来解决冲突,以便尽可能地或者(某些时候)随机减少冲突的数量,也许根据可能性。良好的数据结构对于快速运行至关重要。

答案 1 :(得分:1)

根据允许的约束条件,我认为您可以将SAT减少到此。

采取SAT表达,例如(A | B | C)(〜甲| C |〜d)... 将a替换为a并从每个术语中生成一个向量,为您提供{A,B,C} {a,C,d} ......

您现在遇到从每个向量中选择一个元素的问题,受限于您无法选择变量的两个版本 - 约束表示A与a不兼容,B与b不兼容,依此类推。

如果您可以解决问题的这个实例,您可以通过设置为在您的问题中选择的真实变量A,B,C,...来解决SAT,将伪变量设置为a,b,c, ..并且对未选择的任何东西做出任意选择 - 因此你的问题至少和SAT一样难。 (除非你没有遇到这些类型的限制,在这种情况下我还没有证明你的问题很难)。

给定一个问题的实例,将变量与每个元素相关联,将约束写为布尔表达式(通常只有2个变量),以给出看起来像2-SAT的东西,除了你需要一个表达式给每个向量的表单(A | B | C | D | ...)表示你必须从每个向量中选择至少一个元素 - 所以至少你的问题的确切解决方案版本可能很好地编码为一个输入SAT求解器 - 所以它在NP中,因为我们已经证明它是NP-hard,它是NP完全的。