什么是NP问题,什么是NP hard问题,什么是NP完全问题

什么是NP问题,什么是NP hard问题,什么是NP完全问题先来看一个小故事:(转自:http://zhm2k.blog.163.com/blog/static/5981506820095233143571/)假如老板要你解决一个问题,你绞尽脑汁还是想不出来,叫天天不应,叫地地不灵,这时你走进老板办公室,可以采取3种策略:1)一副倒霉像,神情猥琐,可怜巴巴的说:老板,我没做出来,我想我是太蠢了……boss:蠢材!滚!(失败……)2)

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

先来看一个小故事:(转自:http://zhm2k.blog.163.com/blog/static/5981506820095233143571/

假如老板要你解决一个问题,你绞尽脑汁还是想不出来,叫天天不应,叫地地不灵,这时你走进老板办公室,可以采取3种策略:

1)

一副倒霉像,神情猥琐,可怜巴巴的说:老板,我没做出来,我想我是太蠢了……
boss:蠢材!滚!
(失败……)

2)

雄赳赳气昂昂跨进老板办公室,大吼一声:小样,你丫给我问题根本就无解,害我白想这么些天,我靠!
boss:我才靠,自己做不出来就说这个问题无解,要是人人都这样混,我这老板还当个屁阿,滚!
(做不出来还如此气概,不仅失败,而且欠扁……)

3)

从容不迫的说:老板,我做不出来,但是,我敢肯定,那些大牛们也照样做不出来。
boss:原来是这样,那也难为你了。

虽然是一个笑话,但也可以为我们的生活研究提供一些思路和指导。当你面对一个问题解决不了时,那么就试图去证明别人也解决不了,这的确是一个偷懒逃避的好借口。我觉得P、NP、NP-complete、NP-hard这些名称的出现,就是因为某些难问题,连大牛们都解决不了,无可奈何之下,只好定义一堆东西,为自己找个理由,免得说自己太笨了。其实这是给出一个面对难解问题的解决思路,如果无法得到最优解,那么先去尝试验证哪些解是不是最优解。

 

下面依次介绍

一、计算复杂性

    计算复杂性一般包括时间复杂度和空间复杂度,时间复杂度并不是某算法实际运行需要的时间,而是渐进时间复杂度,即当问题规模趋向于无穷大时,该算法时间复杂度的数量级。常见的时间复杂度,按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n^2)、立方阶O(n^3)、k次方阶O(n^k)、指数阶O(2^n)。这里用大O表示法来表述,给出的是算法的最坏情况的时间代价。

    复杂度关系:c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n! 
    其中c是一个常量,如果一个算法的复杂度为c 、 log2N 、n 、 n*log2N ,那么这个算法时间效率比较高,叫做多项式级的复杂度。如果是 2^n , 3^n ,n!,那么稍微大一些的n就会令这个算法不能动了,这些是非多项式级的,其复杂度计算机往往不能承受。当我们在解决一个问题时,我们选择的算法通常都需要是多项式级的复杂度,非多项式级的复杂度需要的时间太多,往往会超时,除非是数据规模非常小。

    空间复杂度是指算法在计算机内执行时所需存储空间的度量。这里不再细讲。

    自然地,人们会想到一个问题:会不会所有的问题都可以找到复杂度为多项式级的算法呢?很遗憾,答案是否定的。有些问题甚至根本不可能找到一个正确的算法来,这称之为“不可解问题”(Undecidable Decision Problem)。

二、P问题(Polynomial Solvable)

    定义:那些可以在多项式( polynomial )时间内解决的问题,称为P问题。(或:如果一个问题可以找到一个能在多项式的时间里解决它的算法,那么这个问题就属于P问题。)

    时间复杂度如(n^2, n^4,  n(log(n)))都是多项式时间的,指数级别的如(2^n,n^n)这些就不是多项式时间了。
三、NP问题(Non-determinstic Polynomial Solvable)

    定义:给定一个解,我们可以在多项式时间内检查他正确与否的决策问题,为NP问题。
