Day 26:旅行推销员问题(TSP)

之前在贪婪演算法的文章中有提到,现实生活中并不是所有问题都能用演算法快狠准地解决,有些困难的问题只有非常慢的解法。旅行推销员问题(travelling salesman problem)就是这样的一个问题。

旅行推销员问题是:给定一系列城市及任两个城市间的距离,找出造访每个城市一次并回到起始城市的最短路线。

最直接的解法就是把所有可能的路线都列出来,再比较哪一个路线是最短的。我们会发现:

两个城市的路线数:2

三个城市的路线数:3个不同的起点 * 两个城市的路线数 = 6

四个城市的路线数:4个不同的起点 * 三个城市的路线数 = 24

也就是以n个城市来说,会有n!条路线,找出其中的最短路线就需要O(n!),即所谓阶层时间(factorial time)。如果对大O符号的图有印象的话,O(n!)的线正是最陡的那一条,代表执行时间随着输入n变大会急遽增加,光是十个城市,路线数就会增加到3628800。这样的演算法已经不是慢可以形容,往往不是合理范围的资源可以进行的方法。

除了暴力解法外,也可以尝试用上一回提到的动态规划。例如选定任一个城市为起点,从小范围开始,计算并记录起点与任一个城市的最小距离、任两个城市的最小距离...这样作法的执行时间为会是O(n²2^n),虽然比阶层时间快,仍然是指数时间(exponential time),也就是随着n增加执行时间会指数成长。

旅行推销员问题是个NP困难问题,目前还没有快速的演算法可以解决。这点可能有些令人好奇,毕竟这个问题看起来那麽简单,而且还跟我们讨论过的Dijkstra演算法或最小生成树的问题非常相像。

事实上我们也可以像Dijkstra演算法一样,用贪婪演算法来解TSP。例如以任意城市为起点,接着不断选择距离最近的城市,直到去过所有的城市。这样执行时间缩短很多,但也可以想像得出的解不会永远正确。

下一回会写到所谓困难问题的意义,以及如何面对困难问题。


<<:  大共享时代系列_023_可多人协作的试算表软件

>>:  【设计+切版30天实作】|Day25 - Carousel区块 - 把Carousel Caption和Indicators改成心目中理想的模样

关於除错这件事

发达的工具会剥夺人的能力,能力被剥夺後经验会开始狭隘,狭隘的经验则会让思维开始产生死角,有死角的思维...

【DAY 21】为什麽每天可以有这麽多问题?如果有机器人可以帮帮我就好了!— Microsoft Power Virtual Agents 智慧虚拟助理来罗~

哈罗大家好~ 每天的工作日常,从吃早餐了吗?这类的问候问题开始,还有来自老板的工作进度提问,到回答客...

每个人都该学的30个Python技巧|技巧 30:档案操作(字幕、衬乐、练习)

今天!就是今天!!这个系列终於要完结啦~(撒花)(狂撒) 最後一个要教的技巧就是关於档案操作,如果想...

不只懂 Vue 语法:後记 - 为自己坚持 30 天的参赛心得

终於完赛了,这篇文章会以个人完赛心得为主,可谓是零技术成分。(撒花~ 我以为完赛都是这样: 最後才没...

[Day_19]回圈与生成式 - (5)

for回圈与资料储存容器 若要取出资料储存容器(tuple、串列、字典与集合)的所有元素,可以使用「...