到底什麼是P問題、NP問題和NPC問題?

在網址:http://www.matrix67.com/blog/archives/105 看到的

加入一些個人想法後轉載的。

 

作者有一段話說:“不會存在O(2*n^2)的複雜度,因爲前面的那個“2”是係數,根本不會影響到整個程序的時間增長。同樣地,O (n^3+n^2)的複雜度也就是O(n^3)的複雜度。因此,我們會說,一個O(0.01*n^3)的程序的效率比O(100*n^2)的效率低,儘管在n很小的時候,前者優於後者,但後者時間隨數據規模增長得慢,最終O(n^3)的複雜度將遠遠超過O(n^2)。我們也說,O(n^100)的複雜度小於O(1.01^n)的複雜度。

 

容易看出,前面的幾類複雜度被分爲兩種級別,其中後者的複雜度無論如何都遠遠大於前者:一種是O(1),O(log(n)),O(n^a)等,我們把它叫做多項式級的複雜度,因爲它的規模n出現在底數的位置;另一種是O(a^n)和O(n!)型複雜度,它是非多項式級的,其複雜度計算機往往不能承受。當我們在解決一個問題時,我們選擇的算法通常都需要是多項式級的複雜度,非多項式級的複雜度需要的時間太多,往往會超時,除非是數據規模非常小。

 

是因爲指數爆炸吧。

即指數函數:f(x) = a^x (a爲常數),
當 a > 1 時,隨着 x 的增大,f(x) 的增長會明顯加快。
特別是當 a ≥ 2 時,當 x 增大到一定程度後,函數f(x) 會發生“爆炸性”的增長。

 

P問題(Polynomial):

如果一個問題可以找到一個能在多項式的時間裏解決它的算法,那麼這個問題就屬於P問題。

NP問題:

NP問題是指可以在多項式的時間裏驗證一個解的問題。

NP問題的另一個定義是,可以在多項式的時間裏猜出一個解的問題。

 

不是NP問題的問題:即你猜到了解但是沒用,因爲你不能在多項式的時間裏去驗證它。

