P=NP?
旅行商问题(Traveling Salesman Problem)
小灰最近在工作中遇到了一个棘手的问题。公司正在开发一个物流项目,其中一个需求是为快递员自动规划送快递的路线。
有一个快递员,要分别给三家顾客送快递,他自己到达每个顾客家的路程各不相同,每个顾客之间的路程也各不相同。那么想要把快递依次送达这三家,并最终回到起点,哪一条路线所走的总距离是最短的呢?
规划快递路线
按送达顺序选择 B、C、D,快递员从 A 出发并回到 A。然后改变 C-D 的距离,观察你的路线是否仍然最优。
路线: A →
为了寻求最优路线,小灰研究了好久,可惜还是没有找到一个高效率的解决方案。不只是小灰,当前的计算机科学家们也没有找到一个行之有效的优化方案,这是典型的旅行商问题。
有一个商品推销员,要去若干个城市推销商品。该推销员从一个城市出发,需要经过所有城市后,回到出发地。每个城市之间都有道路连通,且距离各不相同,推销员应该如何选择路线,使得总行程最短呢?
这个问题看起来很简单,却很难找到一个真正高效的求解算法。其中最容易想到的,是使用穷举法把所有可能的路线穷举出来,计算出每一条路线的总行程。通过排列组合,从所有路线中找出总行程最短的路线。显然,这个方法的时间复杂度是 ,随着城市数量的增长,花费的运算时间简直不可想象!
知识测验
后来,人们想出了许多相对优化的解决方案,比如动态规划法和分枝定界法等。但是,这些算法的时间复杂度仍然是指数级的,并没有让性能问题得到根本的解决。
像这样的问题有很多,旅行商问题仅仅是其中的一例。对于这类问题统称为 NP 问题。
P=NP?
算法的设计与分析在计算机科学领域有着重要的应用背景。1966~2005 年期间,图灵奖获奖 50 人,其中 10 人以算法设计,7 人以计算理论、自动机和复杂性研究领域的杰出贡献获奖。计算复杂性理论中的 P=NP? 问题是世界七大数学难题之一。
一些常见的算法的时间复杂度,例如二分查找法 、归并排序 、Floyd 最短路径 等,都可以用 表示。这些算法都是多项式时间算法,即能在多项式时间内解决问题。这类问题被称为 P 问题(Polynomial)。
人们常说,能用钱解决的问题都不是问题。在计算机科学家眼中,能用多项式时间解决的问题都不是问题。
然而,世间还存在许多变态的问题,是无法(至少是暂时无法)在多项式时间内解决的,比如一些算法的时间复杂度是 ,甚至 。随着问题规模 的增长,计算量的增长速度是非常恐怖的。这类问题被称为 NP 问题(Non-deterministic Polynomial),意思是“不确定是否能在多项式时间内解决”。
更准确地说,NP 是指一个候选解可以在多项式时间内验证的判定问题集合,并不是 “Non-polynomial” 或“不确定能否多项式时间求解”的缩写。我们目前不知道是否每个 NP 问题都能在多项式时间内求解。
知识测验
有些科学家认为,所有的 NP 问题终究都可以在多项式时间内解决,只是我们暂时还没有找到方法;也有些科学家认为,某些 NP 问题永远无法在多项式时间内解决。这个业界争论用 P=NP? 这个公式来表达。
这还不算完,在所有的 NP 问题当中,还存在着一些大 BOSS,被称为 NPC 问题。
NPC
这里所说的 NPC 问题可不是游戏当中的 NPC。要想理解 NPC 问题,需要先了解归约的概念。
归约(reduction)可以简单理解成问题之间的转化。例如问题是一个一元一次方程的求解问题 ,这个问题可以转化成一个一元二次方程 。
问题 并不比问题 难解决,只要有办法解决 ,就一定能够解决 。对于这种情况,可以说问题 归约于问题 。
同时,这种归约可以逐级传递,比如问题 A 归约于问题 B,问题 B 归约于问题 C,问题 C 归约于问题 D,那么可以说问题 A 归约于问题 D。
知识测验
在 NP 问题之间,也可以存在归约关系。把众多的 NP 问题层层归约,必定会得到一个或多个终极问题,这些归约的终点就是所谓的 NPC 问题(NP-Complete)。旅行商问题被科学家证明属于 NPC 问题。
更准确地说,给定距离上限并询问是否存在合格路线的判定版本属于 NP-Complete;询问最短路线的优化版本属于 NP-hard。
俗话说擒贼先擒王,只要有朝一日,我们能够找到 NPC 问题的多项式时间算法,就能够解决掉所有的 NP 问题!但遗憾的是,至今还没有人能够找到可行的方法,很多人认为这个问题是无解的。
回到最初的快递路线规划问题,既然是工程问题,与其钻牛角尖寻求最优解,不如用小得多的代价寻求次优解。最简单的办法是使用贪心算法,先选择距离起点最近的地点 A,再选择距离 A 最近的地点 B,以此类推,每一步都保证局部最优。这样规划出的路线未必是全局最优,但平均情况下也不会比最优方案差多少。
知识测验
路线判定与工程取舍
一个系统收到 8 个城市的候选巡回路线,以及阈值 42。
- 说明如何验证该路线经过每个城市一次、回到起点且总长度不超过 42,并分析验证步骤的增长速度。
- 分别写出旅行商问题的判定版本和优化版本要回答的问题。
- 对本节四地点示例,从 A 使用最近邻法写出路线并计算总距离。
- 解释为什么最近邻结果不能单独证明路线最优,并提出一种评估路线质量的方法。