P问题、NP问题、NPC问题、NP hard问题

图论算法摘要

1. 图的概念

一个(graph) G = ( V , E ) G=(V,E) G=(V,E)顶点(vertex)集 V V V边(edge)集 E E E 组成。
每一条边就是一个点对 ( a , b ) , a , b ∈ V (a,b),a,b∈V (a,b),a,bV。有时候也把边叫做弧(arc)。

有向图

如果点对 ( a , b ) , a , b ∈ V (a,b),a,b∈V (a,b),a,bV是有序的,那么图就是有向的(directed)。即 ( a , b ) (a,b) (a,b) ( b , a ) (b,a) (b,a)指不同的边。即这条边必须从点a指向点b,而不能反过来。
有向的图称为有向图(digraph)。
顶点 m m m n n n邻接当且仅当 ( m , n ) ∈ E , m , n ∈ V (m,n)∈E,m,n∈V (m,n)E,m,nV

无向图

如果点对 ( a , b ) , a , b ∈ V (a,b),a,b∈V (a,b),a,bV是无序的,那么图就是无向的(directed)。即 ( a , b ) (a,b) (a,b) ( b , a ) (b,a) (b,a)指同一条边。
无向的图称为无向图(digraph)。

有时候边还能有第三种成分,称作权(weight)或值(cost)。

2. P问题、NP问题、不可判定问题

P问题:能够在多项式时间内可用算法求解的问题
NP问题:非确定型多项式时间(nondeterministic polynomial-time)问题。
不可判定问题(undecidable problem):"不可能“解出的问题

P问题的例子:
假设图 G = ( V , E ) G=(V,E) G=(V,E)顶点(vertex)集 V V V边(edge)集 E E E 组成。顶点集 V V V存在子集 V s u b V_{sub} Vsub,边集 E E E存在子集 E s u b E_{sub} Esub
欧拉回路问题:找出一条路径恰好经过 E s u b E_{sub} Esub 每条边一次,计算复杂度为 O ( n ) O(n) O(n)

NP问题的例子:
哈密顿圈问题:找出一个简单圈,该圈包含 V s u b V_{sub} Vsub 的每一个顶点;通过图G的每个结点一次,且仅一次的通路(回路),就是哈密顿通路(回路),也称哈密顿圈。存在哈密顿圈的图就是哈密顿图。尚且不知道有线性算法。更进一步地,哈密顿圈问题是NPC问题。

不可判定问题的例子:
停机问题:让C编译器能够检查语法错误和所有无限循环

难度:P问题

不是所有可判定问题都是NP。例如无哈密顿圈问题不确定是否属于NP。

3. P问题、NP问题、NPC问题、NP hard问题

与NP相关的总共有四类问题:P问题、NP问题、NPC问题和NP hard问题,是计算复杂度理论中研究的主要内容之一。

P问题:Polynomial-time问题,能够在多项式时间内用算法求解的问题 。

P类问题:所有可以在多项式时间内求解的判定问题构成P类问题。判定问题:判断是否有一种能够解决某一类问题的算法的研究课题。

NP问题:Nondeterministic polynomial-time问题,指不确定是否存在多项式时间的求解算法,但可以在多项式时间内验证一个猜测解的正确性的问题。

NP类问题:所有的非确定型多项式时间可解的判定问题构成NP类问题。由于解本身显然提供了验证方法,因此NP类问题包括所有具有多项式时间解的问题。但是,既然验证一个答案比提供一个答案容易得多,而且NP只保证了验证算法具有多项式时间,因此在NP中就会存在不具有多项式时间解法的问题。然而,这样的问题至今未被发现。

NP=P?猜想

针对NP问题有一个千年难题,即NP=P?,
也即是否所有能在多项式时间内验证得出正确解的问题,都是具有多项式时间求解算法的问题?
至今尚未有定论。

