原答案:
algorithm - What is pseudopolynomial time? How does it differ from polynomial time?
我大概翻譯一下:
想要理解“僞多項式時間”,我們需要先給出“多項式時間”的一個清楚的定義。
對於“多項式時間”,我們的直觀概念是時間複雜度,其中是一常數。比如,選擇排序的時間複雜度是,是多項式時間;暴力解決TSP問題的時間複雜度是,不是多項式時間。我們稱這種時間複雜度爲“傳統時間複雜度”。
我們通常認爲傳統時間複雜度中的變量表示數據的輸入規模。比如,選擇排序中,指待排序數組中元素的個數;TSP問題中表示圖中節點的數量。但是,這些所謂的輸入規模,僅僅是直觀的定義,並不足夠嚴謹。爲了標準化這些,在計算標準時間複雜度時,我們給出了輸入規模的標準定義:
一個問題的輸入規模是保存輸入數據所需要的bit位數。
比如,如果排序算法的輸入是一個32-bit整數 數組,那麼輸入規模就是,是指數組中元素的個數。對於一個帶有個節點、條邊的圖,需要的bit位數就是。
瞭解了輸入規模的定義,我們來看“多項式時間”的標準定義:
對於一個問題,在輸入規模爲x的情況下,如果一個算法能夠在O()時間內解決此問題,則我們稱此算法是多項式時間的,其中爲一常數。
當我們處理一些圖論、鏈表、數組、樹等問題時,這個標準定義下的多項式時間和我們傳統的多項式時間相差無幾。比如,用選擇排序對元素個數爲的數組進行排序時,傳統時間複雜度爲。輸入規模,因此,得到的標準時間複雜度是,仍然是多項式時間。
類似的,假設在帶有個節點、條邊的圖中做DFS(深度優先搜索),傳統時間複雜度爲。數據規模,因此,標準時間複雜度是,仍是多項式時間的。
然而,當我們處理一些與數論有關的問題時,事情就不太樂觀了。現在我們來討論判斷一個整數是否爲素數的算法,下面是一個簡單的算法:顯然,這個算法在傳統時間複雜度計算方法中是多項式時間的。我們不妨認爲它的傳統時間複雜度是。然後我們再來分析這個問題的輸入規模,可能有的同學會說,對於32-bit整數,這個輸入規模不就是32嗎?這話雖然沒錯,但是因爲在這個問題中,輸入規模完全依賴於的大小,所以的範圍不再限制在32-bit整數的範圍內,而是要探討當更大時對數據規模的影響。我們知道,保存一個整數所需要的bit位數,因此,在標準的時間複雜度中,此算法的複雜度變爲了!這已經不再是多項式時間,而是一個指數時間。function isPrime(n): for i from 2 to n - 1: if (n mod i) = 0, return false return true
我們可以從下面這個例子中直觀感受一下這種指數時間的增長速度:
對於一個二進制串:
10001010101011
我們記指數時間複雜度算法運行時間爲T。
然後,我們在二進制串後面僅僅增加一位:
100010101010111
這時,算法運行時間會變爲2T(至少)!因此,我們僅僅增加幾個bit 就會使得算法運行時間成倍成倍的增長。
... ...
最後我們來說僞多項式時間的定義:
如果一個算法的傳統時間複雜度是多項式時間的,而標準時間複雜度不是多項式時間的,則我們稱這個算法是僞多項式時間的。
除此之外,原回答者還提到了僞多項式時間算法在加密中的應用,多項式時間的素數判斷算法等,有興趣的同學請移步原答案。