什么是旅行商問題——算法NP、P、NPC知識


  學習 程序員小灰——《什么是旅行商問題》筆記:

旅行商問題

  旅行商問題所描述的是這樣一個場景:

    有一個商品推銷員,要去若干個城市推銷商品。該推銷員從一個城市出發,需要經過所有城市后,回到出發地。每個城市之間都有道路連通,且距離各不相同,推銷員應該如何選擇路線,使得總行程最短呢?

    這個問題看起來很簡單,卻很難找到一個真正高效的求解算法。其中最容易想到的,是使用窮舉法: 

    把所有可能的路線窮舉出來,計算出每一條路線的總行程:    

    A-B-C-D-E-F-G-H-I  

    A-B-C-D-E-F-G-I-H  

    A-B-C-D-E-F-H-G-I  

    A-B-C-D-E-F-H-I-G  

    A-B-C-D-E-F-I-H-G  

    A-B-C-D-E-F-I-G-H

    ......

    ......

    像上面這樣排列組合,從所有路線中找出總行程最短的路線。顯然,這個方法的時間復雜度是O(n!),隨着城市數量的增長,花費的運算時間簡直不可想象!

    后來,人們想出了許多相對優化的解決方案,比如動態規划法分枝定界法(這個算法很有意思,以后會專門寫一篇漫畫來詳細介紹)......但是,這些算法的時間復雜度仍然是指數級的,並沒有讓性能問題得到根本的解決。

P和NP

  NP到底是什么意思呢?

    我們曾經學習過許許多多的算法,這些算法的時間復雜度都可以用多項式來表示,比如:

    歸並排序的時間復雜度是O(nlogn)

    冒泡排序的時間復雜度是O(n^2)

    Floyd算法的時間復雜度是O(n^3)

    盡管這些算法的運行時間有數量級上的差別,但是它們的時間復雜度都可以用O(n^k)來表示,k是一個常數。

    因此,這些算法都是多項式時間算法,能用多項式時間算法解決的問題被稱為P問題( Polynomial)。

    人們常說,能用錢解決的問題都不是問題,在計算機科學家眼中,能用多項式時間解決的問題都不是問題。

    然而,世間還存在許多變態的問題,是無法(至少是暫時無法)在多項式時間內解決的,比如一些算法的時間復雜度是O(2^n),甚至O(n!)。

    隨着問題規模n的增長,計算量的增長速度是非常恐怖的。這類問題被稱為NP問題(Non-deterministic Polynomial),意思是“不確定是否能用多項式時間解決”。

    有些科學家認為,所有的NP問題終究都可以在多項式時間內解決,只是我們暫時還沒有找到方法;也有些科學家認為,某些NP問題永遠無法在多項式時間內解決。    

    這個業界爭論可以用一個公式來表達:

      NP = P?

歸約和NPC 

  這里所說的NPC問題可不是游戲當中的NPC,它究竟是什么意思呢?要想理解NPC問題,我們需要先了解歸約的概念。

    歸約,可以簡單理解成問題之間的轉化。例如問題Q是一個一元一次方程的求解問題:3x+6 = 12,這個問題可以轉化成一個一元二次問題Q':0x^2+3x+6 = 12。

    顯然,問題Q並不比問題Q'更難解決,只要有辦法解決Q',就一定能夠解決Q。對於這種情況,我們可以說問題Q歸約於問題Q'

    同時,這種歸約可以逐級傳遞,比如問題A歸約於問題B,問題B歸約於問題C,問題C歸約於問題D,那么我們可以說問題A歸約於問題D。

    在NP問題之間,也可以存在歸約關系。我們把眾多的NP問題層層歸約,必定會得到一個或多個“終極問題”,這些歸約的終點就是所謂的NPC問題(NP-complete),也可以翻譯成PC完全問題。上面所講的旅行商問題,被科學家證明屬於NPC問題。

    

    就數量上而言,NP問題遠比P問題要多,而NP之中的NPC問題也僅占極少數,所以P、NP、NPC之間的關系可以用下圖來表示:

    

    俗話說擒賊先擒王,只要有朝一日,我們能夠找到NPC問題的多項式時間算法,就能夠解決掉所有的NP問題!但遺憾的是,至今還沒有人能夠找到可行的方法,很多人認為這些問題是無解的。

回到最初的問題:

  既然是工程問題,我們與其鑽牛角尖尋求最優解,不如用小得多的代價尋求次優解。

    最簡單的辦法是使用貪心算法,先選擇距離起點最近的城市A,再選擇距離A城市最近的城市B... 以此類推,每一步都保證局部最優。

    這樣規划出的路線雖然未必是全局最優,但平均情況下也不會比最優方案差多少。

    除此之外,還有許多近似的解決方案,比如遺傳算法、蟻群算法等等。谷歌有一款開源工具OR-TOOL,當中也包含路線規划的實現,可以研究一下。

總結:

  本文提到的算法名及可擴展內容:    

    窮舉法、動態規划法、分枝定界法
    歸並排序、冒泡排序、Floyd算法
    貪心算法
    遺傳算法、蟻群算法
    谷歌開源工具OR-TOOL


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM