NP问题

介绍

相信大部分人在阅读论文或者求解问题过程中都会看到,这不就是NP问题之类的话。然后便去google什么是NP问题,之后仍是一头雾水,本人最开始也深受困扰,之后决心搞懂这类问题的真正含义,经过一番探究之后,才不由感慨数学的精妙。在这里感谢 Matrix67 这位博主,能够将这么复杂的问题解释的如此条理清晰与明确,学习之后深受启发!本文主要目的更多为进行的知识整理和巩固,方便日后复习。

时间复杂度的概念

在进行NP问题介绍之前,先对时间复杂度这个概念进行概括

时间复杂度是指执行算法所需要的计算工作量,即当问题规模扩大后,程序需要的时间长度增长得有多快。
也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而应该看当这个数据的规模变大到数百倍后,程序运行时间是否还是一样,或者也跟着慢了数百倍,或者变慢了数万倍。

不管数据有多大,程序处理花的时间始终是那么多的,我们就说这个程序很好,具有O(1)的时间复杂度,也称常数级复杂度;
数据规模变得有多大,花的时间也跟着变得有多长,这个程序的时间复杂度就是O(n),比如找n个数中的最大值;
而像冒泡排序、插入排序等,数据扩大2倍,时间变慢4倍的,属于O(n^2)的复杂度。
还有一些穷举类的算法,所需时间长度成几何阶数上涨,这就是O(a^n)的指数级复杂度,甚至O(n!)的阶乘级复杂度。

容易看出,几类复杂度被分为两种级别:

  1. 一种是O(1),O(log(n)),O(n^a)等,我们把它叫做 多项式级的复杂度,因为它的规模n出现在底数的位置;
  2. 另一种是O(a^n)和O(n!)型复杂度,它是非多项式级的复杂度,其复杂度计算机往往不能承受。

当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。

问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?
NO!
如问题:输出从1到n这n个数的全排列。
无论你如何输出,输出的复杂度都是n!
当然,有人说,这样的“问题”不是一个“正规”的问题,正规的问题是让程序解决一个问题,输出一个“YES”或“NO”(这被称为判定性问题),或者一个什么什么的最优值(这被称为最优化问题)。

如Hamilton回路 问题:

给你一个图,问你能否找到一条经过每个顶点一次且恰好一次(不遗漏也不重复)最后又走回来的路(满足这个条件的路径叫做Hamilton回路)。
这个问题现在还没有找到多项式级的算法。

P问题

如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。

NP问题

NP并不意味着非P类问题

NP问题是指这样一类问题:在多项式的时间里求一个解很难,但在多项式的时间里验证一个解很容易。
即,在一个题中,找一个解很困难,但验证一个解很容易。
当然也有不是NP问题的问题,即你猜到了解但是没用,因为你不能在多项式的时间里去验证它。

下面我要举的例子是一个经典的例子,它指出了一个目前还没有办法在多项式的时间里验证一个解的问题。很显然,前面所说的Hamilton回路是NP问题,因为验证一条路是否恰好经过了每一个顶点非常容易。但我要把问题换成这样:试问一个图中是否不存在Hamilton回路。这样问题就没法在多项式的时间里进行验证了,因为除非你试过所有的路,否则你不敢断定它“没有Hamilton回路”。

很显然,所有的P类问题都是NP问题。也就是说,能多项式地解决一个问题,必然能多项式地验证一个问题的解——既然正解都出来了,验证任意给定的解也只需要比较一下就可以了。关键是,人们想知道,是否所有的NP问题都是P类问题。即P=NP?

NP-完全问题

首先介绍 约化 的概念:一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A

比如说,现在有两个问题:求解一个一元一次方程和求解一个一元二次方程。那么我们说,前者可以约化为后者,意即知道如何解一个一元二次方程那么一定能解出一元一次方程。
这个规则即是:两个方程的对应项系数不变,一元二次方程的二次项系数为0。按照这个规则把前一个问题转换成后一个问题,两个问题就等价了。

“问题A可约化为问题B” 有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说,问题A不比问题B难。

从约化的定义中我们看到,一个问题约化为另一个问题,时间复杂度增加了,问题的应用范围也增大了。通过对某些问题的不断约化,我们能够不断寻找复杂度更高,但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法。

再回想前面讲的P和NP问题,联想起约化的传递性,自然地,我们会想问,如果不断地约化上去,不断找到能“通吃”若干小NP问题的一个稍复杂的大NP问题,那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的 NP问题的这样一个超级NP问题? 答案当然是肯定的。

换句话说,只要解决了这个问题,那么所有的NP问题都解决了。这种问题的存在难以置信,并且更加不可思议的是,这种问题不只一个,它有很多个,它是一类问题。这一类问题就是传说中的NPC 问题,也就是NP-完全问题。

NPC问题的出现使整个NP问题的研究得到了飞跃式的发展。我们有理由相信,NPC问题是最复杂的问题。

NPC问题的定义非常简单。同时满足下面两个条件的问题就是NPC问题。
首先,它得是一个NP问题; 然后,所有的NP问题都可以约化到它

证明一个问题是 NPC问题也很简单。先证明它至少是一个NP问题,再证明其中一个已知的NPC问题能约化到它

现在被证明是NPC问题的有很多,任何一个找到了多项式算法的话所有的NP问题都可以完美解决了。因此说,正是因为NPC问题的存在,P=NP变得难以置信。

NP-Hard问题

顺便讲一下 NP-Hard问题
NP-Hard问题是这样一种问题,它满足NPC问题定义的第二条 所有的NP问题都可以约化到它 ,但不一定要满足第一条(就是说,NP-Hard问题要比 NPC问题的范围广)。
NP-Hard问题同样难以找到多项式的算法,但它不一定是NP问题。即使NPC问题发现了多项式级的算法,NP-Hard问题有可能仍然无法得到多项式级的算法。

你可能感兴趣的:(算法整理)