精华内容
下载资源
问答
  • P问题NP问题NP完全问题NP问题

    万次阅读 多人点赞 2019-06-12 14:06:30
    在讲P类问题之前先介绍两个个概念:多项式,时间复杂度。(知道这两概念的可以自动跳过这部分) 1、多项式:axn-bxn-1+c 恩....就是长这个样子的,叫x最高次为n的多项式.... 咳咳,别嫌我啰嗦。。有些人说不定还真...

     

     

    转载出处。 https://blog.csdn.net/qq_21768483/article/details/80430590

    在讲P类问题之前先介绍两个个概念:多项式,时间复杂度。(知道这两概念的可以自动跳过这部分)

    1、多项式:axn-bxn-1+c

    恩....就是长这个样子的,叫x最高次为n的多项式....

    咳咳,别嫌我啰嗦。。有些人说不定还真忘了啥是多项式了。。例如第一次看到的鄙人→_→

    2、时间复杂度

    我们知道在计算机算法求解问题当中,经常用时间复杂度和空间复杂度来表示一个算法的运行效率。空间复杂度表示一个算法在计算过程当中要占用的内存空间大小,这里暂不讨论。时间复杂度则表示这个算法运行得到想要的解所需的计算工作量,他探讨的是当输入值接近无穷时,算法所需工作量的变化快慢程度。

    举个例子:冒泡排序。

    在计算机当中,排序问题是最基础的,将输入按照大小或其他规则排好序,有利于后期运用数据进行其他运算。冒泡排序就是其中的一种排序算法。假设手上现在有n个无序的数,利用冒泡排序对其进行排序,

    ①首先比较第1个数和第2个数,如果后者>前者,就对调他们的位置,否则不变

    ②接着比较第2个数和第3个数,如果后者>前者,就对调他们的位置,否则不变

    ③一直向下比较直到第n-1和第n个数比较完,第一轮结束。(这时候最大的数移动到了第n个数的位置)

     

    ④重复前三步,但是只比较到第n-1个数(将第二大的数移动到第n-1个数位置)

    ⑤持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

    举个实例:5,4,3,2,1,对其进行排序,先是比较5跟4变成4,5,3,2,1,第一轮结束后变成43215,可以计算,当对其排序完正好要经过4+3+2+1=10次比较,当然这是最复杂的情况,即完全反序。可以知道对于n个数,至多要经过1+2+...+n-1即(n^2-n)/2次比较才能排好序。这个式子里n的最高次阶是2,可知道当n→∞时,一次性对其比较次数影响很小,所以我们把这个算法的时间复杂度比作:o(n^2)。取其最高次,可以看出,这是一个时间复杂度为多项式的表示方式。

    时间复杂度排序o(1)<o(n)<o(lgn)<o(n^2)<o(n^a)<o(e^n)(a>2,n表示输入的数据个数,o(1)为常数级别)

     

    好了,介绍完上面的概念就可以开始讲关于什么叫P类问题了。以上个例子冒泡排序为例,我们知道了,在排序这个大问题里,是可以找到一种时间复杂度为多项式o(n^2)的算法(如冒泡排序法)来求解排序问题的,所以我们说排序问题是一个有多项式时间算法的问题。

    所以我们称,

    P类问题:存在多项式时间算法的问题。(P:polynominal,多项式)

     

    然后扯个题外话,为什么我们要研究这个?因为计算机处理的输入常常不是那么几十个几千个那么一点点,想象一下,当计算机处理的数据达到100万个的时候,时间复杂度为o(n^2)和o(e^n)的算法,所需的运行次数简直是天壤之别,o(e^n)指数级的可能运行好几天都没法完成任务,所以我们才要研究一个问题是否存在多项式时间算法。而我们也只在乎一个问题是否存在多项式算法,因为一个时间复杂度比多项式算法还要复杂的算法研究起来是没有任何实际意义的。

     

    好了,接下来我们介绍NP,先给定义,

    NP类问题:能在多项式时间内验证得出一个正确解的问题。(NP:Nondeterministic polynominal,非确定性多项式)

    P类问题是NP问题的子集,因为存在多项式时间解法的问题,总能在多项式时间内验证他。

     

    注意定义,这里是验证。NP类问题,我用个人的俗话理解就是,不知道这个问题是不是存在多项式时间内的算法,所以叫non-deterministic非确定性,但是我们可以在多项式时间内验证并得出这个问题的一个正确解。举个例子,

    著名的NP类问题:旅行家推销问题(TSP)。即有一个推销员,要到n个城市推销商品,他要找出一个包含所有n个城市的环路,这个环路路径小于a。我们知道这个问题如果单纯的用枚举法来列举的话会有(n-1)! 种,已经不是多项式时间的算法了,(注:阶乘算法比多项式的复杂)。那怎么办呢?我们可以用猜的,假设我人品好,猜几次就猜中了一条小于长度a的路径,我画画画画,好的,我得到了一条路径小于a的环路,问题解决了,皆大欢喜。可是,我不可能每次都猜的那么准,也许我要猜完所有种呢?所以我们说,这是一个NP类问题。也就是,我们能在多项式的时间内验证并得出问题的正确解,可是我们却不知道该问题是否存在一个多项式时间的算法,每次都能解决他(注意,这里是不知道,不是不存在)。

    所以这就引出了这类讨论的一个千年问题:是否 NP类问题=P类问题?

    即,是否所有能在多项式时间内验证得出正确解的问题,都是具有多项式时间算法的问题呢?

    太让人震惊了,要是解决了这个问题,那岂不是所有的NP问题都可以通过计算机来解决?

     

    圣战的结果是,有的存在,有的不存在。=_=

    在这场圣战中,人们还发现了很多的东东,也就是我们接下来要介绍的NPC问题(啊喂,我不是游戏NPC)和NPH问题。

    (PS :网络上经常有人说,这不是个NP问题吗,其实很多时候他们说的应该是NPC问题,而不是NP问题)

    为了证明这个千古难题,科学家想出了很多办法。其中之一就是问题的约化。所谓问题约化就是,可以用问题B的算法来解决A ,我们就说问题A可以约化成问题B。举个例子,一元一次方程的求解,跟二元一次方程的求解,我们知道,只要能求解二元一次方程,那就可以用二元一次方程的解法来求解一元一次方程,只需要将一元一次方程加上y,并附加一个方程y=0就可以将一元一次方程变形为一个二元一次方程,然后用二元一次方程的解法来求解这个方程。注意,这里二元一次方程的解法会比一元一次的复杂。所以我们说,只需要找到解二元一次方程的规则性解法,那就能用这个规则性解法来求解一元一次方程。从这里也可以看出,约化是具有传递性的,如A约化到B,B约化到C,A就可以约化到C,同时不断约化下去,我们会发现一个很惊人的特性,就是他一定会存在一个最大的问题,而我们只需要解决了这个问题,那其下的所有问题也就解决啦!这就是我们所说的NPC问题的概念!!!

    引到NP问题里就是,对于同一类的所有的NP类问题,若他们都可以在多项式时间内约化成最难的一个NP类问题,(我们直观的认为,被约化成的问题应具有比前一个问题更复杂的时间复杂度)当我们针对这个时间复杂度最高的超级NP问题要是能找到他的多项式时间算法的话,那就等于变向的证明了其下的所有问题都是存在多项式算法的,即NP=P!!!!给出NPC问题定义。

    (3)NPC类问题(Nondeterminism Polynomial complete):存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。其定义要满足2个条件: 

    首先,它得是一个NP问题;

    然后,所有的NP问题都可以约化到它。

    要证明npc问题的思路就是: 

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

    (4)NP难问题(NP-hard问题):

        NP-Hard问题是这样一种问题,它满足NPC问题定义的第二条但不一定要满足第一条(就是说,NP-Hard问题要比 NPC问题的范围广,NP-Hard问题没有限定属于NP),即所有的NP问题都能约化到它,但是他不一定是一个NP问题。

        NP-Hard问题同样难以找到多项式的算法,但它不列入我们的研究范围,因为它不一定是NP问题。即使NPC问题发现了多项式级的算法,NP-Hard问题有可能仍然无法得到多项式级的算法。事实上,由于NP-Hard放宽了限定条件,它将有可能比所有的NPC问题的时间复杂度更高从而更难以解决。

     

    以上四个问题他们之间的关系可以用下图来表示: 
    这里写图片描述

    展开全文
  • NP问题总结(概念+例子+证明)

    千次阅读 2020-03-29 20:22:11
    本文是自己对NP问题的一次总结,因为看别的博客要不只讲概念,要不只有例子,算是一次汇总吧,加上自己的一点小理解,由于看了一段时间才进行总结的,有些图是直接用的别人画好的,但是不记得网址了,特此鸣谢~

    目录

    基本概念

    证明思路

    常见例子

    21个常见NPC问题

    原理论证


    基本概念

    P问题:(polynominal)    存在多项式时间算法的问题,即在多项式时间内可解的问题;

       例如:冒泡排序、快速排序等问题;

    NP问题:(Nondeterministic polynominal在多项式时间内验证出一个正确解的问题,也就是说这个问题不一定在多项式时间内可解,但可以在多项式时间内验证;

       例如:大数分解问题,比如180576这个数让你拆成两个数相乘,必须是三位乘以三位的,可能很久都解不出来(如果是一个很大很大的数的话),但是我告诉你这是352*513得到的,那么很简单就能在多项式时间内验证是否正确,这就是NP问题;

     

    NPC类问题Nondeterminism Polynomial complete):存在这样一个NP问题,所有的NP问题都可以约化成它。  

    NP-Hard类问题Nondeterminism Polynomial hard):所有NP问题都可以约化成它。

    这里插一句,何为约化,以及两者的具体解释我在下面给出,但是可以看的所谓的NP完全问题和NP难问题的唯一差别就是这个问题本身是不是NP问题。然后两者都是可以被所有NP问题约化的。那也就是说,NP-H问题是包含NPC问题的,而NPC又至少是一个NP问题,那么它也被NP包含,但NP-H问题不一定是NP问题,所以有一部分NP-H问题是NP,有一部分不是,这样整个概念相互包含与相交的逻辑就出来了,如下:

    因此说了这么多,个人认为为什么要判断一个问题是哪类问题,原因在于,它有助于让我们在决心实现这类问题之前对问题的难易程度进行一个有效的判断。如果一个问题是一个NP难问题,众所周知我们是不一定能够找到最优解的,有时候持有次优解即可。如果一个问题连NP问题都不是,也就是说我在多项式时间内连验证它都很费劲,又谈何解决出来呢?这类问题就不大有研究的必要了;

    证明思路

    前面的概念留了一个点,说NP-H问题和NPC问题都是所有NP问题可以约化到的,那么究竟什么是约化?我了解到的:B能解决A,那么就说A可以约化到B,也就是说,B是一个复杂度比A更高的算法,B通过某种特殊情况(简化),可以变成A问题,比如B问题是二元一次方程,A问题是一元一次方程,当B问题,y=0时,它就转变成了一元一次问题。也就是说B问题能解决A,那么就说A问题可以约化到B;

    那说了这么多,NPC的或者NP-H问题的证明思路究竟是什么呢?首先我要先判断一下这个问题本身是不是NP问题(给出一个解能否在多项式时间内验证),然后找到一个已知的NPC问题去约化到这个问题,因为我去验证一个问题,把所有NP问题都约化一遍到我这个问题上不太可能,而NPC问题本身的定义就是所有NP问题可以约化到它,那我拿一个已知的NPC问题,去验证这个NPC问题可以约化到它,即

                     所有NP问题->已知的NPC问题->亟待解决的新问题;

    这样,也就简化了我去验证一个新问题是不是NPC问题的方式;

    证明是NP-Complete 问题:                                                                        证明是NP-Hard 问题:

    ①证明本身是NP问题;                                                                               ①无需证明本身是NP问题;

    ②证明一个已知的NPC问题能约化到它                                                       ②证明一个已知的NPC问题能约化到它;

     

    常见例子

    说了这么多,再来两个例子来巩固一下:

    首先是一个诱导子图的问题,问题描述在第一行,那么想证明这个问题是不是NPC问题(是NPC就一定是NP-H了),首先判断它是不是NP问题,那么给出一个子图包含K个点,问你是否最少包含l条边,很容易就能验证,即在多项式时间内可以验证,是NP问题。

    其次,找到一个已知的NPC问题,验证这个已知的NPC问题可以约化到这个新问题,那么就能证明他是NPC问题了(即找到一个特殊情况把这个问题简化到已知的NPC问题)

    那么当l=C_{k}^{2}时,该问题就变成了找一个K大小的完全子图(因为完全子图边和顶点的关系就是C_{k}^{2}),而找完全子图的问题也称Clique问题,是一个已知的NPC问题,那么通过设定l的特殊取值,将待解决问题转化成了现有NPC问题,即由一个NPC问题约化而来,本例得证;

     

    2.

    In the HITTING SET problem, we are given a family of sets {S1, S2, . . . , Sn} and a budget b, and we wish to find a set H of size b which intersects every Si , if such an H exists. In other words, we want HSi ∅ for all i.

    Show that HITTING SET is NP-complete.

    大概的意思就是这是一个碰撞集问题,这个集合H跟Si的各个集合都相交:

     

    然后来证明他是一个NPC问题:

    ①首先证明它是一个NP问题,像我上图一样,如果给出了一个集合H,问你它是否跟所有的Si都相交,那么这是在多项式时间内可以验证的;即是NP问题;

    ②证明一个已知的NPC问题可以约化到它:

       当我把Si集合特殊化,即我把每条边当成一个Si,集合的元素就是每条边的两端,更改后图如下:

    然后把问题变成,找该图中的最小顶点覆盖问题(Vertex cover),即找到的集合包含图中每条边的至少一端。这样也满足了我的集合H和所有Si集合都相交(将Si集合特化成一条边的作用),那么我亟待解决的问题就特化成了已知的NPC问题——最小顶点覆盖问题。那么本例得证;

    21个常见NPC问题

    既然现有的方式是找到一个已有的NPC问题去验证我要验证的新问题,那么知道了解现有的NPC问题就变得很重要,下面列举了常见的NPC问题,而每个子主题(往后错一格)代表这我可以由前面的主题约化而来:

    可以看到,这些问题约化来约化去,都是有一个初始问题的,因为一个问题由另一个已知的NPC问题约化而来,那么第一个NPC问题是怎么来的?那就要用到NPC问题的本身定义了:所有的NP问题可以约化到它;

    这个方式就是经典的SAT问题,由上图也可以看到,这些已有的NPC问题它的最开始,都是用SAT问题证明的;

    原理论证

    证明了所有的算法都是可以编码为boolean formula(布尔型)问题,这意味着所有算法都可以使用SAT求解,因为他们本质上就是boolean formula问题。

     

    对于任意的boolearn foumula成以下标准式:                

                                              (..∨...∨..)∧(..∨...∨..)∧...

                                                               SAT:如何取值,使式子为真?或根本         

                                                                      不存在一个取值使式子为真。

    这些话是我做的ppt里写的,直接拷过来,意思就是,这所有算法无外乎就是在一个给定集合中找到解,或者无解,而这些算法的选择,条件等等都是可以编码为布尔型,用合取范式的方式表述这个算法的情况,算法有解,就代表合取范式为真,算法无解,就代表这个式子取值为假。

    具体还是看例子,用SAT模型去证明我上面所说的Clique问题:

    首先看这个图,我要找它的k=3 的clique也就是完全子图,答案先放在这(b、c、d)

    那现在将他编码为布尔型,任意编码,但边代表着我的相邻节点必须可以同时为真,像a,b可以同时取值为X1,X2,但不能同时取值X1和,然后图就变成下图:

    编完码后,将其写成SAT的合取范式模型,这里因为k=3,所以合取范式里的析取范式个数为3,搭配是任意的:

    写完后,找到一个k=3的clique,就变成了找到这个合取范式为真的情形。是单独的,所以它必须为真,那么X1就是假,那X2就必须为真,为假,那么X3就必须为真,由此得出,编码bcd为真,即k=3的clique找到了;

     

    以上就是NP问题的概念+证明逻辑+例子,当然自己只是浅显的学习,如果有错误或者论证思路不严密,还望赐教;

     

    注:我这里一直再说NPC NPC,因为NPC是包含在NP-Hard问题里的,很多人所讲的这个问题是np难的,其实就是NPC问题,因为NPC比np难多了一个问题本身是NP的,如果这个问题你连验证都验证不了,又谈何解决呢?

    展开全文
  • 算法:NP问题NP完全问题(NPC),NPhard问题

    万次阅读 多人点赞 2016-12-14 22:51:03
    在做计算机算法关于NP完全问题这一章的作业的时候,发现有很多概念理解的不是很透彻,然后就反复看老师的讲义,在网上查阅各种资料,花了很多时间来弄懂这块的内容。发现书上的概念太正式,定义太标准,不容易很快...

        在做计算机算法关于NP完全问题这一章的作业的时候,发现有很多概念理解的不是很透彻,然后就反复看老师的讲义,在网上查阅各种资料,花了很多时间来弄懂这块的内容。发现书上的概念太正式,定义太标准,不容易很快理解,而网上的资料有些地方论述的不够全面,像我这样的新手在遇到NP家族的概念和问题的时候就很容易懵逼…因此在此将我的心得与整理的资料放在这里,一方面供我以后自己参考,避免又搞混,一方面和大家进行交流。

    一、概念介绍

    下面就对这些令人头疼的概念做个简单的介绍和对比:

    1. P类问题

        这类问题是最简单的一类问题,即所有这类问题都可以用一个确定性算法在多项式时间内求出解。此类问题的复杂度是此类问题的一个实例的规模n的多项式函数。比如排序问题,求最短路径问题等。

    2. NP(Non-deterministic Polynomial,即多项式复杂程度的非确定性问题)问题

        有些问题很难找到多项式时间的解法(也许根本就不存在),但是如果给出了该问题的一个解,我们可以在多项式时间内判断这个解是否正确,比如对于哈密尔顿回路问题,如果给出一个任意的回路,我们可以很容易的判断出该回路是否是哈密尔顿回路(看是不是所有顶点都在回路中)。


    P类问题是NP问题的子集,原因是P类问题既然能在多项式时间内求解,也必然能在多项式时间在验证它的解,满足NP类问题的定义。

    3. NP完全问题(NPC)


        如果所有NP问题都能在多项式时间内转化为A,则称A为NPC问题。

    NPC是NP的子集。

    4. NP-hard问题(NPH,NP困难问题)

        问题A不一定是一个NP问题,但所有的NPC问题都可以在多项式时间内转化为A,则称A为NPH问题。

    二、其他知识

    1. NPC问题一定是NP困难问题

        根据NP完全问题和NP困难问题的定义可以发现,NP完全问题A的定义中,除了要求对于所有别的判定问题A’ ∈NP,都有A’ ∝A,还要求A∈NP,而NP困难问题不一定是NP问题,所以可以看出NP完全问题是NP困难问题的子集,所以NP完全问题一定都是NP困难问题。

    2.NP困难问题中包含的一些问题是既不属于NP也不属于P类问题的,一个典型的例子就是第k个最重子集问题。

    3.证明一个新问题A是NPC问题的方法:

    a.证明A∈NP;

    b.选取一个已知的NPC问题B;

    c.构造一个从B到A的变换f;

    d.证明f为一个多项式变换。

    这里一个关键的问题是如何选取参照物B和构造多项式变换f。在实际的证明中参照物的选择带有一定的经验性,已知的NPC问题越多越有利。第一个被证明的NPC问题是sat问题(可满足性问题),这个开创性的工作是由COOK完成的,自从他证明了sat问题是NPC问题以来,人们已经发现并证明了数千个NPC问题,如0/1背包问题和哈密尔顿回路问题等。

    4.几个典型的NPC问题

    三维匹配问题(3 dimensional matching,3DM);三元精确覆盖问题(exact cover by 3-set,X3C);顶点覆盖问题(vertex cover,VC);

    哈密尔顿回路问题(Hamiltonian circuit,HC);划分问题(PARTS);三元可满足性问题(3SAT);团问题(CLIQUE);0/1背包(判定)问题(0/1KPS)

        暂时先写这么多,本人水平有限,可能有些讲的不清楚的地方,欢迎批评指正。

    展开全文
  • P问题NP问题、NPC问题以及NP-hard问题理解与区分

    这或许是众多OIer最大的误区之一。
    你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题并不是那种“只有搜才行”的问题,NPC问题才是。好,行了,基本上这个误解已经被澄清了。下面的内容都是在讲什么是P问题,什么是NP问题,什么是NPC问题,你如果不是很感兴趣就可以不看了。接下来你可以看到,把NP问题当成是NPC问题是一个多大的错误。
    还是先用几句话简单说明一下时间复杂度。时间复杂度并不是表示一个程序解决问题需要花多少时间,而是当问题规模扩大后,程序需要的时间长度增长得有多快。也就是说,对于高速处理数据的计算机来说,处理某一个特定数据的效率不能衡量一个程序的好坏,而应该看当这个数据的规模变大到数百倍后,程序运行时间是否还是一样,或者也跟着慢了数百倍,或者变慢了数万倍。不管数据有多大,程序处理花的时间始终是那么多的,我们就说这个程序很好,具有O(1)的时间复杂度,也称常数级复杂度;数据规模变得有多大,花的时间也跟着变得有多长,这个程序的时间复杂度就是O(n),比如找n个数中的最大值;而像冒泡排序、插入排序等,数据扩大2倍,时间变慢4倍的,属于O(n^2)的复杂度。还有一些穷举类的算法,所需时间长度成几何阶数上涨,这就是O(a^n)的指数级复杂度,甚至O(n!)的阶乘级复杂度。不会存在O(2*n^2)的复杂度,因为前面的那个“2”是系数,根本不会影响到整个程序的时间增长。同样地,O(n^3+n^2)的复杂度也就是O(n^3)的复杂度。因此,我们会说,一个O(0.01*n^3)的程序的效率比O(100*n^2)的效率低,尽管在n很小的时候,前者优于后者,但后者时间随数据规模增长得慢,最终O(n^3)的复杂度将远远超过O(n^2)。我们也说,O(n^100)的复杂度小于O(1.01^n)的复杂度。
    容易看出,前面的几类复杂度被分为两种级别,其中后者的复杂度无论如何都远远大于前者:一种是O(1),O(log(n)),O(n^a)等,我们把它叫做多项式级的复杂度,因为它的规模n出现在底数的位置;另一种是O(a^n)和O(n!)型复杂度,它是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。
    自然地,人们会想到一个问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?很遗憾,答案是否定的。有些问题甚至根本不可能找到一个正确的算法来,这称之为“不可解问题”(Undecidable Decision Problem)。The Halting Problem就是一个著名的不可解问题,在我的MSN Space上有过专门的介绍和证明。再比如,输出从1到n这n个数的全排列。不管你用什么方法,你的复杂度都是阶乘级,因为你总得用阶乘级的时间打印出结果来。有人说,这样的“问题”不是一个“正规”的问题,正规的问题是让程序解决一个问题,输出一个“YES”或“NO”(这被称为判定性问题),或者一个什么什么的最优值(这被称为最优化问题)。那么,根据这个定义,我也能举出一个不大可能会有多项式级算法的问题来:Hamilton回路。问题是这样的:给你一个图,问你能否找到一条经过每个顶点一次且恰好一次(不遗漏也不重复)最后又走回来的路(满足这个条件的路径叫做Hamilton回路)。这个问题现在还没有找到多项式级的算法。事实上,这个问题就是我们后面要说的NPC问题。
    下面引入P类问题的概念:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。P是英文单词多项式的第一个字母。哪些问题是P类问题呢?通常NOI和NOIP不会出不属于P类问题的题目。我们常见到的一些信息奥赛的题目都是P问题。道理很简单,一个用穷举换来的非多项式级时间的超时程序不会涵盖任何有价值的算法。
    接下来引入NP问题的概念。这个就有点难理解了,或者说容易理解错误。在这里强调(回到我竭力想澄清的误区上),NP问题不是非P类问题。NP问题是指可以在多项式的时间里验证一个解的问题。NP问题的另一个定义是,可以在多项式的时间里猜出一个解的问题。比方说,我RP很好,在程序中需要枚举时,我可以一猜一个准。现在某人拿到了一个求最短路径的问题,问从起点到终点是否有一条小于100个单位长度的路线。它根据数据画好了图,但怎么也算不出来,于是来问我:你看怎么选条路走得最少?我说,我RP很好,肯定能随便给你指条很短的路出来。然后我就胡乱画了几条线,说就这条吧。那人按我指的这条把权值加起来一看,嘿,神了,路径长度98,比100小。于是答案出来了,存在比100小的路径。别人会问他这题怎么做出来的,他就可以说,因为我找到了一个比100小的解。在这个题中,找一个解很困难,但验证一个解很容易。验证一个解只需要O(n)的时间复杂度,也就是说我可以花O(n)的时间把我猜的路径的长度加出来。那么,只要我RP好,猜得准,我一定能在多项式的时间里解决这个问题。我猜到的方案总是最优的,不满足题意的方案也不会来骗我去选它。这就是NP问题。当然有不是NP问题的问题,即你猜到了解但是没用,因为你不能在多项式的时间里去验证它。下面我要举的例子是一个经典的例子,它指出了一个目前还没有办法在多项式的时间里验证一个解的问题。很显然,前面所说的Hamilton回路是NP问题,因为验证一条路是否恰好经过了每一个顶点非常容易。但我要把问题换成这样:试问一个图中是否不存在Hamilton回路。这样问题就没法在多项式的时间里进行验证了,因为除非你试过所有的路,否则你不敢断定它“没有Hamilton回路”。
    之所以要定义NP问题,是因为通常只有NP问题才可能找到多项式的算法。我们不会指望一个连多项式地验证一个解都不行的问题存在一个解决它的多项式级的算法。相信读者很快明白,信息学中的号称最困难的问题——“NP问题”,实际上是在探讨NP问题与P类问题的关系。
    很显然,所有的P类问题都是NP问题。也就是说,能多项式地解决一个问题,必然能多项式地验证一个问题的解——既然正解都出来了,验证任意给定的解也只需要比较一下就可以了。关键是,人们想知道,是否所有的NP问题都是P类问题。我们可以再用集合的观点来说明。如果把所有P类问题归为一个集合P中,把所有NP问题划进另一个集合NP中,那么,显然有P属于NP。现在,所有对NP问题的研究都集中在一个问题上,即究竟是否有P=NP?通常所谓的“NP问题”,其实就一句话:证明或推翻P=NP。
    NP问题一直都是信息学的巅峰。巅峰,意即很引人注目但难以解决。在信息学研究中,这是一个耗费了很多时间和精力也没有解决的终极问题,好比物理学中的大统一和数学中的歌德巴赫猜想等。
    目前为止这个问题还“啃不动”。但是,一个总的趋势、一个大方向是有的。人们普遍认为,P=NP不成立,也就是说,多数人相信,存在至少一个不可能有多项式级复杂度的算法的NP问题。人们如此坚信P≠NP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-完全问题,也即所谓的NPC问题。C是英文单词“完全”的第一个字母。正是NPC问题的存在,使人们相信P≠NP。下文将花大量篇幅介绍NPC问题,你从中可以体会到NPC问题使P=NP变得多么不可思议。
    为了说明NPC问题,我们先引入一个概念——约化(Reducibility,有的资料上叫“归约”)。
    简单地说,一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A,或者说,问题A可以“变成”问题B。《算法导论》上举了这么一个例子。比如说,现在有两个问题:求解一个一元一次方程和求解一个一元二次方程。那么我们说,前者可以约化为后者,意即知道如何解一个一元二次方程那么一定能解出一元一次方程。我们可以写出两个程序分别对应两个问题,那么我们能找到一个“规则”,按照这个规则把解一元一次方程程序的输入数据变一下,用在解一元二次方程的程序上,两个程序总能得到一样的结果。这个规则即是:两个方程的对应项系数不变,一元二次方程的二次项系数为0。按照这个规则把前一个问题转换成后一个问题,两个问题就等价了。同样地,我们可以说,Hamilton回路可以约化为TSP问题(Travelling Salesman Problem,旅行商问题):在Hamilton回路问题中,两点相连即这两点距离为0,两点不直接相连则令其距离为1,于是问题转化为在TSP问题中,是否存在一条长为0的路径。Hamilton回路存在当且仅当TSP问题中存在长为0的回路。
    “问题A可约化为问题B”有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说,问题A不比问题B难。这很容易理解。既然问题A能用问题B来解决,倘若B的时间复杂度比A的时间复杂度还低了,那A的算法就可以改进为B的算法,两者的时间复杂度还是相同。正如解一元二次方程比解一元一次方程难,因为解决前者的方法可以用来解决后者。
    很显然,约化具有一项重要的性质:约化具有传递性。如果问题A可约化为问题B,问题B可约化为问题C,则问题A一定可约化为问题C。这个道理非常简单,就不必阐述了。
    现在再来说一下约化的标准概念就不难理解了:如果能找到这样一个变化法则,对任意一个程序A的输入,都能按这个法则变换成程序B的输入,使两程序的输出相同,那么我们说,问题A可约化为问题B。
    当然,我们所说的“可约化”是指的可“多项式地”约化(Polynomial-time Reducible),即变换输入的方法是能在多项式的时间里完成的。约化的过程只有用多项式的时间完成才有意义。
    好了,从约化的定义中我们看到,一个问题约化为另一个问题,时间复杂度增加了,问题的应用范围也增大了。通过对某些问题的不断约化,我们能够不断寻找复杂度更高,但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法。再回想前面讲的P和NP问题,联想起约化的传递性,自然地,我们会想问,如果不断地约化上去,不断找到能“通吃”若干小NP问题的一个稍复杂的大NP问题,那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的NP问题的这样一个超级NP问题?答案居然是肯定的。也就是说,存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。这种问题的存在难以置信,并且更加不可思议的是,这种问题不只一个,它有很多个,它是一类问题。这一类问题就是传说中的NPC问题,也就是NP-完全问题。NPC问题的出现使整个NP问题的研究得到了飞跃式的发展。我们有理由相信,NPC问题是最复杂的问题。再次回到全文开头,我们可以看到,人们想表达一个问题不存在多项式的高效算法时应该说它“属于NPC问题”。此时,我的目的终于达到了,我已经把NP问题和NPC问题区别开了。到此为止,本文已经写了近5000字了,我佩服你还能看到这里来,同时也佩服一下自己能写到这里来。
    NPC问题的定义非常简单。同时满足下面两个条件的问题就是NPC问题。首先,它得是一个NP问题;然后,所有的NP问题都可以约化到它。证明一个问题是NPC问题也很简单。先证明它至少是一个NP问题,再证明其中一个已知的NPC问题能约化到它(由约化的传递性,则NPC问题定义的第二条也得以满足;至于第一个NPC问题是怎么来的,下文将介绍),这样就可以说它是NPC问题了。
    既然所有的NP问题都能约化成NPC问题,那么只要任意一个NPC问题找到了一个多项式的算法,那么所有的NP问题都能用这个算法解决了,NP也就等于P了。因此,给NPC找一个多项式算法太不可思议了。因此,前文才说,“正是NPC问题的存在,使人们相信P≠NP”。我们可以就此直观地理解,NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。

    顺便讲一下NP-Hard问题。NP-Hard问题是这样一种问题,它满足NPC问题定义的第二条但不一定要满足第一条(就是说,NP-Hard问题要比NPC问题的范围广)。NP-Hard问题同样难以找到多项式的算法,但它不列入我们的研究范围,因为它不一定是NP问题。即使NPC问题发现了多项式级的算法,NP-Hard问题有可能仍然无法得到多项式级的算法。事实上,由于NP-Hard放宽了限定条件,它将有可能比所有的NPC问题的时间复杂度更高从而更难以解决。
    不要以为NPC问题是一纸空谈。NPC问题是存在的。确实有这么一个非常具体的问题属于NPC问题。下文即将介绍它。
    下文即将介绍逻辑电路问题。这是第一个NPC问题。其它的NPC问题都是由这个问题约化而来的。因此,逻辑电路问题是NPC类问题的“鼻祖”。
    逻辑电路问题是指的这样一个问题:给定一个逻辑电路,问是否存在一种输入使输出为True。
    什么叫做逻辑电路呢?一个逻辑电路由若干个输入,一个输出,若干“逻辑门”和密密麻麻的线组成。看下面一例,不需要解释你马上就明白了。
    

    ┌───┐
    │ 输入1├─→┐ ┌──┐
    └───┘ └─→┤ │
    │ OR ├→─┐
    ┌───┐ ┌─→┤ │ │ ┌──┐
    │ 输入2├─→┤ └──┘ └─→┤ │
    └───┘ │ ┌─→┤AND ├──→输出
    └────────┘ ┌→┤ │
    ┌───┐ ┌──┐ │ └──┘
    │ 输入3├─→┤ NOT├─→────-┘
    └───┘ └──┘
    这是个较简单的逻辑电路,当输入1、输入2、输入3分别为True、True、False或False、True、False时,输出为True。
    有输出无论如何都不可能为True的逻辑电路吗?有。下面就是一个简单的例子。
    ┌───┐
    │输入1 ├→─┐ ┌──┐
    └───┘ └─→┤ │
    │AND ├─→┐
    ┌─→┤ │ │
    │ └──┘ │ ┌──┐
    │ └→┤ │
    ┌───┐ │ │AND ├─→输出
    │输入2 ├→─┤ ┌──┐ ┌→┤ │
    └───┘ └→┤NOT ├→──┘ └──┘
    └──┘
    上面这个逻辑电路中,无论输入是什么,输出都是False。我们就说,这个逻辑电路不存在使输出为True的一组输入。
    回到上文,给定一个逻辑电路,问是否存在一种输入使输出为True,这即逻辑电路问题。
    逻辑电路问题属于NPC问题。这是有严格证明的。它显然属于NP问题,并且可以直接证明所有的NP问题都可以约化到它(不要以为NP问题有无穷多个将给证明造成不可逾越的困难)。证明过程相当复杂,其大概意思是说任意一个NP问题的输入和输出都可以转换成逻辑电路的输入和输出(想想计算机内部也不过是一些0和1的运算),因此对于一个NP问题来说,问题转化为了求出满足结果为True的一个输入(即一个可行解)。
    有了第一个NPC问题后,一大堆NPC问题就出现了,因为再证明一个新的NPC问题只需要将一个已知的NPC问题约化到它就行了。后来,Hamilton回路成了NPC问题,TSP问题也成了NPC问题。现在被证明是NPC问题的有很多,任何一个找到了多项式算法的话所有的NP问题都可以完美解决了。因此说,正是因为NPC问题的存在,P=NP变得难以置信。P=NP问题还有许多有趣的东西,有待大家自己进一步的挖掘。攀登这个信息学的巅峰是我们这一代的终极目标。现在我们需要做的,至少是不要把概念弄混淆了。


    1。有解但无算法的问题:
    比如圆周率Pi的小数点后面是否有连续的100万个0。因为Pi是一个客观存在的实数,所以Pi的值是确定的,因此这个问题的解也是存在的。要么是yes,要么是no,虽然我们不知道他到底是什么,但他是客观存在的,不随时间改变,不随人的认识而改变。但是没有算法可以计算这个问题的答案。当然,可以用一种苯办法来解决这个问题,就是不停地计算Pi的小数点后面的值,如果发现了有连续的100万个0,则这个问题的答案就是yes,但是如果没有发现,我们必须一直计算下去,而且永远无法停止~~,所以这种苯办法根本称不上是算法,因为他不满足算法在有限步内终止的条件。所以这个问题是没有算法的(至少目前认为如此,也许以后可以从数论中找到某种方法来求出小数点后面是否有连续的k个0,或从概率的角度计算Pi的小数点后面的值的分布等等等等)。

    2.无解也无算法的问题:
    例如,给定任意一个命题,是否存在一种算法判断这个命题是真是假?这就是著名的图灵停机问题。如果存在这个算法,那么我们只要找到这个算法就可以一劳永逸了,以后无论拿到什么新的命题,都可以用这个算法来验证一下,立刻就知道该命题是真是假,这样我们就掌握了整个宇宙的终极真理:)。但是图灵已经证明了这样的算法是不存在的,这个问题也是无解的。(证明中主要利用了康托尔对角线删除法,就是用来证明实数和自然数不等势的那种对角线删除法)

    3。可计算与不可计算:
    根据图灵-丘奇论题,:
    1。可计算的问题就是能被图灵机计算的问题;(图灵的定义)
    2。可计算的问题就是使用lamda演算系统可以计算的问题;(丘奇的定义)

    图灵丘奇论题与其说是定理,不如说是算法的定义。因为算法本身就是一个不精确的概念,到底什么是算法,以前一直没有确切的定义。而图灵-丘奇论题则从数学上给出了算法的形式定义。

    图灵说:所有的图灵机能计算的问题都是有算法的(也就是可计算的),所有有算法的问题都可以用图灵机计算。这个论题本身是无法证明的,它就像物理中的光速不变定律一样,是一条自然定律,不能加以逻辑上的证明,只能用实验来检验。而目前来看,图灵命题也和光速不变一样,经得住历史和时间的检验,现在即使发展到了量子计算机,还是没有摆脱图灵机的约束,量子计算机上可计算的问题也是普通的图灵机上可计算的问题,只不过计算效率不同而已。

    不可计算的问题的两个例子前面已经说过了,一个是Pi的例子,另一个是图灵停机问题。

    4。可证明性与不可证明性
    在一个公里系统中,有若干条公里,有一些推导规则,在系统中进行定理的证明,就是从公理出发,利用这些规则推导出新的定理。如果最终能得到我们需要证明的命题,则该命题为真;如果最终得到了和我们需要证明的命题相违背的命题,则我们要证明的命题为假。

    如果把系统中所有的定理看作图中的节点,假如从定理i1,i2,..ik根据系统的规则可以推导出定理j,则从i1,i2,…ik分别连接一条到j的有向边。这样整个公理系统构造成了一个有向图。定理的证明过程事实上是在公理系统中从公理表示的节点出发,构造一颗到达目标命题节点的“证明树”。因而定理的证明就和图论中的路经搜索类似(BTW,这就是定理自动化证明的基本原理)。

    超级天才歌德尔在25岁的时候提出了著名的歌德尔不完备性定理。该定理指出:在任何一个公理化系统中,要么存在着矛盾,这个系统是不完备的。
    所谓存在着矛盾,就是可以证明命题A成立,也可以证明命题A的否命题成立,这就自相矛盾了。
    所谓不完备,是指系统中存在着一些命题,无法证明它成立,也无法证明它不成立。这就好像在一个图中存在着某些孤立点,从基本的公理节点出发永远无法访问到这些孤立点。

    歌德尔在“不完备性定理”的证明过程中构造出了一个无法证明是真是伪的定理。具体说起来比较麻烦,我根据自己的理解将其简化为下述的简单形式:

    命题A = “命题A不成立”

    现在问命题A是否成立。如果命题A成立,则根据命题A的内容,命题A应该不成立;如果命题A不成立,则根据命题A的内容,命题A又应该成立。

    这个例子很不严谨,因为它事实上混淆了语法和语义层次。但我觉得这个例子可以作为歌德尔的例子的一个简化版本。歌德的那个例子要比这个严谨和复杂得多,但实质上是差不多的,也是利用了逻辑中的悖论。

    罗素等人所提倡的解决这种悖论的方法就是给谓词逻辑分层次,从而产生了一阶谓词逻辑、二阶谓词逻辑等。像上面的例子,罗素认为命题A的内容描述了命题A本身的性质,这就超出了命题A所能表达的范围,他认为这样的A不是合法的命题。

    【转自:http://www.matrix67.com/blog/archives/105 http://blog.csdn.net/dongwq/article/details/4305435

    展开全文
  • P问题NP问题、NPC问题NP-hard问题详解

    万次阅读 多人点赞 2018-09-19 18:44:24
    要理解P问题NP问题、NPC问题NP-hard问题,需要先弄懂几个概念: 什么是多项式时间? 什么是确定性算法?什么是非确定性算法? 什么是规约/约化? 多项式时间(Polynomial time) 什么是时间复杂度? 时间...
  • 什么是P问题NP问题和NPC问题

    千次阅读 2017-04-17 11:48:56
    你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题
  • 例子:停机问题 不可能有复杂度O(多项式)问题 例子:输出从1到n这n个数的全排列(因为把结果打印出来也是O(n!)的复杂度) &quot;正规&quot;问题 正规的问题是让程序解决一个问题 输出一个“YES”或...
  • NP问题

    千次阅读 2012-01-04 17:17:56
    NP问题http://baike.baidu.com/view/158424.htmP(Polynomial,多项式)问题.P问题是可以在多项式时间内被确定机(通常意义的计算机)解决的问题.NP(Non-Deterministic Polynomial, 非确定多项式)问题,是指可以在多项式...
  • P问题NP问题、NPC问题NP hard问题

    万次阅读 多人点赞 2019-01-17 17:33:13
    NP问题例子: 哈密顿圈 问题:找出一个简单圈,该圈包含 V s u b V_{sub} V s u b ​ 的每一个顶点;通过图G的每个结点一次,且仅一次的通路(回路),就是哈密顿通路(回路),也称 哈密顿圈 。存在哈密顿圈...
  • P问题NP问题、NPC问题的概念及实例证明

    万次阅读 多人点赞 2016-05-21 16:29:25
    四、NP-Complete间的规约例子 首先解释一下什么是NP问题,什么是NP hard问题,什么是NP完全问题。 * P Problem:这个应该最易理解,就是一个问题可以在Polynominal的时间的得到解决,当然,是对于任意input size。...
  • P问题NP问题NP问题

    千次阅读 2019-03-06 11:06:43
    有一则程序员界的笑话,就是有一哥们去google面试的时候被问到一个问题是:在什么情况下P=NP,然后他的回答是”当N=1的时候”。这是我第一次听说P=NP问题,大概是在临近毕业为找工作而准备的时候。 这几天科技类...
  • 算法中的P问题NP问题NP完全问题NP问题

    万次阅读 多人点赞 2017-11-11 09:42:32
    在讨论算法的时候,常常会说到这个问题的求解是个P类问题,或者是NP问题等等,于是我特地搜了这方面的资料,自己总结了下,估计研究算法的大家应该都知道,要是我总结的哪里不对,欢迎一起探讨~ 在讲P类...
  •  你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题...
  • NP-hard NP问题

    千次阅读 2013-10-30 11:13:57
    NP 是 Non-deterministic Polynomial 的缩写,NP 问题通俗来说是其解的正确性能够被很容易检查的问题,这里"很容易检查"指的是存在一个多项式检查算法。 例如,著名的推销员旅行问题(Travel Saleman Problem or ...
  • 引到NP问题里就是,对于同一类的所有的NP问题,若他们都可以在多项式时间内约化成最难的一个NP问题,(我们直观的认为,被约化成的问题应具有比前一个问题更复杂的时间复杂度)当我们针对这个时间复杂度最高的...
  • 概念P问题:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。...之所以要定义NP问题,是因为通常只有NP问题才可能找到多项式的算法。 所有的P类问题都是NP问题。也就
  • 在讲P类问题之前先介绍两个个概念:多项式,时间复杂度。(知道这两概念的可以自动跳过这部分) 1. 多项式:axn−bxn−1+cax^n-bx^{n-1}+caxn−bxn−1+c 恩…就是长这个样子的,叫 xxx 最高次为 nnn 的多项式… 咳咳,...
  • P问题:该问题存在一个可以在多项式时间内解决该问题的算法。(P:polynominal,多项式) 为什么我们要研究这个?因为计算机处理的输入常常不是那么几十个几千个那么一点点,想象一下,当计算机处理的数据达到100万个...
  • 从哈密尔顿路径谈NP问题

    万次阅读 2015-11-06 21:01:35
    1859年,爱尔兰数学家哈密尔顿(Hamilton)提出下列周游世界的游戏:在正十二面体的二十个顶点上依次标记伦敦、巴黎、莫斯科等世界著名大城市,正十二面体的棱表示连接这些城市的...哈密尔顿问题是一个著名的NP问题
  • 首先解释一下什么是NP问题,什么是NP hard问题,什么是NP完全问题。 看下面的图,他们之间的关系表示的比较清楚。 P Problem:这个应该最易理解,就是一个问题可以在Polynominal的时间的得到解决,当然,是对于...
  • 本文档对NP完全问题详细解释,举了很多的例子 NP完全问题(NP-C问题),是世界七大数学难题之一。 NP的英文全称是Non-deterministic Polynomial的问题,即多项式复杂程度的非确定性问题。简单的写法是 NP=P?,问题就...
  • P类问题NP问题与NPC类问题

    千次阅读 多人点赞 2018-10-08 18:51:09
    你会经常看到网上出现“这怎么做,这不是NP问题吗”、“这个只有搜了,这已经被证明是NP问题了”之类的话。你要知道,大多数人此时所说的NP问题其实都是指的NPC问题。他们没有搞清楚NP问题和NPC问题的概念。NP问题...
  • 本文搬运自什么是P问题NP问题和NPC问题,作者是Matrix67,本文在原文之上略做修改,加黑了重点的地方, 对部分稍难理解的地方做了解释,原文已经讲的非常清楚了,向原作者致敬(作者12年前写这篇文章的时候应该...
  • P问题NP问题,NPC问题概念

    千次阅读 2016-09-29 12:25:48
    P,NP,NPC,NP-hard概念

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 74,270
精华内容 29,708
关键字:

np问题例子