问题来源:
在一个周六的晚上,你参加了一个盛大的晚会。由于感到局促不安,你想知道这一大厅中是否有你已经认识的人。你的主人向你提议说,你一定认识那位正在甜点盘附近角落的女士罗丝。不费一秒钟,你就能向那里扫视,并且发现你的主人是正确的。然而,如果没有这样的暗示,你就必须环顾整个大厅,一个个地审视每一个人,看是否有你认识的人。
生成问题的一个解通常比验证一个给定的解时间花费要多得多。这是这种一般现象的一个例子。与此类似的是,如果某人告诉你,数13,717,421可以写成两个较小的数的乘积,你可能不知道是否应该相信他,但是如果他告诉你他可以因式分解为3607乘上3803,那么你就可以用一个袖珍计算器容易验证这是对的。
人们发现,所有的完全多项式非确定性问题,都可以转换为一类叫做满足性问题的逻辑运算问题。既然这类问题的所有可能答案,都可以在多项式时间内计算,人们于是就猜想,是否这类问题,存在一个确定性算法,可以在多项式时间内,直接算出或是搜寻出正确的答案呢?这就是著名的NP=P?的猜想。
不管我们编写程序是否灵巧,判定一个答案是可以很快利用内部知识来验证,而没有这样的提示而需要花费大量时间来求解,被看作逻辑和计算机科学中最突出的问题之一。它是斯蒂文·考克于1971年陈述的。

NP hard问题:Non-deterministic Polynomial hard problem(NPH)问题,如果所有NP问题可在多项式时间内转化(归约,意思是解决了后者也就相应的解决了前者)成某个问题,则该问题称为NP难问题。

这里规约的意思是将一个特殊问题一般化,即将原问题推广为一个最一般的、最有概括性、也更难的、计算复杂度更高的问题,这个问题具有最高的计算复杂度,如果这个最一般的问题也能有多项式时间求解算法,那么那些特殊的原问题也能有多项式时间求解算法。
解决了这个NP hard问题,所有NP问题都能够被解决了。

  • NP hard问题不一定是NP问题,有可能是不可判定问题。这时候说明原问题也是不可判定的。c

NPC问题:Non-deterministic Polynomial complete problem ,如果所有NP问题可在多项式时间内归约成某个NP问题,则该NP问题称为NP完全问题。NPC包含了NP中最难的问题。

解决了这个NPC问题。所有NP问题都能够被解决了。

  • NPC问题相当广泛,包括来自操作系统(调度和安全)、数据库系统、运筹学、逻辑学、特别是图论等不同领域的问题。
    可满足性问题、哈密顿圈问题、巡回售货员问题、最长路径问题都是NPC问题。 装箱(bin packing)问题、背包(knapsack)问题、图的着色(graph coloring)问题以及团(clique)的问题都是著名的NPC问题。NPC问题相当广泛,包括来自操作系统(调度和安全)、数据库系统、运筹学、逻辑学、特别是图论等不同领域的问题。
  • 背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?它是在1978年由Merkel和Hellman提出的。背包问题已经研究了一个多世纪,早期的作品可追溯到1897年数学家托比亚斯·丹齐格(Tobias Dantzig,1884-1956)的早期作品 ,并指的是包装你最有价值或有用的物品而不会超载你的行李的常见问题。

你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题并不是那种“只有搜才行”的问题,NPC问题才是,NPC是最难的NP问题。

总结一下:

  • P问题能够保证存在多项式时间求解算法;NP问题不确定是否存在多项式时间求解算法,但确定存在多项式时间验证算法。
  • P问题是NP问题的子集,因为存在多项式时间求解算法的问题,一定能够在多项式时间内被验证。
  • NP hard问题不一定是NP问题,有可能是不可判定问题。这时候说明原问题也是不可判定的。
  • NPC问题既是NP问题的子集,又是NP hard问题的子集,所以NPC问题是NP问题和NP hard问题的交集。
  • NP hard问题和NPC问题都要求能够在多项式时间规约成另外一个问题。这里规约的意思是将一个特殊问题一般化,即将原问题推广为一个最一般的、最有概括性、也更难的、计算复杂度更高的问题,这个问题具有最高的计算复杂度,如果这个最一般的问题也能有多项式时间求解算法,那么那些特殊的原问题也能有多项式时间求解算法。
  • 假设 N P = P NP=P NP=P 猜想不成立,那么计算复杂度的相对关系为(按照由低到高): P < N P < N P C < N P h a r d P < NP < NPC < NP hard P<NP<NPC<NPhard
  • 假设 N P = P NP=P NP=P 猜想成立,那么说明所有存在多项式时间验证算法的问题都存在多项式时间求解算法,而NPC本身属于NP问题,因此NPC也存在多项式时间求解算法,所以 N P C = P NPC=P NPC=P,所以 P = N P = N P C P=NP=NPC P=NP=NPC,属于NP hard问题的一个子集。

