P問題 NP問題 NPC問題 NP難問題的概念

2021-06-02 02:35:19 字數 3229 閱讀 2668

你會經常看到網上出現「這怎麼做,這不是np問題嗎」、「這個只有搜了,這已經被證明是np問題了」之類的話。你要知道,大多數人此時所說的np問題其實都是指的npc問題。他們沒有搞清楚np問題和npc問題的概念。np問題並不是那種「只有搜才行」的問題,npc問題才是。好,行了,基本上這個誤解已經被澄清了。下面的內容都是在講什麼是p問題,什麼是np問題,什麼是npc問題,你如果不是很感興趣就可以不看了。接下來你可以看到,把np問題當成是 npc問題是乙個多大的錯誤。 

還是先用幾句話簡單說明一下時間複雜度。時間複雜度並不是表示乙個程式解決問題需要花多少時間,而是當問題規模擴大後,程式需要的時間長度增長得有多快。也就是說,對於高速處理資料的計算機來說,處理某乙個特定資料的效率不能衡量乙個程式的好壞,而應該看當這個資料的規模變大到數百倍後,程式執行時間是否還是一樣,或者也跟著慢了數百倍,或者變慢了數萬倍。不管資料有多大,程式處理花的時間始終是那麼多的,我們就說這個程式很好,具有o(1)的時間複雜度,也稱常數級複雜度;資料規模變得有多大,花的時間也跟著變得有多長,這個程式的時間複雜度就是o(n),比如找n個數中的最大值;而像氣泡排序、插入排序等,資料擴大2倍,時間變慢4倍的,屬於o(n^2)的複雜度。還有一些窮舉類的演算法,所需時間長度成幾何階數**,這就是o(a^n)的指數級複雜度,甚至o(n!)的階乘級複雜度。不會存在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!)型複雜度,它是非多項式級的,其複雜度計算機往往不能承受。當我們在解決乙個問題時,我們選擇的演算法通常都需要是多項式級的複雜度,非多項式級的複雜度需要的時間太多,往往會超時,除非是資料規模非常小。 

自然地,人們會想到乙個問題:會不會所有的問題都可以找到複雜度為多項式級的演算法呢?很遺憾,答案是否定的。有些問題甚至根本不可能找到乙個正確的演算法來,這稱之為「不可解問題」(undecidable decision problem)。the halting problem就是乙個著名的不可解問題,在我的blog上有過專門的介紹和證明。再比如,輸出從1到n這n個數的全排列。不管你用什麼方法,你的複雜度都是階乘級,因為你總得用階乘級的時間列印出結果來。有人說,這樣的「問題」不是乙個「正規」的問題,正規的問題是讓程式解決乙個問題,輸出乙個「yes」或「no」(這被稱為判定性問題),或者乙個什麼什麼的最優值(這被稱為最優化問題)。那麼,根據這個定義,我也能舉出乙個不大可能會有多項式級演算法的問題來:hamilton迴路。問題是這樣的:給你乙個圖,問你能否找到一條經過每個頂點一次且恰好一次(不遺漏也不重複)最後又走回來的路(滿足這個條件的路徑叫做hamilton迴路)。這個問題現在還沒有找到多項式級的演算法。事實上,這個問題就是我們後面要說的npc問題。 

下面引入p類問題的概念:如果乙個問題可以找到乙個能在多項式的時間裡解決它的演算法,那麼這個問題就屬於p問題。p是英文單詞多項式的第乙個字母。哪些問題是p類問題呢?通常noi和noip不會出不屬於p類問題的題目。我們常見到的一些資訊奧賽的題目都是p問題。道理很簡單,乙個用窮舉換來的非多項式級時間的超時程式不會涵蓋任何有價值的演算法。 