比如,我要找一个图的哈密顿路径,随便给我一个解,我都可以在多项式时间内检查它是不是哈密顿路径。只要形如定义的问题,就是NP问题。

    之所以要定义NP问题,是因为通常只有NP问题才可能找到多项式的算法。我们不会指望一个连多项式地验证一个解都不行的问题存在一个解决它的多项式级的算法。相信读者很快明白,信息学中的号称最困难的问题——“NP问题”,实际上是在探讨NP问题与P类问题的关系。

    很显然,所有的P类问题都是NP问题。也就是说,能多项式地解决一个问题,必然能多项式地验证一个问题的解——既然正解都出来了,验证任意给定的解也只需要比较一下就可以了。关键是,人们想知道,是否所有的NP问题都是P类问题。我们可以再用集合的观点来说明。如果把所有P类问题归为一个集合P中,把所有 NP问题划进另一个集合NP中,那么,显然有P属于NP。现在,所有对NP问题的研究都集中在一个问题上,即究竟是否有P=NP?通常所谓的“NP问题”,其实就一句话:证明或推翻P=NP。

    目前为止这个问题还“啃不动”。但是,一个总的趋势、一个大方向是有的。人们普遍认为,P=NP不成立,也就是说,多数人相信,存在至少一个不可能有多项式级复杂度的算法的NP问题。人们如此坚信P≠NP是有原因的,就是在研究NP问题的过程中找出了一类非常特殊的NP问题叫做NP-complete问题,也即所谓的NPC问题。

四、归约

    为了说明NPC问题,我们先引入一个概念——约化(Reducibility,有的资料上叫“归约”)。

    简单地说,一个问题A可以约化为问题B的含义即是,可以用问题B的解法解决问题A,或者说,问题A可以“变成”问题B。

    “问题A可约化为问题B”有一个重要的直观意义:B的时间复杂度高于或者等于A的时间复杂度。也就是说,问题A不比问题B难。这很容易理解。既然问题A能用问题B来解决,倘若B的时间复杂度比A的时间复杂度还低了,那A的算法就可以改进为B的算法,两者的时间复杂度还是相同。

    从约化的定义中我们看到,一个问题约化为另一个问题,时间复杂度增加了,问题的应用范围也增大了。通过对某些问题的不断约化,我们能够不断寻找复杂度更高,但应用范围更广的算法来代替复杂度虽然低,但只能用于很小的一类问题的算法。再回想前面讲的P和NP问题,联想起约化的传递性,自然地,我们会想问,如果不断地约化上去,不断找到能“通吃”若干小NP问题的一个稍复杂的大NP问题,那么最后是否有可能找到一个时间复杂度最高,并且能“通吃”所有的 NP问题的这样一个超级NP问题?答案居然是肯定的。也就是说,存在这样一个NP问题,所有的NP问题都可以约化成它。换句话说,只要解决了这个问题,那么所有的NP问题都解决了。这种问题的存在难以置信,并且更加不可思议的是,这种问题不只一个,它有很多个,它是一类问题。这一类问题就是传说中的NPC 问题,也就是NP-完全问题。

五、NP-complete问题

    定义:NP-c问题是这样的一类问题,首先他是属于NP的,而且他是NP问题里面最难解决的问题。难到什么程度?只要其中某个问题可以在P时间内解决,那么所有的NP问题就都可以在P时间内解决了。
既然所有的NP问题都能约化成NPC问题,那么只要任意一个NPC问题找到了一个多项式的算法,那么所有的NP问题都能用这个算法解决了,NP也就等于P 了。因此,给NPC找一个多项式算法太不可思议了。

    “正是NPC问题的存在,使人们相信P≠NP”。我们可以就此直观地理解,NPC问题目前没有多项式的有效算法,只能用指数级甚至阶乘级复杂度的搜索。
    NP-c问题的定义出来了,但是,它忽悠了半天,除了说明这类问题比较难之外,其他啥也没有。我们还是不知道到底什么问题是NP-c问题,如何判定一个问题是不是NP-c问题。
    1970年,cook同志发明了cook定理,找到了第一个NP-c问题,SAT(Satisfiability)问题(逻辑电路问题)。他是这么说的,如果SAT问题可以在P时间解决,那么所有的NP问题都可以在P时间内解决。

    有了第一个NPC问题后,一大堆NPC问题就出现了,因为再证明一个新的NPC问题只需要将一个已知的NPC问题约化到它就行了。后来,Hamilton 回路成了NPC问题,TSP问题也成了NPC问题,其他还有图染色问题、背包问题等。现在被证明是NPC问题的有很多,任何一个找到了多项式算法的话所有的NP问题都可以完美解决了。因此说,正是因为NPC问题的存在,P=NP变得难以置信。