"NP问题一直都是信息学的巅峰。巅峰,意即很引人注目但难以解决。在信息学研究中,这是一个耗费了很多时间和精力也没有解决的终极问题,好比物理学中的大统一数学中的哥德巴赫猜想等。

目前为止这个问题还“啃不动”。但是,一个总的趋势、一个大方向是有的。人们普遍认为,P=NP不成立,也就是说,多数人相信,存在至少一个不可能有多项式级复杂度的算法的NP问题。人们如此坚信P≠NP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-完全问题,也即所谓的 NPC问题。C是英文单词“完全”的第一个字母。正是NPC问题的存在,使人们相信P≠NP。
NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。
NP-Hard放宽了限定条件,它将有可能比所有的NPC问题的时间复杂度更高从而更难以解决。"[4]

  • 各种问题的计算复杂度如下图(来自参考资料[1])所示:
    P问题、NP问题、NPC问题、NP hard问题_第1张图片

最后引用一下资料[3] [总结]算法中的P问题、NP问题、NP完全问题和NP难问题关于这几个问题的解释,因为太形象了,基本不需要修改,所以就直接搬运了:

"著名的NP类问题:旅行家推销问题(TSP)。即有一个推销员,要到n个城市推销商品,他要找出一个包含所有n个城市的环路,这个环路路径小于a。我们知道这个问题如果单纯的用枚举法来列举的话会有 ( n − 1 ) ! (n-1)! (n1)! 种,已经不是多项式时间的算法了,(注:阶乘算法比多项式的复杂)。那怎么办呢?我们可以用猜的,假设我人品好,猜几次就猜中了一条小于长度a的路径,我画画画画,好的,我得到了一条路径小于a的环路,问题解决了,皆大欢喜。可是,我不可能每次都猜的那么准,也许我要猜完所有种呢?所以我们说,这是一个NP类问题。也就是,我们能在多项式的时间内验证并得出问题的正确解,可是我们却不知道该问题是否存在一个多项式时间的算法,每次都能解决他(注意,这里是不知道,不是不存在)。
所以这就引出了这类讨论的一个千年问题:是否 NP类问题=P类问题?
即,是否所有能在多项式时间内验证得出正确解的问题,都是具有多项式时间算法的问题呢?
太让人震惊了,要是解决了这个问题,那岂不是所有的NP问题都可以通过计算机来解决?
圣战的结果是,有的存在,有的不存在。=_=
在这场圣战中,人们还发现了很多的东东,也就是我们接下来要介绍的NPC问题和NPH问题。

为了证明这个千古难题,科学家想出了很多办法。其中之一就是问题的约化。所谓问题约化就是,可以用问题B的算法来解决A ,我们就说问题A可以约化成问题B。举个例子,一元一次方程的求解,跟二元一次方程的求解,我们知道,只要能求解二元一次方程,那就可以用二元一次方程的解法来求解一元一次方程,只需要将一元一次方程加上y,并附加一个方程y=0就可以将一元一次方程变形为一个二元一次方程,然后用二元一次方程的解法来求解这个方程。注意,这里二元一次方程的解法会比一元一次的复杂。所以我们说,只需要找到解二元一次方程的规则性解法,那就能用这个规则性解法来求解一元一次方程。从这里也可以看出,约化是具有传递性的,如A约化到B,B约化到C,A就可以约化到C,同时不断约化下去,我们会发现一个很惊人的特性,就是他一定会存在一个最大的问题,而我们只需要解决了这个问题,那其下的所有问题也就解决啦!这就是我们所说的NPC问题的概念!!!
引到NP问题里就是,对于同一类的所有的NP类问题,若他们都可以在多项式时间内约化成最难的一个NP类问题,(我们直观的认为,被约化成的问题应具有比前一个问题更复杂的时间复杂度)当我们针对这个时间复杂度最高的超级NP问题要是能找到他的多项式时间算法的话,那就等于变向的证明了其下的所有问题都是存在多项式算法的,即NP=P!!!!给出NPC问题定义,
NPC问题:如果所有np问题都能在多项式时间内转化为他,则称该np问题为npc问题(NPC:NP
complete又叫NP完全问题)
NPC问题是NP问题的子集。

