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