计算复杂性:P、NP、NP-hard、NP-complete 一篇通关
不管是刷算法题、做项目优化还是准备面试「计算复杂性」相关的概念P、NP、NP-hard、NP-complete绝对是绕不开的坎。很多人第一次接触时都会被这些名词搞懵甚至越看越乱——“NP问题到底是不是能解决”“NP-hard和NP-complete有啥区别”“PNP到底是个啥梗”这篇博客抛开晦涩的学术公式用最通俗的语言实例把这些概念彻底讲透从基础到进阶让你看完就能区分、能理解、能复述再也不怕被问到相关问题一、什么是计算复杂性在讲具体概念之前先搞明白一个核心问题什么是计算复杂性简单说计算复杂性就是“解决一个问题需要付出多大的计算代价”——代价主要指时间比如需要运行多少步和空间比如需要占用多少内存。通常来讲关注的是时间复杂性。举个例子给1000个数字排序用冒泡排序需要O(n²)步用快速排序平均需要O(nlogn)步。这两种算法的“时间复杂性”不同解决问题的效率也天差地别。而今天要讲的P、NP等概念本质上就是「对问题的时间复杂性进行分类」——不同类型的问题其解决难度、可解决性都不同。核心前提讨论的“问题”都是判定问题输出只有“是”或“否”这是为了统一标准方便分类。比如“这个数是质数吗”“这个图有没有 Hamiltonian 回路”都是判定问题。二、逐个拆解核心概念从易到难2.1 P类问题Polynomial Time多项式时间可解问题最容易理解的一类问题也是平时接触最多的问题。P类问题定义存在一个多项式时间算法能够在O(n^k)的时间内n是问题输入规模k是一个常数比如1、2、3判断问题的答案是“是”还是“否”。通俗说这类问题是“能快速解决”的。不管输入规模多大比如n1000、n10000只要算法的时间复杂度是多项式级比如O(n)、O(n²)、O(n³)就属于P类。实例都是我们熟悉的问题排序问题判定版“给定n个数字能否在O(nlogn)时间内排好序”——能快速排序、归并排序都是多项式时间所以属于P类。最短路径问题判定版“给定图G起点s、终点t能否找到一条长度≤L的路径”——Dijkstra算法是O(mnlogn)m是边数多项式时间属于P类。质数判定现代算法“给定一个数n是否是质数”——现在有多项式时间算法比如AKS算法所以属于P类以前认为是NP类后来被证明属于P。关键P类问题的核心是可快速求解算法的时间复杂度是多项式级。2.2 NP类问题Non-deterministic Polynomial Time非确定性多项式时间问题NP类问题定义不能保证快速求解但能快速“验证”一个答案是否正确的判定问题。也就是说对于一个问题如果给出一个“候选答案”我们能在多项式时间内验证这个答案是不是正确的那么这个问题就属于NP类。这里的“非确定性”Non-deterministic可以通俗理解为“存在一个猜测过程能猜到一个正确答案且验证这个答案的时间是多项式级的”。通俗说这类问题“不好解决但好验证”。比如你不知道怎么快速找到答案但别人给你一个答案你能很快判断他对不对。实例重点理解Hamiltonian 回路问题判定版“给定一个图G是否存在一条经过所有顶点一次且仅一次最后回到起点的回路”——目前没有找到多项式时间算法来“求解”即找到这条回路但如果别人给你一条回路你只需要遍历一遍看是否符合条件所有顶点都经过、不重复、回到起点这个验证过程是O(n)n是顶点数多项式时间所以属于NP类。子集和问题判定版“给定一组整数和一个目标值S是否存在一个子集其和等于S”——求解很难比如100个整数要枚举所有子集是2^100种可能指数级时间但验证很简单别人给你一个子集你加一下和看是不是等于SO(n)时间属于NP类。注意所有P类问题都属于NP类因为如果一个问题能快速求解P那么它的答案自然能快速验证直接求解出答案再验证一遍即可验证时间和求解时间同级也是多项式级。所以 P ⊆ NP。核心误区NP ≠ 不可解NP只是“求解难验证易”至于能不能快速求解目前还不知道。2.3 NP-hard类问题NP-hardNP难问题NP-hard类问题定义如果所有NP类问题都能在多项式时间内归约到某个问题A那么问题A就是NP-hard问题。这里的“归约”Reduction是核心通俗理解为如果能解决问题A那么就能解决所有NP类问题。也就是说问题A的难度 ≥ 所有NP类问题的难度。关键特点NP-hard问题不一定属于NP类——也就是说它可能连“快速验证答案”都做不到有些NP-hard问题即使给你一个候选答案你也无法在多项式时间内验证它是否正确。NP-hard问题是“最难”的一类问题目前没有任何多项式时间算法能解决它如果有那么所有NP类问题都能被解决即PNP。实例停机问题判定版“给定一个程序和输入这个程序会停机吗”——这是NP-hard问题但它不属于NP类因为即使给你一个“会停机”的答案你也无法在多项式时间内验证你需要运行程序而程序可能无限循环永远无法验证。旅行商问题TSP优化版“给定n个城市和两两之间的距离找到一条经过所有城市一次且仅一次最后回到起点的最短路径”——这是NP-hard问题注意TSP的判定版属于NP类优化版属于NP-hard。2.4 NP-complete类问题NP完全问题NP-complete类简称NPC问题定义一个问题A必须同时满足两个条件才是NP-complete问题问题A属于NP类能快速验证答案问题A是NP-hard问题所有NP类问题都能归约到它。通俗说NPC问题是“NP类中最难的问题”——只要能找到一个NPC问题的多项式时间算法那么所有NP类问题都能找到多项式时间算法即PNP反之如果证明某个NPC问题没有多项式时间算法那么所有NPC问题都没有多项式时间算法即P≠NP。实例经典NPC问题记几个就够了Hamiltonian 回路问题判定版前面提到过属于NP类能验证且所有NP类问题都能归约到它所以是NPC问题。子集和问题判定版属于NP类且是NP-hard所以是NPC问题。布尔可满足性问题SAT“给定一个布尔表达式比如 (a∨¬b)∧(¬a∨c)是否存在一组变量赋值使得表达式为真”——这是第一个被证明的NPC问题库克定理是所有NPC问题的“鼻祖”。顶点覆盖问题判定版“给定一个图G和一个整数k是否存在一个顶点子集大小≤k使得图中所有边都至少有一个端点在这个子集里”——NPC问题。三、核心关系梳理一张图看懂所有类别很多人看完单个概念还是乱这里用通俗的语言集合关系帮你理清P ⊆ NP所有能快速求解的问题都能快速验证因为求解出答案后验证就是一步的事。NP-complete ⊆ NP ∩ NP-hardNPC问题是NP和NP-hard的交集——既属于NP能验证又属于NP-hard最难。NP-hard 包含 NP-completeNP-hard是更大的集合里面既有NPC问题属于NP也有不属于NP的问题比如停机问题。补充目前学术界的普遍猜想是 P ≠ NP也就是说存在一些NP类问题比如NPC问题永远没有多项式时间算法只能用近似算法、启发式算法比如遗传算法、模拟退火来逼近最优解。四、常见误区纠正误区1NP问题是“不能快速解决的问题”——错NP只是“不能保证快速解决”但可能存在多项式时间算法只是目前没找到而且NP问题能快速验证。误区2NP-hard问题都属于NP类——错NP-hard不一定属于NP比如停机问题是NP-hard但不属于NP无法快速验证。误区3NPC问题是“不可解的问题”——错NPC问题是“目前没有多项式时间算法解决”但可以用指数级算法比如枚举解决只是当输入规模变大时比如n30指数级算法就会变得不可行2^30是10亿级运行时间会非常长。误区4PNP是“能不能找到快速算法”——本质是“能快速验证的问题是否都能快速求解”。如果PNP那么很多现在认为“难”的问题比如NPC问题都会有快速算法对密码学、人工智能、物流优化等领域影响巨大。五、实际应用为什么我们要懂这些对于程序员来说了解计算复杂性主要有3个作用评估问题难度拿到一个问题能快速判断它属于哪一类——如果是P类就直接找多项式时间算法如果是NPC问题就不要浪费时间找“最优快速算法”而是用近似算法、启发式算法来解决比如TSP问题实际中用贪心算法逼近最优解。面试加分大厂面试中经常会问“这个问题是NP问题吗”“为什么TSP是NPC问题”懂这些概念能体现你的算法功底和逻辑思维。理解技术边界比如密码学中的RSA加密本质就是利用“大质数分解是NPC问题”目前没有多项式时间算法如果未来PNP被证明RSA加密就会被破解整个互联网安全体系都会受到影响。六、总结一句话记住所有核心P能快速解NP能快速验NPC是NP里最难的NP-hard比NPC更难可能不能验目前猜想P≠NP。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2425649.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!