六、NP-hard问题
    定义:NP-hard问题是这样的问题,只要其中某个问题可以在P时间内解决,那么所有的NP问题就都可以在P时间内解决了。NP-c问题就是NP-hard问题。但注意NP-hard问题它不一定是NP问题,比如,下围棋就是NP-hard问题,但不是NP问题,我们要在一个残局上找一个必胜下法,告诉我们下一步下在哪里。显然,我们找不这个解,而且更难的是,就算有人给我了一个解,我们也无法在P时间内判断它是不是正确的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/230936.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Windows程序设计——窗口键盘消息滚动事件[通俗易懂]

    Windows程序设计——窗口键盘消息滚动事件[通俗易懂]设置头文件#include <Windows.h>#include “systems.h”以下是头文件内容#pragma once#include <Windows.h>#define NUMLINES ((int)(sizeof sysmetrics/sizeof sysmetrics[0]))struct { int Index; char sz…

  • 如何学习嵌入式Linux_韦东山

    如何学习嵌入式Linux_韦东山我在100ASK_IMX6ULL售后群里,发现很多初学者只有单片机基础,甚至没有单片机基础。在学习Linux时,对很多概念比较陌生,导致不知道学什么,也不知道学了之后有什么用。所以我趁着五一假期,编写此文。从事嵌入式Linux培训12年来,我们写过很多《关于如何学习linux》的文章,这是最新的,本文将不断更新。第1章单片机和Linux的区别1.1有哪些产品使用单片机或Linux所有的电子产品,所用技术都可以认为要么是单片机,要么是Linux;GUI方面主要是QT/Android,它们都是运行于

  • PostgreSQL row number

    PostgreSQL row number作者:moocbaby(handan)日期:2019-01-19标签:postgreSQL,rownumberPosrgreSQLrownumber查询语句如下:Selectrow_number()over()fromtable_name;或者Selectrow_number()over(orderbyt.adesc)fromfromtab…

  • cabal ghc

    cabal ghc

  • apk逆向激活成功教程入门级[通俗易懂]

    apk逆向激活成功教程入门级[通俗易懂]样本很简单,就只有个发短信的行为,内容加密,可以直接写解密方法解密,但是这里我想通过hook解密方法直接动态看解密内容。动态跑发现并没有运行到解密方法那里,查看代码发现解密前有个if没通过:试着反编译修改代码找到对应的smali代码删除掉重新编译生成apk搞定。新生成的apk成功删除掉了if判断那块代码最后hook解密方法动态看到解密内容附上样本:链接:https://p…

  • 普通大一学生的自我反思[通俗易懂]

    普通大一学生的自我反思[通俗易懂]​ 暑假高考完,得知自己被计科(普通本科)录取,便开始在知乎等地方搜索相关知识,以此来提高自己的认识。​ 先是在b站上跟着比特鹏哥学完了c语言(基础),这里又要有一大段故事了,我家在江苏扬州,大概是9月份突然爆发了疫情,就被关在家里不让出去,(在家里坐牢,核酸检测,基本隔一天就要做一次)就在B站上天天看鹏哥学c语言,一开始有新鲜劲,学起来还是很有动力的,后来学到指针,很是痛苦,就又专门去B站听了其他的指针教程,学着学着慢慢就明白了,当时每天的生活节奏基本就是,起床打开电脑学习c语言,学饿了,吃点饭(由于疫

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号