查看原文,点我
计算复杂性理论
在计算机算法中,计算复杂性是一个很重要的研究内容。计算复杂性理论(Computational complexity theory)被认为是理论计算机科学和数学的一个分支。
对于计算机而言,任何一个问题的求解都需要资源(即使是最简单的1+1的问题)。计算复杂性理论通过引入数学计算模型来研究这些问题以及定量计算解决问题所需的资源(时间和空间),从而将资源的确定方法正式化。
计算复杂性理论将计算问题按照在不同计算模型下所需时间资源的不同予以分类,就得到了常见的P、NP、NP完全、NP难这样的概念(note:P代表Polynomial,即多项式时间的概念)
P问题 一个问题如果在确定性图灵机上所需时间不会超过一个确定的多项式(以输入的长度为多项式的不定元),那么我们称这类问题的集合为P(polynomial time Turing machine)
通俗地来说P问题就是多项式时间内可解的问题
NP问题 可以在非确定型图灵机上在多项式时间内找出解的问题的集合
如果一个问题,可以在多项式时间内验证他的解是否正确,则该问题是一个NP问题。显然 P ∈ N P P\in NP P∈NP (note:到目前为止,P不等于NP)
NP-C问题(NP-Complete) 这里Complete是完备的意思
一个决定性问题C若是为NPC,则代表它对NP是完备的,这表示:
a) 该问题是一个NP问题对于一个NP-C问题,我们不可能尝试将所有的NP规约到它,所以通常采用下述方法证明一个问题是NP-C问题:
b) 所有属于NP的问题都可归约成该问题
a) 证明给定该问题的一个解,可以在多项式时间验证该问题在计算复杂度理论内,一个极度重要的成就是史提芬·古克在1971年证明出了第一个NP-完全问题— 布尔可满足性问题。
b) 可以将一个已知的NP-C问题规约到该问题(已经证明的NPC问题:卡普的21个NPC问题或者A compendium of NP optimization problems)
Cook定理(1971) 可满足问题属于NP-C可满足问题(SAT)
可满足问题是判断任意给定的一个布尔表达式是否存在一个真赋值(如果有这样一个真赋值,则称该布尔表达式可满足)
NP-Hard 相较于NP-C问题,NP-Hard问题仅满足条件2
即所有的NP问题都可以规约到NP-Hard问题我们可以得到以下的关系图:
通常通过将一个已知的NP-C问题规约到该问题来证明一个问题是NP-Hard问题
证明 P = N P P=NP P=NP是一个未解决的千禧年难题,当然如果最终证明 P = N P P=NP P=NP,会发生很多“有趣”的事情:比如当下流行的密码理论将不再安全,可能这时能够期待的就只有量子加密技术的早日出现吧。
基本概念
多项式时间 多项式时间可解的问题,即P问题,通常被认为是一个易解的问题;一个多项式时间的算法往往也被认为是好的算法。然而多项式时间具体是什么含义?
在计算复杂度理论中,多项式时间(Polynomial time)指的是一个问题的计算时间m(n)不大于问题大小n的多项式倍数。用数学语言描述则为 m ( n ) = O ( n k ) , k m(n)= O(n^k),k m(n)=O(nk),k为一常量值。
规约(reduction) 在可计算性理论与计算复杂性理论中,归约是将某个计算问题转换为另一个问题的过程。比较直观的说法:如果一个能有效解决问题B的算法,也可以作为解决问题A的子程序,则将问题A称为“可归约”到问题B,因此求解A并不会比求解B更困难。
规约是证明NP-Hard问题的一种常用方法,通常用 < = <= <=这个符号来表示,如 p < = Q p<=Q p<=Q,表示P is reducible to Q , or Q is the reduction from P or P is reduced to Q(P问题可以归约到Q问题,or可以把P归约到Q)。方便记忆的话,这里的规约符号可以记作小于且等于,即说明问题P至少比Q容易,或者Q至少比P难
【计算复杂性理论】可以说,一个问题归约为另一个问题的过程,是将问题复杂化的过程。归约得到问题的应用范围往往也扩大了。例如,一元二次方程的求解和一元一次方程的求解。
- 问题A能够规约为问题B
a) 一个能求解问题B的算法一定可以用来求解问题A(以子问题的形式)
b) 求解问题A的难度一定不会比求解问题B的难度大(这里的难度大指的是求解过程需要更多的计算、存储资源等)。——>可以从侧面证明,如求解A的难度更大,而由于A可以规约为问题B,则可以用求解问题B的算法来求解问题A,则求解A的算法可以替换为一个难度更低的算法- 规约具有传递性:A可以规约为B,B能规约为C,则A一定可以规约为C
规约的类型较多,在本文中的规约特指多项式时间规约,即在多项式时间内将一个问题规约到另一个问题。
多项式归约主要做的就是以下两个转化(注意两个转化都要在polynomial的时间内完成)
- 把P的输入转化到Q的输入;
- 把Q的输出转化到P的输出。
3SAT问题定义如下:
给定一个有穷的布尔变量集合 X = { x 1 , x 2 , ? ? , x n } , ∣ X ∣ = n X=\{x_1,x_2,\cdots,x_n\},|X|=n X={x1?,x2?,?,xn?},∣X∣=n,每个变量取值为0或1,有一组子句(Clause) C = { C 1 , C 2 , ? ? , C m } , ∣ C ∣ = m , C = C 1 ∩ C 2 ∩ ? ∩ C m C=\{C_1,C_2,\cdots,C_m\},|C|=m,C=C_1\cap C_2\cap\cdots \cap C_m C={C1?,C2?,?,Cm?},∣C∣=m,C=C1?∩C2?∩?∩Cm?,每个 C i C_i Ci?是由三个变量组成的析取范式,即 z 1 ∪ z 2 ∪ z 3 z_1\cup z_2 \cup z_3 z1?∪z2?∪z3?.其中
- x i x_i xi?是布尔变量(Variable)
- 一个布尔变量 x i x_i xi?或它的否定形式 x i ˉ \bar{x_i} xi?ˉ?是文字(literal)
- C i C_i Ci?为子句,一个子句包含3个文字(literal)
一个3SAT的例子:
X = { x 1 , x 2 , x 3 } , C = { C 1 , C 2 , C 3 } , C 1 = x 1 ∪ x 2 ˉ ∪ x 3 , C 2 = x 1 ˉ ∪ x 2 ˉ ∪ x 3 , C 3 = x 1 ˉ ∪ x 2 ∪ x 3 ˉ X=\{x_1,x_2,x_3\},C=\{C_1,C_2,C_3\},C_1=x_1\cup \bar{x_2}\cup x_3,C_2=\bar{x_1}\cup \bar{x_2}\cup x_3,C_3=\bar{x_1}\cup x_2\cup \bar{x_3} X={x1?,x2?,x3?},C={C1?,C2?,C3?},C1?=x1?∪x2?ˉ?∪x3?,C2?=x1?ˉ?∪x2?ˉ?∪x3?,C3?=x1?ˉ?∪x2?∪x3?ˉ?对于3SAT问题,有以下结论
存在一个真值赋值: x 1 , x 2 = 1 , x 3 = 1 x_1,x_2=1,x_3=1 x1?,x2?=1,x3?=1,使得 C = 1 C=1 C=1,即该布尔表达式是可满足的
3 S A T ∈ N P C 3SAT\in NPC 3SAT∈NPC0-1背包问题
众所周知,0-1背包问题是一个NP-C问题,应用动态规划算法可以得到伪多项式时间的算法,如何证明0-1背包问题是一个NP-C问题?
0-1 背包问题(0-1 Knapsack)在数学上的定义如下:
通俗的来讲就是:
我们有n种物品,物品j的重量为 w j w_j wj?,价格为 p j p_j pj?,我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W.在限定的总重量内,我们如何选择,才能使得物品的总价格最高.如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题0-1背包问题本质上是一个优化问题,为了证明0-1背包问题是一个NP-C问题,我们首先引入0-1背包问题对应的判定问题(记作0-1 Knapsack Fill )
我们有n种物品,物品j的重量为 w j w_j wj?,价格为 p j p_j pj?,我们假定所有物品的重量和价格都是非负的,限定每种物品只能选择0个或1个,是否存在一个选择策略,使得选择的物品总重量为W看上去似乎引入0-1 Knapsack Fill问题没有任何用处,实际上对于优化问题和其对应的判定问题,有如下结论:
一个优化问题,不会比其对应的判定问题简单由此,可以从0-1 Knapsack Fill问题入手,来证明0-1 Knapsack问题的复杂性
- 证明0-1 Knapsack Fill∈ \in ∈ P问题
显然给定0-1 Knapsack的一个解,可以在多项式时间内验证该解是否正确:对选取的物品集合做一次遍历,累加得到价格和重量总和,即可验证。所以0-1 Knapsack Fill∈ \in ∈ P问题.
- 将一个已知的NP-C问题规约到0-1 Knapsack Fill问题(多项式时间内)
证明3SAT<=0-1 Knapsack Fill
- 对于一个3SAT问题,设 X = { x 1 , x 2 , ? ? , x n } , ∣ X ∣ = n X=\{x_1,x_2,\cdots,x_n\},|X|=n X={x1?,x2?,?,xn?},∣X∣=n,有一组子句 C = { C 1 , C 2 , ? ? , C m } , ∣ C ∣ = m , C = C 1 ∩ C 2 ∩ ? ∩ C m C=\{C_1,C_2,\cdots,C_m\},|C|=m,C=C_1\cap C_2\cap\cdots \cap C_m C={C1?,C2?,?,Cm?},∣C∣=m,C=C1?∩C2?∩?∩Cm?。
- 对于0-1 Knapsack Fill问题,存在一组物品 U U U和背包容量W,我们希望得到结论:当且仅当C可满足时,存在物品集合的子集 U ′ ∈ U U^{'}\in U U′∈U 使得 ∑ u ∈ U ′ w ( u ) = W \sum_{u\in U^{'}} w(u)=W ∑u∈U′?w(u)=W。
- 对于每个布尔变量 x i x_i xi?,对应 u i 和 u i ˉ u_i和\bar{u_i} ui?和ui?ˉ?
- 对于每个子句 c j c_j cj?,定义两个补偿对象(compensating objects) c o 1 j 和 c o 2 j co1_j和co2_j co1j?和co2j?
- 用 ( n + m ) (n+m) (n+m)长度的3进制数表示物品重量 w ( u ) w(u) w(u),其中第 i i i个数字与布尔变量 x i x_i xi?相关;第 ( n + j ) (n+j) (n+j)个数字,与子句 c j c_j cj?相关。
- 对于 u i 和 u i ˉ u_i和\bar{u_i} ui?和ui?ˉ?:
- 最右边 n n n个数字:第 i i i个数字为1,其余数字为0
- 最左边 m m m个数字:如果 x i ( 与 u i x_i(与u_i xi?(与ui?相关)或者 x i ˉ ( 与 u i ˉ 相 关 ) \bar{x_i}(与\bar{u_i}相关) xi?ˉ?(与ui?ˉ?相关)在子句 c j c_j cj?中出现,则第 n + j n+j n+j个数字为1,其余数字为0
- 对于 c o 1 j 和 c o 2 j co1_j和co2_j co1j?和co2j?:
- 最右边 n n n个数字:全为0
- 最左边 m m m个数字(用来标识对应的子句 c j c_j cj?):第 n + j n+j n+j个数字为1,其余数字为; c o 1 j 和 c o 2 j co1_j和co2_j co1j?和co2j?的重量相同
- 背包容量 W W W
- 最右边 n n n个数字:全为1
- 最左边 m m m个数字:全为3
- 对于 u i 和 u i ˉ u_i和\bar{u_i} ui?和ui?ˉ?:
- U = { u i , u i ˉ : 1 ≤ i ≤ n } ∪ { c o 1 j , c o 2 j : 1 ≤ j ≤ m } U=\{u_i,\bar{u_i}: 1\leq i\leq n\}\cup\{co1_j,co2_j: 1\leq j \leq m\} U={ui?,ui?ˉ?:1≤i≤n}∪{co1j?,co2j?:1≤j≤m}
- w ( u i ) 由 ( n + m ) w(u_i)由(n+m) w(ui?)由(n+m)个二进制数组成
- 第 i i i个数字为1
- 当且仅当 x i x_i xi?在子句 c j c_j cj?中出现时,第 n + j n+j n+j个数字为1
- 其余所有数字均为0
- w ( u i ˉ ) 由 ( n + m ) w(\bar{u_i})由(n+m) w(ui?ˉ?)由(n+m)个二进制数组成
- 第 i i i个数字为1
- 当且仅当 x i ˉ \bar{x_i} xi?ˉ?在子句 c j c_j cj?中出现时,第 n + j n+j n+j个数字为1
- 其余所有数字均为0
- w ( c o 1 j ) = w ( c o 2 j ) 由 ( n + m ) w(co1_j)=w(co2_j)由(n+m) w(co1j?)=w(co2j?)由(n+m)个二进制数组成
- 第 n + j n+j n+j个数字为1
- 其余所有数字均为0
- w ( u i ) 由 ( n + m ) w(u_i)由(n+m) w(ui?)由(n+m)个二进制数组成
- 背包容量 W W W为 ( n + m ) (n+m) (n+m)长度的二进制数
- 最右的 n n n个数为1
- 最左的 m m m个数为3
- 先证明存在物品集合 U ′ ∈ U U^{'}\in U U′∈U使得 ∑ u ∈ U ′ w ( u ) = W \sum_{u\in U^{'}} w(u)=W ∑u∈U′?w(u)=W时,C可满足
- 假设已得到部分物品集合 U ′ ∈ U U^{'}\in U U′∈U使得 ∑ u ∈ U ′ w ( u ) = W \sum_{u\in U^{'}} w(u)=W ∑u∈U′?w(u)=W
- 最右边的 n n n个数字全为1:保证 u i , u i ˉ u_i,\bar{u_i} ui?,ui?ˉ?有且仅有一个出现在集合 U ′ U^{'} U′(否则第 i i i个数字的值为0或2,与假设冲突)——>可以得到一组3SAT中布尔变量的赋值,记作 v v v。
- 如果 u i ∈ U ′ u_i\in U^{'} ui?∈U′,则有 x i v = 1 x_i^{v}=1 xiv?=1
- 如果 u i ˉ ∈ U ′ \bar{u_i}\in U^{'} ui?ˉ?∈U′,则有 x i ˉ v = 1 或 者 x i v = 0 \bar{x_i}^{v}=1或者x_i^v=0 xi?ˉ?v=1或者xiv?=0
- 最右边的 m m m个数字均为3:保证每个子句 c j c_j cj?均是可满足的,即 C C C可满足
- 如果 c o 1 j , c o j 2 均 不 属 于 U ′ co1_j,coj_2均不属于U^{'} co1j?,coj2?均不属于U′,有 ∑ u ∈ U ′ , u = u i o r u = u i ˉ w ( u ) = 3 \sum_{u\in U^{'},u=u_i or u=\bar{u_i}} w(u)=3 ∑u∈U′,u=ui?oru=ui?ˉ??w(u)=3。所以子句 c j c_j cj?中的布尔变量均为1,所以每个子句均可满足
- 有且仅有 c o 1 j , c o j 2 中 的 一 个 属 于 U ′ co1_j,coj_2中的一个属于U^{'} co1j?,coj2?中的一个属于U′,,有 ∑ u ∈ U ′ , u = u i o r u = u i ˉ w ( u ) = 2 \sum_{u\in U^{'},u=u_i or u=\bar{u_i}} w(u)=2 ∑u∈U′,u=ui?oru=ui?ˉ??w(u)=2。所以子句 c j c_j cj?中有两个布尔变量为1,所以每个子句均可满足(合取范式)
- c o 1 j , c o j 2 均 属 于 U ′ co1_j,coj_2均属于U^{'} co1j?,coj2?均属于U′,,有 ∑ u ∈ U ′ , u = u i o r u = u i ˉ w ( u ) = 1 \sum_{u\in U^{'},u=u_i or u=\bar{u_i}} w(u)=1 ∑u∈U′,u=ui?oru=ui?ˉ??w(u)=1。所以子句 c j c_j cj?中有一个布尔变量为1,所以每个子句均可满足(合取范式)
- 证明当C可满足时,存在物品集合的子集 U ′ ∈ U U^{'}\in U U′∈U 使得 ∑ u ∈ U ′ w ( u ) = W \sum_{u\in U^{'}} w(u)=W ∑u∈U′?w(u)=W
- 与上述证明过程类似,这里不再赘述
- 输入过程: x i , x i ˉ 与 u i , u i ˉ x_i,\bar{x_i}与u_i,\bar{u_i} xi?,xi?ˉ?与ui?,ui?ˉ?对应; x i , x i ˉ 是 否 在 子 句 c j 中 出 现 由 第 ( n + j ) 个 数 字 标 识 x_i,\bar{x_i}是否在子句c_j中出现由第(n+j)个数字标识 xi?,xi?ˉ?是否在子句cj?中出现由第(n+j)个数字标识,结合而成的 ( n + m ) (n+m) (n+m)个数字表示物品重量
- 输出过程:当且仅当C可满足时,存在物品集合的子集 U ′ ∈ U U^{'}\in U U′∈U 使得 ∑ u ∈ U ′ w ( u ) = W \sum_{u\in U^{'}} w(u)=W ∑u∈U′?w(u)=W。
3SAT:
X = { x 1 , x 2 , x 3 , x 4 , x 5 } , C = { c 1 , c 2 , c 3 , c 4 } , c 1 = { x 1 , x 2 ˉ , x 4 } , c 2 = { x 2 , x 3 ˉ , x 5 ˉ } , c 3 = { x 3 , x 4 , x 5 } , c 4 = { x 1 ˉ , x 2 , x 5 ˉ } X=\{x_1,x_2,x_3,x_4,x_5\},C=\{c_1,c_2,c_3,c_4\},c_1=\{x_1,\bar{x_2},x_4\},c_2=\{x_2,\bar{x_3},\bar{x_5}\},c_3=\{x_3,x_4,x_5\},c_4=\{\bar{x_1},x_2,\bar{x_5}\} X={x1?,x2?,x3?,x4?,x5?},C={c1?,c2?,c3?,c4?},c1?={x1?,x2?ˉ?,x4?},c2?={x2?,x3?ˉ?,x5?ˉ?},c3?={x3?,x4?,x5?},c4?={x1?ˉ?,x2?,x5?ˉ?}
对应的0-1 Knapsack Fill问题:
U = { u 1 , u 1 ˉ , u 2 , u 2 ˉ , u 3 , u 3 ˉ , u 4 , u 4 ˉ , u 5 , u 5 ˉ , c o 1 1 , c o 2 1 , c o 1 2 , c o 2 2 , c o 1 3 , c o 2 3 , c o 1 4 , c o 2 4 } U=\{u_1,\bar{u_1},u_2,\bar{u_2},u_3,\bar{u_3},u_4,\bar{u_4},u_5,\bar{u_5},co1_1,co2_1,co1_2,co2_2,co1_3,co2_3,co1_4,co2_4\} U={u1?,u1?ˉ?,u2?,u2?ˉ?,u3?,u3?ˉ?,u4?,u4?ˉ?,u5?,u5?ˉ?,co11?,co21?,co12?,co22?,co13?,co23?,co14?,co24?},W=333311111.
物品集合U中物品对应重量为:
对于0-1 knapsack问题,给定其一个解,无法在多项式时间内验证该解是否正确:
- 可以从侧面给出不严谨证明:0-1 knapsack是一个优化问题,如果能在多项式时间内验证一个解,相当于能在多项式时间内求出该优化问题的最优解
推荐阅读
- Python - Search Insert Position
- Leetcode35 搜索插入位置
- Data|单链表的增删查改
- 软件编程|STL使用总结
- Probabilistic|一次遍历等概率选取字符串中的某个字符
- 欧几里得算法(即辗转相除法)的时间复杂度log(N)的简洁证明
- 八皇后问题 回溯递归 C语言版
- memcopy
- HMM与序列标注