1. 旅行商问题
1.1. the Travelling Salesman Problem
-
1.1.1. 旅行商问题最早的记录出现于19世纪
-
1.1.2. 这个问题被威廉·汉密尔顿(William Hamilton)和托马斯·柯克曼(Thomas Kirkman)重新表述为一个数学问题
1.2. 要求确定在一系列城市间旅行的最短路线
-
1.2.1. 已知城市的名字和它们彼此之间的距离
-
1.2.2. 要求所有的城市都必须到访一次,而且只能是一次
-
1.2.3. 走访城市的顺序可以是任意的,只要旅程的起点和终点都是推销员的家乡城市就行
-
1.2.4. 挑战在于如何找到总行程最短的路线
1.3. 寻找最短路线的最简单方法是穷举搜索(exhaustive search)
-
1.3.1. 穷举搜索,或称蛮力搜索,会计算每个可能的旅行路线的长度,并选择最短的那个
-
1.3.2. 蛮力搜索很慢
1.4. 穷举搜索算法
-
1.4.1. 将一组城市名字构成的集合作为输入
-
1.4.2. 如果集合中只含有一个城市,那么输出一个只包含该城市的路线,否则:创建一个空列表
-
1.4.3. 对集合中的每个城市重复以下操作
-
1.4.3.1. 创建该集合的副本,忽略掉已选择的城市
-
1.4.3.2. 在返回的所有路线的开端插入选定的城市
-
1.4.3.3. 将这些路线添加到列表中
-
-
1.4.4. 输出所有找到的路线
-
1.4.5. 当路线列表生成后,路线的长度可以通过计算城市到城市间距离的总和来得到
1.5. 如果有100个城市呢?100个完全相互连接的城市将得到99!种路线,大约是9×10^155(9后面跟着155个0)种
-
1.5.1. 现代的台式计算机根本应付不了这样的计算
-
1.5.2. 对于旅行商问题而言,即使是处理看似中等大小的路线图,穷举搜索的速度也出奇地慢
1.6. 最快的算法并不比穷举搜索快出多少
-
1.6.1. 要显著加快搜索速度,唯一的办法就是接受妥协
-
1.6.1.1. 必须接受这种算法找不到最短路线的可能性
-
1.6.1.2. 最好的快速近似算法只能保证找到的路线长度在最短路线长度的140%以内
-
-
1.6.2. 妥协和近似并不总是可以接受的,有的时候必须要找到最短的可能路线
1.7. 在计算机时代之初的1954年,最大的有已知解的旅行商问题仅包含49个城市
1.8. 50年后,最大的已解出路线包括24978个瑞典城市
1.9. 目前最前沿的挑战是一个包含1904711个城市的世界地图
-
1.9.1. 这张地图上目前发现的最短路线是7515772212千米
-
1.9.2. 这个路线是凯尔德·赫尔斯冈(Keld Helsgaun)在2013年发现的,但没人知道这是不是最短的路线
2. 测量复杂度
2.1. 旅行商问题的困难在于,算法需要解决计算的复杂度
2.2. 计算复杂度是指执行一个算法所需的基本操作(内存访问、加法或乘法)的数量
-
2.2.1. 一个算法需要的操作越多,计算所需的时间就越长
-
2.2.2. 最能说明问题的方面是,随着输入元素数量的增加,操作的数量将以何种方式增加
-
2.2.3. 简单直接的算法具有恒定的(constant)复杂度
2.3. 搜索书的复杂度与书架上书籍的数量成正比
- 2.3.1. 计算复杂度与书的数量成线性(linear)关系
2.4. 插入排序的计算复杂度与图书数量的平方成正比
- 2.4.1. 书的数量与操作数量之间是二次(quadratic)函数关系
2.5. 快速排序的复杂度等于书的数量乘以书的数量的对数
-
2.5.1. 一个变量的对数的增长速度比其本身的增长速度慢,所以快速排序的复杂度比插入排序的复杂度低
-
2.5.2. 快速排序的平均计算复杂度是准线性的(quasilinear)
2.6. 添加、搜索和排序图书的算法具有所谓的多项式(polynomial)计算复杂度
-
2.6.1. 多项式时间算法的计算复杂度与输入数量的某个恒定次幂成正比
-
2.6.2. 对于线性复杂度,幂是1,而对于二次函数关系的复杂度,幂是2
-
2.6.3. 多项式时间算法对于大量输入可能会很慢,但在现代计算机上,它们基本上是易于处理的
2.7. 更具挑战性的是那些具有超多项式(superpolynomial)计算复杂度的算法
-
2.7.1. 这些方法的复杂度比多项式时间算法高
-
2.7.2. 执行超多项式时间算法所需的操作的数量会随着输入数量的增加激增
-
2.7.3. 求解旅行商问题的穷举搜索算法具有超多项式的时间复杂度
2.8. 使用额外的数据存储可以减少操作的数量
- 2.8.1. 一本书的索引增加了页数,但大大减少了找到给定关键字所需的时间
2.9. 对于每一个问题,都必然有一个最快的算法
2.10.
3. 复杂度分级
3.1. 2000年,马萨诸塞州剑桥市克雷数学研究所(Clay Mathematics Institute)宣布,将为能解决7个千禧年难题的人颁发100万美元的奖金
-
3.1.1. 这7个问题被选为所有数学领域中最重要的问题
-
3.1.2. “P vs NP问题”就是这7个问题之一
3.2. 研究者根据一个计算问题已知的最快算法的复杂度来对其进行分级
-
3.2.1.
-
3.2.2.
3.3. 可以用多项式时间算法解决的问题称为P问题[对应于多项式时间(polynomial time,P时间)],P问题被认为是可以快速解决的
- 3.3.1. 排序就是一个P问题
3.4. 可以用多项式时间算法验证其解的问题称为NP问题[对应于非确定性多项式时间(non-deterministic polynomial time,NP时间)]
-
3.4.1. 目前没有解决NP问题需要的时长的定义
-
3.4.2. 有些NP问题可以在P时间内解出来,其他的则不能
3.5. 因为解决问题也是验证给定解决方案的一种方式,所以根据定义,P问题也是NP问题
- 3.5.1. 所有P问题的集合是NP问题集合的子集
3.6. 属于NP但不属于P的问题被称为NP\P问题(NP减去P)
-
3.6.1. 这些问题解决起来很慢,不过如果有答案(正确与否未知),那么答案验证起来会很快
-
3.6.2. 数独游戏就是一个NP\P问题
- 3.6.2.1. 数独解决起来很慢,但检查起来很快
3.7. 其他问题都是大于NP问题(>NP)
-
3.7.1. 这些问题不能在多项式时间内解决或验证
-
3.7.2. 它们的求解和检查程序需要超多项式时间
-
3.7.3. 旅行商问题就是这样一个问题——解决它需要阶乘时间
-
3.7.3.1. 检查答案是否为最短路线的唯一方法是再次运行求解程序
-
3.7.3.2. 验证问题的解也需要阶乘时间
-
-
3.7.4. 解决和验证起来都很缓慢的问题是>NP问题
3.8. 斯蒂芬·库克(Stephen Cook)
-
3.8.1. 1971年,加拿大多伦多大学的斯蒂芬·库克(Stephen Cook)发表了一篇论文,对复杂度研究产生了重大影响
- 3.8.1.1. 论文引出了数学中最大的谜题之一——所谓的“P vs NP问题”,即“能否找到一个多项式时间算法来解决所有NP问题?”
-
3.8.2. 能解决所有NP问题的多项式时间算法将彻底改变许多应用程序
-
3.8.2.1. 以前难以解决的问题可以很快得到解决
-
3.8.2.2. 从交通运输到制造业,我们可以制定出更高效的时间表
-
3.8.2.3. 可以预测分子间的相互作用,加速药物设计和太阳能电池板的开发
-
-
3.8.3. 库克证明了如果存在一个解决NP完全问题的多项式时间算法,那么这个算法也可以在多项式时间内解决所有NP问题
-
3.8.4. 库克的工作还证明了某些>NP问题可以在多项式时间内转化(transform)为NP完全问题
-
3.8.4.1. 这种转化是通过处理>NP问题的输入,使NP完全算法能够完成计算来实现的
-
3.8.4.2. 找到一种能求解NP完全问题的快速算法,将为这些>NP问题提供更快的求解方法
-
-
3.8.5. 库克于1982年获得了图灵奖
3.9. 最复杂的NP问题被称为NP完全问题(NP-Complete problem)
-
3.9.1. 一个求解NP完全问题的快速算法能够将所有NP\P问题转化为单纯的P问题
- 3.9.1.1. 其结果是,NP集合会突然等于P集合
-
3.9.2. NP完全问题还包括背包装箱问题、战舰博弈问题和图着色问题
3.10. NP完全问题和可以经P时间转化为NP完全问题的>NP问题统称为NP困难问题(NP-Hard problem)
-
3.10.1. 用于求解NP完全问题的多项式时间算法,同样可以快速求解所有NP困难问题
-
3.10.2. 旅行商问题是NP困难问题
3.11. 能够解决其中任何一个问题的多项式时间算法都有可能荣获菲尔兹奖,这相当于数学领域的诺贝尔奖
3.12. 旅行商问题的一个简化版本——“旅行商决策问题”(Travelling Salesman Decision Problem),是个已知的NP完全问题
-
3.12.1. 这个问题问的是:“对于给定的路线图,能否找到比指定距离更短的路线?”
-
3.12.2. 验证旅行商问题的一个解需要再次求解该问题(>NP),然而验证旅行商决策问题的某个给定解却可以很快
- 3.12.2.1. 只需简单地测量给定解的路线长度,并将结果与指定的距离进行比较
-
3.12.3. 求解决策问题很慢,但验证起来很快(NP\P)