NP Completeness¶
约 1156 个字 6 行代码 2 张图片 预计阅读时间 4 分钟
难易与快慢
-
难易!=快慢
-
在本节内容中,难易指的是是否能用多项式时间解决,与算法本身的快慢无关系
-
而快慢就是我们平时分析复杂度时,感受到的快慢
-
根据问题的难度,由不同的定义划分,问题可以分为:
-
P 问题(polynomial time)、NP 问题(nondeterministic polynomial time)、NPC 问题(NP complete)、NPH 问题(NP hard)。除此之外 ,我们还需要额外了解不可计算问题(undecidable)。
Undecidable Problem
-
先来看一下特殊的不可计算问题
-
不可判定问题(undecidable problem)是一类特殊的决定性问题,它的特点是我们无法设计一个算法来求解它的结果。
-
其中一个比较典型的例子就是停机问题
P=NP?¶
P
-
P 取自 polynomial time,指的是可以用确定型图灵机在多项式时间内解决的问题。
-
也就是我们通常意义下所说的,可以在多项式时间内解决的问题。
NP
-
NP 即 nondeterministic polynomial time,指的是可以用非确定型图灵机在多项式时间内解决的问题。这个说法等价于可以用确定型图灵机在多项式时间内验证(判断答案是否正确)。
-
也就是我们通常意义下所说的,可以在多项式时间内验证的问题。
NPC
-
NPC 即 NP complete,NP 完全,是 NP 中最难的决定性问题(并不是无限定词的最难的问题!)。而我们称满足如下条件的问题为 NPC 问题:
-
是一个 NP 问题;
-
所有 NP 问题都可以多项式时间归约为该问题;
-
-
由 2 可以有结论,所有的 NPC 问题难度相同——一旦有一个 NPC 问题被解决,那么所有 NPC 问题,乃至所有 NP 问题都能被解决。
-
如果我们试图证明一个问题是 NPC 问题,我们可以通过这种手段:
-
判定该问题是一个 NP 问题;
-
判定一个已知的 NPC 问题可以多项式时间归约为该问题,或判定该问题是 NPH(在下面)问题;
-
第一个被证明是 NPC 的问题是 Circuit-SAT🔍 问题。
NPH
NPH问题就是NPC的宽泛版,所有的NP问题都可以归约到NPH问题,但NPH问题不一定是一个NP问题
例:Halting Problem¶
-
停机问题是一个典型的不可计算问题,它指的是,对于任意一个程序,我们无法设计一个算法来判断它是否会在有限时间内停机(即判断程序是否会死循环)。
-
我们通过反证法可以证明:
-
假设存在函数
willHalt(func F)
可以判断函数F
是否会停机,如果会,则返回true
,否则返回false
。那么我们可以构造一个这样的函数foo()
:
-
接下来,如果我们想知道
foo()
是否会停机,就会执行willHalt(foo)
。然而在foo()
内部也有一个willHalt(foo)
,如果它认为foo()
会停机,则构造一个死循环;而如果它认为foo()
不会停机,则选择让它立刻停机,于是这里就产生了矛盾。 -
理解上面这段内容的关键就是,这里虽然不存在事实意义上的“死循环”,但可以理解为这里存在一个逻辑上的递归,而这种“逻辑上的递归”,正是导致停机问题成为一个不可计算问题的原因。
例:Hamilton Cycle Problem¶
-
给定一个图,判断是否存在一条路径,使得它经过图中的每个点恰好一次,且最后回到起点。
-
哈密顿回路问题是一个 NPC 问题。
例:Traveling Salesman Problem¶
-
旅行商问题有两种定义,其中前者是 NPH,而被称为“判定版本”的后者是 NPC。
-
我们谈论的都是判定版本的 TSP
-
给定一个完全图,判断是否存在一条路径,使得它经过图中的每个点恰好一次,且最后回到起点,且路径长度不超过\(k\)
例:Circuit-SAT¶
-
Circuit-SAT 又叫 circuit satisfiability problem,它是最早被证明是 NPC 的问题,即通过 NPC 问题的定义证明。
-
Circuit-SAT 即为确定给定布尔电路是否具有使输出为真的输入分配的决策的问题。
-
上图中,左侧电路满足条件,右侧电路不满足条件。
-
或者,更抽象的来说,是判断一个具有n个布尔变量的布尔表达式是否具有结果为 True 的解。