当然,很多时候NPC问题是找不到一个多项式时间算法的,更多时候他是一个指数级的算法。

最后介绍下NPH问题。
NPH问题:我们又叫NP难问题,他不是一个NP问题,然后所有的NPC问题都可以在多项式时间内转化为他的话,我们就叫他NPH(hard)问题。"

背景知识:确定性问题 VS 非确定性问题、确定性算法 VS 非确定性算法

确定型机器 VS 非确定型机器

  • 确定型机器在每个时刻都在执行一条命令,根据这条命令,机器再去实行下一条唯一确定的命令。
  • 非确定型机器对其后的步骤是有选择的,可以自由进行它想要的任意选择。如果这些后面的步骤中有一条导致问题的解,那么它总是选择这个正确的步骤。因此,非确定型机器具有非常好的猜测(优化)能力,例如应用于梯度下降
  • NP中的每一个问题都能够用一台非确定型计算机多项式时间内求解。
  • 计算机的一个形式化模型称作图灵机(Turing machine)。
  • 但是**没有人能够构建一台非确定型计算机,非确定性是非常有用的理论结构,但是并没有人们所想的那么强大。**即使使用非确定性,不可判定问题依然是不可判定的。

确定性问题 VS 非确定性问题 (including NP问题)

  • 确定性问题:有些计算问题是确定性的,例如加减乘除,只要按照公式推导,按部就班一步步来,就可以得到结果;
  • 非确定性问题:但是,有些问题是无法按部就班直接地计算出来。比如,找大质数的问题。有没有一个公式能推出下一个质数是多少呢?这种问题的答案,是无法直接计算得到的,只能通过间接的“猜算”来得到结果。这也就是非确定性问题。而这些问题的通常有个算法,它不能直接告诉你答案是什么,但可以告诉你,某个可能的结果是正确的答案还是错误的。
  • 多项式时间非确定性问题(NP问题):如果这个可以告诉你“猜算”的答案正确与否的验证算法,可以在多项式时间内算出来,就叫做多项式时间非确定性问题(NP问题)
  • 而如果这个问题的所有可能答案,都是可以在多项式时间内进行正确与否的验算的话,就叫完全多项式非确定问题。
  • 完全多项式非确定性问题可以用穷举法得到答案,一个个检验下去,最终便能得到结果。但是这样算法的复杂程度是指数关系,因此计算的时间随问题的复杂程度成指数的增长,很快便变得不可计算了。
  • 人们发现,所有的完全多项式非确定性问题,都可以转换为一类叫做满足性问题的逻辑运算问题。既然这类问题的所有可能答案,都可以在多项式时间内计算,人们于是就猜想,是否这类问题存在一个确定性算法,可以在多项式时间内直接算出或是搜寻出正确的答案呢?这就是著名的NP=P?的猜想
  • 解决这个猜想,无非两种可能,一种是找到一个这样的算法,只要针对某个特定NP完全问题找到一个算法,所有这类问题都可以迎刃而解了,因为他们可以转化为同一个问题。另外的一种可能,就是这样的算法是不存在的。那么就要从数学理论上证明它为什么不存在。

确定性算法 VS 非确定性算法(including NP算法)

  • 确定性算法:求解过程的每一步都是确定的,例如一元二次方程的求根算法,只要传入参数,每一步求解都是确定的,这种算法就叫做确定性算法。
  • 我们知道,生成问题的一个解通常比验证一个猜测解要花费更多的时间。判定一个答案是可以很快利用内部知识来验证,而没有这样的提示而需要花费大量时间来求解。也就是验证很简单,求解很困难。
  • 非确定性算法:非确定性算法将问题分解成猜测和验证两个阶段。算法的猜测阶段是非确定性的,算法的验证阶段是确定性的,它验证猜测阶段给出解的正确性
  • 多项式时间非确定性(NP)算法:设算法A是解一个判定问题Q的非确定性算法,如果A的验证阶段能在多项式时间内完成,则称A是一个多项式时间非确定性(NP)算法

时间复杂度关系(Big O)

