子集推理NP-complete?

时间:2012-05-17 15:33:28

标签: algorithm np-complete

考虑以下问题:

有N个硬币编号为1到N.

你看不到它们,但是给出了关于它们的M个事实:

struct Fact
{
    set<int> positions
    int num_heads
}

positions标识硬币的子集,num_heads是该子集中的硬币数量。

鉴于这些M个事实,你需要计算出最大数量的头部。

这个问题NP完全吗?如果是,减少量是多少?如果不是,什么是多项式时间解?

例如:

N = 5
M = 3
fact1 = { {1, 2}, 1 } // Either coin 1 or coin 2 is a head
fact2 = { {4}, 0 } // Coin 4 is a tail
fact3 = { {2, 4, 5}, 2 } // Out of coins 2, 4 and 5, two are heads

具有与事实匹配的最多头部的配置是:

T H H T H

所以答案是3个头。

3 个答案:

答案 0 :(得分:2)

假设您有3-SAT问题。您可以将该问题中的每个布尔变量v映射到两个硬币。称他们为'真(v)'和'假(v)'。这个想法是,如果对3-SAT问题的解决方案中的v是真的,那么'true(v)'就是头;否则'假(v)'是头。对于每个v,您添加硬币约束

{true(v), false(v)} has 1 heads, and has 1 tails

在此之后,您可以使用文字l1,l2,l3翻译3-SAT子句

l1 or l2 or l3

到硬币约束

{t/f(l1), t/f(l2), t/f(l3)} has at least 1 heads

其中t / f(l1)为'true(l1)'或'false(l1)',具体取决于子句中l1是正(否定)还是负(否定)。我们只需要证明在硬币问题中可以实现“至少1个头”,因为“至少1个头”不能直接表达。这可以使用以下设备完成。设C1,C2,C3为三个硬币,我们要为其约束'至少其中一个是头'。创建其他三个硬币X1,X2,X3并加入约束

{X1, X2, X3, C1, C2, C3} has 4 heads

但X1,X2,X3没有其他限制。仅当C1,C2,C3中的至少一个为头时,才满足该约束;硬币X1..3可用于提供剩余的头部。

请注意,此减少根本不使用问题的“最大头数”方面;如果3-SAT公式不可满足,根本不可能为表示布尔变量的硬币选择头/尾状态。

这是从3-SAT到你的硬币问题的多项式减少,表明它是NP难的。为了证明它是NP完全的,只需观察可以在多项式时间QED中检查硬币问题的解决方案。

答案 1 :(得分:1)

One-in-three 3SAT简单地减少了问题的决策版本(根本没有配置吗?),这在NP中很简单。最大化版本是NP- hard (但不完整,因为它不是决策问题),甚至是必须具有令人满意的配置的承诺版本:将决策减少的输出添加到一个额外的硬币出现在所有的子集中,创造了一个糟糕的额外解决方案,其中硬币是头部而所有其他都是尾部。

答案 2 :(得分:0)

完美匹配可以直接减少这个问题 - 将边缘表示为硬币,对于图形中的每个顶点创建一个事实,规定恰好一个附带边缘是头部。当且仅当存在硬币解决方案时,才存在原始图形中的完美匹配。