1.先是讲了np完全问题的一般概念。简单的说就是一般的计算问题分为p,np和npc问题,还有一类更难的nph问题不过目前不在讨论范围内。npc问题的特点是,所有的np问题都能reduce到npc问题。就比如说我们要解决让刁大大能够从1数到10的问题。虽然这个问题很难,但是我们可以换个思路解决,我们把它推演(reduce)一下,变成教他从1数到20的问题。那么如果我们解决了这个新问题,原来的老问题也就同时解决了。从1数到10和从1数到20,就相当于np问题和npc问题之间的关系。
那么这样的结果就是,如果任意一个npc问题能够被以多项式级复杂度解决的话,那就意味着所有的np问题都能以多项式级复杂度解决了。那么也意味着p就等于np了。当然,目前来说p=np?还是悬而未决的问题。
对于实际应用来说,应该时刻留意自己遇到的算法问题是不是npc问题。判断的方法一般是,看你自己的问题能不能从其他已知是npc的问题reduce得到。如果是的话,就只能以指数复杂度去求解了。当然,用近似算法也是很不错的——类似knapsack problem的greedy解法。
说起knapsack problem,原来它居然是一个npc问题。当时做的时候都没注意。回想他的动态规划解法,会发现其实它的复杂度是指数级别的。因为你比如说背包容量是100单位,那么实际上你是循环了一百次的,而你的输入(按十进制算)就只有3位。如果你背包容量是1000单位,输入只多了一位而已,但是你要循环计算1000次,这显然是指数级复杂度了。这有点类似用递归的方法做乘法,会发现连几万的乘法都会很慢,因为是指数级的复杂度。
2.后面讲到的第一个npc问题是顶点覆盖问题。其实倒不如说是边覆盖问题:给定一个无向连通图,判断最少用几个其中的结点,能够覆盖到所有的边,其中一个结点可以覆盖身边的两条边(也可能是一条如果这点就只连了一条边的话)。这个算法有不错的近似解法,在算法导论上可以看到。但是这里光头哥给的是严格算法。算法是动态规划的思路,构造subproblem的办法是,把subproblem相比problem去掉了任意一条边中的一个顶点或另一个顶点。最后得到的是指数级的复杂度,不过还是比bruteforce好很多。
3.旅行商人问题:给定无向有权连通图,让一个商人从一个源点出发,遍历所有结点回到源点,怎样才能使经过的权值最小?这也是个npc问题,也是有不错的近似解法,在算法讨论上有讲。这里光头哥给的还是动态规划的严格算法,其中subproblem的构造很tricky,讲道理动态规划算法的构造都挺伤脑筋的。最后当然还是指数级的,不过也还是比暴力求解好了。
原文地址:https://www.cnblogs.com/dynasty919/p/8550790.html