一個經典的例子,它指出了一個目前還沒有辦法在多項式的時間裏驗證一個解的問題。很顯然,前面所說的Hamilton迴路是NP問題,因爲驗證一條路是否恰好經過了每一個頂點非常容易。但我要把問題換成這樣:試問一個圖中是否不存在Hamilton迴路。這樣問題就沒法在多項式的時間裏進行驗證了,因爲除非你試過所有的路,否則你不敢斷定它“沒有Hamilton迴路”。

 

      “NP問題”,實際上是在探討NP問題與P類問題的關係。因爲通常只有NP問題纔可能找到多項式的算法。我們不會指望一個連多項式地驗證一個解都不行的問題存在一個解決它的多項式級的算法。

    所有的P類問題都是NP問題。也就是說,能多項式地解決一個問題,必然能多項式地驗證一個問題的解——既然正解都出來了,驗證任意給定的解也只需要比較一下就可以了。關鍵是,人們想知道,是否所有的NP問題都是P類問題。我們可以再用集合的觀點來說明。如果把所有P類問題歸爲一個集合P中,把所有 NP問題划進另一個集合NP中,那麼,顯然有P屬於NP。現在,所有對NP問題的研究都集中在一個問題上,即究竟是否有NP=P?通常所謂的“NP問題”,其實就一句話:證明或推翻NP=P。

 

       但是目前,人們普遍認爲,NP=P不成立,也就是說,多數人相信,存在至少一個不可能有多項式級複雜度的算法的NP問題。人們如此堅信P≠NP是有原因的,就是在研究NP問題的過程中找出了一類非常特殊的NP問題叫做NP-完全問題,也即所謂的 NPC問題。C是英文單詞“完全”的第一個字母。正是NPC問題的存在,使人們相信P≠NP。

    爲了說明NPC問題,我們先引入一個概念——約化(Reducibility,有的資料上叫“歸約”)。
    簡單地說,一個問題A可以約化爲問題B的含義即是,可以用問題B的解法解決問題A,或者說,問題A可以“變成”問題B。《算法導論》上舉了這麼一個例子。比如說,現在有兩個問題:求解一個一元一次方程和求解一個一元二次方程。那麼我們說,前者可以約化爲後者,意即知道如何解一個一元二次方程那麼一定能解出一元一次方程。我們可以寫出兩個程序分別對應兩個問題,那麼我們能找到一個“規則”,按照這個規則把解一元一次方程程序的輸入數據變一下,用在解一元二次方程的程序上,兩個程序總能得到一樣的結果。這個規則即是:兩個方程的對應項係數不變,一元二次方程的二次項係數爲0。按照這個規則把前一個問題轉換成後一個問題,兩個問題就等價了。同樣地,我們可以說,Hamilton迴路可以約化爲TSP問題(Travelling Salesman Problem,旅行商問題):在Hamilton迴路問題中,兩點相連即這兩點距離爲0,兩點不直接相連則令其距離爲1,於是問題轉化爲在TSP問題中,是否存在一條長爲0的路徑。Hamilton迴路存在當且僅當TSP問題中存在長爲0的迴路。

  “問題A可約化爲問題B”有一個重要的直觀意義:B的時間複雜度高於或者等於A的時間複雜度。也就是說,問題A不比問題B難。這很容易理解。既然問題A能用問題B來解決,倘若B的時間複雜度比A的時間複雜度還低了,那A的算法就可以改進爲B的算法,兩者的時間複雜度還是相同。正如解一元二次方程比解一元一次方程難,因爲解決前者的方法可以用來解決後者。
    很顯然,約化具有一項重要的性質:約化具有傳遞性。如果問題A可約化爲問題B,問題B可約化爲問題C,則問題A一定可約化爲問題C。這個道理非常簡單,就不必闡述了。
    現在再來說一下約化的標準概念就不難理解了:如果能找到這樣一個變化法則,對任意一個程序A的輸入,都能按這個法則變換成程序B的輸入,使兩程序的輸出相同,那麼我們說,問題A可約化爲問題B。
    當然,我們所說的“可約化”是指的可“多項式地”約化(Polynomial-time Reducible),即變換輸入的方法是能在多項式的時間裏完成的。約化的過程只有用多項式的時間完成纔有意義。

       從約化的定義中我們看到,一個問題約化爲另一個問題,時間複雜度增加了,問題的應用範圍也增大了。通過對某些問題的不斷約化,我們能夠不斷尋找複雜度更高,但應用範圍更廣的算法來代替複雜度雖然低,但只能用於很小的一類問題的算法。再回想前面講的P和NP問題,聯想起約化的傳遞性,自然地,我們會想問,如果不斷地約化上去,不斷找到能“通吃”若干小NP問題的一個稍複雜的大NP問題,那麼最後是否有可能找到一個時間複雜度最高,並且能“通吃”所有的 NP問題的這樣一個超級NP問題?答案居然是肯定的。也就是說,存在這樣一個NP問題,所有的NP問題都可以約化成它。換句話說,只要解決了這個問題,那麼所有的NP問題都解決了。這種問題的存在難以置信,並且更加不可思議的是,這種問題不只一個,它有很多個,它是一類問題。這一類問題就是傳說中的NPC 問題,也就是NP-完全問題。NPC問題的出現使整個NP問題的研究得到了飛躍式的發展。我們有理由相信,NPC問題是最複雜的問題。再次回到全文開頭,我們可以看到,人們想表達一個問題不存在多項式的高效算法時應該說它“屬於NPC問題”。

 NPC問題的定義非常簡單。同時滿足下面兩個條件的問題就是NPC問題。首先,它得是一個NP問題;然後,所有的NP問題都可以約化到它。證明一個問題是 NPC問題也很簡單。先證明它至少是一個NP問題,再證明其中一個已知的NPC問題能約化到它(由約化的傳遞性,則NPC問題定義的第二條也得以滿足;至於第一個NPC問題是怎麼來的,下文將介紹),這樣就可以說它是NPC問題了。