接下來引入np問題的概念。這個就有點難理解了,或者說容易理解錯誤。在這裡強調(回到我竭力想澄清的誤區上),np問題不是非p類問題。np問題是指可以在多項式的時間裡驗證乙個解的問題。np問題的另乙個定義是,可以在多項式的時間裡猜出乙個解的問題。比方說,我rp很好,在程式中需要列舉時,我可以一猜乙個準。現在某人拿到了乙個求最短路徑的問題,問從起點到終點是否有一條小於100個單位長度的路線。它根據資料畫好了圖,但怎麼也算不出來,於是來問我:你看怎麼選條路走得最少?我說,我rp很好,肯定能隨便給你指條很短的路出來。然後我就胡亂畫了幾條線,說就這條吧。那人按我指的這條把權值加起來一看,嘿,神了,路徑長度98,比100小。於是答案出來了,存在比100小的路徑。別人會問他這題怎麼做出來的,他就可以說,因為我找到了乙個比100 小的解。在這個題中,找乙個解很困難,但驗證乙個解很容易。驗證乙個解只需要o(n)的時間複雜度,也就是說我可以花o(n)的時間把我猜的路徑的長度加出來。那麼,只要我rp好,猜得準,我一定能在多項式的時間裡解決這個問題。我猜到的方案總是最優的,不滿足題意的方案也不會來騙我去選它。這就是np問題。當然有不是np問題的問題,即你猜到了解但是沒用,因為你不能在多項式的時間裡去驗證它。下面我要舉的例子是乙個經典的例子,它指出了乙個目前還沒有辦法在多項式的時間裡驗證乙個解的問題。很顯然,前面所說的hamilton迴路是np問題,因為驗證一條路是否恰好經過了每乙個頂點非常容易。但我要把問題換成這樣:試問乙個圖中是否不存在hamilton迴路。這樣問題就沒法在多項式的時間裡進行驗證了,因為除非你試過所有的路,否則你不敢斷定它「沒有hamilton迴路」。 

之所以要定義np問題,是因為通常只有np問題才可能找到多項式的演算法。我們不會指望乙個連多項式地驗證乙個解都不行的問題存在乙個解決它的多項式級的演算法。相信讀者很快明白,資訊學中的號稱最困難的問題——「np問題」,實際上是在**np問題與p類問題的關係。 

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

np問題一直都是資訊學的巔峰。巔峰,意即很引人注目但難以解決。在資訊學研究中,這是乙個耗費了很多時間和精力也沒有解決的終極問題,好比物理學中的大統一和數學中的歌德**猜想等。 

目前為止這個問題還「啃不動」。但是,乙個總的趨勢、乙個大方向是有的。人們普遍認為,p=np不成立,也就是說,多數人相信,存在至少乙個不可能有多項式級複雜度的演算法的np問題。人們如此堅信p≠np是有原因的,就是在研究np問題的過程中找出了一類非常特殊的np問題叫做np-完全問題,也即所謂的 npc問題。c是英文單詞「完全」的第乙個字母。正是npc問題的存在,使人們相信p≠np。下文將花大量篇幅介紹npc問題,你從中可以體會到npc問題使p=np變得多麼不可思議。 

為了說明npc問題,我們先引入乙個概念——約化(reducibility,有的資料上叫「歸約」)。 

P問題 NP問題 NP完全問題和NP難問題

在講p類問題之前先介紹兩個個概念 多項式,時間複雜度。知道這兩概念的可以自動跳過這部分 1 多項式 axn bxn 1 c 恩.就是長這個樣子的,叫x最高次為n的多項式.咳咳,別嫌我囉嗦。有些人說不定還真忘了啥是多項式了。例如第一次看到的鄙人 2 時間複雜度 我們知道在計算機演算法求解問題當中,經常...

P問題 NP問題和NPC問題

p就是能在多項式時間內解決的問題 np就是能在多項式時間驗證答案正確與否的問題。p是否等於np實質上就是在問,如果對於乙個問題我能在多項式時間內驗證其答案的正確性,那麼我是否能在多項式時間內解決它?再說說np hardness和np completenes.這裡涉及乙個概念,不妨稱為問題之間的歸約。...

P問題 NP問題 NP完全問題和NP難問題概念梳理

正規的問題是讓程式解決乙個問題 很顯然,p類問題是np類問題,p類問題的驗證程式可以這樣設計,顯然驗證程式屬於o 多項式 驗證程式 猜測解 演算法程式 問題解 return 問題解 猜測解p np問題其實 的就是p類問題和np類問題的關係,由前面我們知道p類問題是np類問題,但是我們仍不知道np類問...