时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快。[4]
“也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而应该看当这个数据的规模变大到数百倍后,程序运行时间是否还是一样,或者也跟着慢了数百倍,或者变慢了数万倍。不管数据有多大,程序处理花的时间始终是那么多的,我们就说这个程序很好,具有 O ( 1 ) O(1) O(1)的时间复杂度,也称常数级复杂度;数据规模变得有多大,花的时间也跟着变得有多长,这个程序的时间复杂度就是 O ( n ) O(n) O(n),比如找n个数中的最大值;而像冒泡排序、插入排序等,数据扩大2倍,时间变慢4倍的,属于 O ( n 2 ) O(n^2) O(n2)的复杂度。
还有一些穷举类的算法,所需时间长度成几何阶数上涨,这就是 O ( a n ) O(a^n) O(an)的指数级复杂度,甚至 O ( n ! ) O(n!) O(n!)的阶乘级复杂度。
不会存在 ( 2 ∗ n 2 ) (2*n^2) (2n2)的复杂度,因为前面的那个“2”是系数,根本不会影响到整个程序的时间增长。同样地, O ( n 3 + n 2 ) O (n^3+n^2) O(n3+n2)
的复杂度也就是 O ( n 3 ) O(n^3) O(n3)的复杂度。
因此,我们会说,一个 O ( 0.01 ∗ n 3 ) O(0.01*n^3) O(0.01n3)的程序的效率比 O ( 100 ∗ n 2 ) O(100*n^2) O(100n2)的效率低,尽管在n很小的时候,前者优于后者,但后者时间随数据规模增长得慢,最终 O ( n 3 ) O(n^3) O(n3)的复杂度将远远超过 O ( n 2 ) O(n^2) O(n2)
我们也说, O ( n 100 ) O(n^{100}) O(n100)的复杂度小于 O ( 1.0 1 n ) O(1.01^n) O(1.01n)的复杂度。(多项式时间小于指数级时间)
容易看出,前面的几类复杂度被分为两种级别,其中后者的复杂度无论如何都远远大于前者:一种是 O ( 1 ) , O ( l o g ( n ) ) , O ( n a ) O(1),O(log(n)),O(n^a) O(1),O(log(n)),O(na)
等,我们把它叫做多项式级的复杂度,因为它的规模n出现在底数的位置;另一种是 O ( a n ) O(a^n) O(an) O ( n ! ) O(n!) O(n!)型复杂度,它是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。” [4]

  • 按照计算时间递增的方向: O ( 1 ) < O ( l o g ( n ) ) < O ( l o g c n ) < O ( n ) < O ( n l o g ( n ) ) < O ( n 1.5 ) < O ( n 2 ) < O ( n c ) < O ( c n ) < O ( n ! ) < O ( n n ) O(1)<O(log(n))<O({log}^{c}n)<O(n)<O(nlog(n))<O(n^{1.5})<O(n^2)<O(n^c)<O(c^n)<O(n!)<O(n^n) O(1)<O(log(n))<O(logcn)<O(n)<O(nlog(n))<O(n1.5)<O(n2)<O(nc)<O(cn)<O(n!)<O(nn)
  • 多项式时间: O ( n c ) O(n^c) O(nc)
  • 指数时间:: O ( c n ) O(c^n) O(cn)
  • 很多时候NPC问题是找不到一个多项式时间算法的,更多时候它是一个指数级 O ( c n ) O(c^n) O(cn)的算法。
  • NP hard问题的计算复杂度不止多项式时间 O ( n c ) O(n^c) O(nc),可能是 O ( c n ) 、 O ( n ! ) , 甚 至 是 O ( n n ) O(c^n)、O(n!),甚至是O(n^n) O(cn)O(n!)O(nn)
  • 计算机处理的输入常常不是那么几十个几千个那么一点点,想象一下,当计算机处理的数据达到100万个的时候,时间复杂度为 O ( n 2 ) O(n^2) O(n2) O ( e n ) O(e^n) O(en)的算法,所需的运行次数简直是天壤之别, O ( e n ) O(e^n) O(en)指数级的可能运行好几天都没法完成任务,所以我们才要研究一个问题是否存在多项式时间算法。
  • 我们也只在乎一个问题是否存在多项式算法,因为一个时间复杂度比多项式算法还要复杂的算法研究起来是没有任何实际意义的

[1] NP问题、NP难问题(NPH)和NP完全问题(NPC)理解
[2] 百度百科——NP完全问题
[3] [总结]算法中的P问题、NP问题、NP完全问题和NP难问题
[4] 什么是P问题、NP问题和NPC问题

你可能感兴趣的:(图论算法)