既然所有的NP問題都能約化成NPC問題,那麼只要任意一個NPC問題找到了一個多項式的算法,那麼所有的NP問題都能用這個算法解決了,NP也就等於P 了。因此,給NPC找一個多項式算法太不可思議了。因此,前文才說,“正是NPC問題的存在,使人們相信P≠NP”。我們可以就此直觀地理解,NPC問題目前沒有多項式的有效算法,只能用指數級甚至階乘級複雜度的搜索。

順便講一下NP-Hard問題。NP-Hard問題是這樣一種問題,它滿足NPC問題定義的第二條但不一定要滿足第一條(就是說,NP-Hard問題要比 NPC問題的範圍廣)。NP-Hard問題同樣難以找到多項式的算法,但它不列入我們的研究範圍,因爲它不一定是NP問題。即使NPC問題發現了多項式級的算法,NP-Hard問題有可能仍然無法得到多項式級的算法。事實上,由於NP-Hard放寬了限定條件,它將有可能比所有的NPC問題的時間複雜度更高從而更難以解決。

        順便講一下NP-Hard問題。NP-Hard問題是這樣一種問題,它滿足NPC問題定義的第二條但不一定要滿足第一條(就是說,NP-Hard問題要比 NPC問題的範圍廣)。NP-Hard問題同樣難以找到多項式的算法,但它不列入我們的研究範圍,因爲它不一定是NP問題。即使NPC問題發現了多項式級的算法,NP-Hard問題有可能仍然無法得到多項式級的算法。事實上,由於NP-Hard放寬了限定條件,它將有可能比所有的NPC問題的時間複雜度更高從而更難以解決。

       不要以爲NPC問題是一紙空談。NPC問題是存在的。
       下文即將介紹邏輯電路問題。這是第一個NPC問題。其它的NPC問題都是由這個問題約化而來的。因此,邏輯電路問題是NPC類問題的“鼻祖”。

       邏輯電路問題是指的這樣一個問題:給定一個邏輯電路,問是否存在一種輸入使輸出爲True。
       什麼叫做邏輯電路呢?一個邏輯電路由若干個輸入,一個輸出,若干“邏輯門”和密密麻麻的線組成。看下面一例,不需要解釋你馬上就明白了。
  ┌───┐
  │ 輸入1├─→┐    ┌──┐
  └───┘    └─→┤    │
                      │ or ├→─┐
  ┌───┐    ┌─→┤    │    │    ┌──┐
  │ 輸入2├─→┤    └──┘    └─→┤    │
 &
nbsp;└───┘    │                ┌─→┤AND ├──→輸出
                └────────┘┌→┤    │
  ┌───┐    ┌──┐            │  └──┘
  │ 輸入3├─→┤ NOT├─→────┘
  └───┘    └──┘
    這是個較簡單的邏輯電路,當輸入1、輸入2、輸入3分別爲True、True、False或False、True、False時,輸出爲True。

 

    有輸出無論如何都不可能爲True的邏輯電路嗎?有。下面就是一個簡單的例子。
  ┌───┐
  │輸入1 ├→─┐    ┌──┐
  └───┘    └─→┤    │
                      │AND ├─→┐
                ┌─→┤    │    │
                │    └──┘    │  ┌──┐
                │                └→┤    │
  ┌───┐    │                    │AND ├─→輸出
  │輸入2 ├→─┤  ┌──┐      ┌→┤    │
  └───┘    └→┤NOT ├→──┘  └──┘
                    └──┘
     上面這個邏輯電路中,無論輸入是什麼,輸出都是False。我們就說,這個邏輯電路不存在使輸出爲True的一組輸入。

 

      有了第一個NPC問題後,一大堆NPC問題就出現了,因爲再證明一個新的NPC問題只需要將一個已知的NPC問題約化到它就行了。後來,Hamilton 迴路成了NPC問題,TSP問題也成了NPC問題。現在被證明是NPC問題的有很多,任何一個找到了多項式算法的話所有的NP問題都可以完美解決了。因此說,正是因爲NPC問題的存在,NP=P變得難以置信。NP=P問題還有許多有趣的東西,有待大家自己進一步的挖掘。攀登這個信息學的巔峯是我們這一代的終極目標。現在我們需要做的,至少是不要把概念弄混淆了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章