簡體   English   中英

算法最壞情況運行時間的上限與下限

[英]Upper bound vs lower bound for worst case running time of an algorithm

我正在學習算法分析。 我理解算法的最壞情況運行時間的概念。

但是,算法在最壞情況下運行時間的上限和下限是多少?

有什么可以將上結合用於運行算法的時間最壞情況下的例子是從不同的下限為運行相同的算法的時間的最壞情況?

對於函數f(n)g(n)上限大 O ),如果對於“足夠大的 n”, f(n)<=c*g(n) ,對於常量c [g 支配 f]
g(n) 是下限大 Omega ),如果對於“足夠大的 n”, f(n) >= c*g(n) ,對於常數c [f 支配 g]

如果g(n)f(n)上界和下界 [具有不同的 c],我們說 g(n) 是 f(n) [Big theta] 的緊界

使用上界而不是緊上界的例子:有時,很難找到緊上界,例如斐波遞歸算法。 所以我們很容易找到 O(2^n) 的簡單上界。 在這篇文章的答案中可以找到更多信息。

它與最壞/基本/...情況有什么關系? (根據評論要求):

最壞情況/平均情況(或任何其他情況)會影響復雜度函數是什么,但 big-O、big-Omega 和 big-Theta 可以應用於這些情況中的每一種。

例如,HashTable 插入是Θ(1)平均情況插入和Θ(n)最壞情況插入。 它也是O(n)平均情況插入(邊界不嚴密)和Ω(1)最壞情況插入。

首先,讓我們談談案例。 算法輸入案例問題實例相關聯。 對於排序問題(我們希望以特定順序查找集合的排列),我可以查看一個實例,例如數字集合 {1, 5, 4, 2, 6}。 這組數字將成為旨在解決排序問題的排序算法的輸入,例如選擇排序或其他排序算法之一。

可以為任何想要解決問題的算法提供相同的輸入集。 不管我使用什么排序算法,輸入集總是相同的(因為,根據定義,它們都是同一問題的實例)。 但是,對於給定算法,給定情況可能更好或更糟。 無論輸入是什么,有些算法總是執行相同的操作,但有些算法在某些輸入上可能表現更差。 然而,這意味着每個算法都有一些最好的情況和一些最壞的情況; 我們有時也會談論平均情況(通過取所有情況的平均值)或預期情況(當我們有理由預期一種情況會比其他情況更常見時)。

算法案例示例

“找到未排序列表的最小值”的問題對於每個可能的輸入總是相同的。 不管你寫什么聰明的算法,你都必須檢查每一個元素。 如果您有一個零列表或隨機數列表或第一個元素是最小值的列表,這並不重要,直到您到達最后才知道。 該算法的每種情況都是相同的,因此最好的情況是最壞的情況,平均情況和預期情況也是如此。 如果列表被排序,我們可以做得更好,但這是一個不同的問題。

“在列表中查找給定元素”的問題是不同的。 假設您使用的是對列表進行線性遍歷的算法,結果可能是給定元素是列表的第一個元素,並且您會立即完成。 但是,它也可能是列表的最后一個元素,在這種情況下,您必須遍歷整個內容才能找到它。 所以你有一個最好的情況和一個最壞的情況。

作為輸入大小函數的算法

當我們想要分析一個算法時,我們算法學家會考慮我們可以向算法拋出的每一種可能情況。 通常,兩個最有趣的情況是最好的情況和最壞的情況。 如果您將算法運行時視為其輸入的函數,那么最好的情況是最小化函數的輸入,而最壞的情況是最大化函數的輸入。 我在這里使用代數數學意義上的“函數”:繪制一條線的一系列 x/y 對(輸入/輸出對,或在本例中為“輸入大小/執行步驟數”)。

由於算法的運行時間是其輸入的函數,因此對於每種可能的輸入大小,我們都有不同的最佳情況(和最壞情況)。 所以有時我們將最好的情況視為單個輸入,但它實際上是一組輸入(每個輸入大小一個)。 對於給定的算法來說,最好的情況和最壞的情況是非常具體的事情。

界限

現在邊界呢? 邊界是我們用來與給定算法的函數進行比較的函數。 我們可以考慮無數的邊界函數。 您可以在圖形上繪制多少種可能的線條? 這就是邊界函數的數量。 大多數算法學家通常只對一些特定的函數感興趣:常數函數、線性函數、對數函數、指數函數等。

上限是位於另一個函數之上的函數。 下限是位於另一個函數之下的函數。 當我們談論 Big O 和 Big Omega 時,我們並不關心邊界是否總是高於或低於另一個函數,只是在某個點之后它們總是如此(因為有時算法對於小輸入大小會變得奇怪)。

任何給定函數都有無數個可能的上限,任何給定函數都有無數個可能的下界。 但當我們談論不同大小的無窮大時,這是那些奇怪的時期之一。 作為上限,該函數不能低於另一個函數,因此我們排除了另一個函數下面的無限多個函數(因此它小於所有可能函數的集合)。

當然,僅僅因為有無限的上限,並不意味着它們都是有用的。 函數 f(∞) 是每個函數的上限,但這就像在說“我的錢少於無窮多”——對於確定我是身無分文還是百萬富翁來說並不是特別有用。 因此,我們經常對“緊”的上限(也稱為“最小上限”或“最高”)感興趣,對此沒有更好的上限。

最佳/最差情況 + 下限/上限

我們有代表算法運行時函數的上函數和下函數的最佳/最壞情況。 我們有上界和下界代表其他函數,它們可能位於(分別)任何其他函數的頂部或下方。 它們可以結合起來表達關於算法的關鍵思想。

最壞情況下界:當算法被賦予最大化算法運行時間的輸入時,該函數是算法運行時函數下方的邊界。

Worst Case Upper Bound :一個函數,它是算法運行時函數之上的邊界,當該算法被賦予最大化算法運行時間的輸入時。

最佳情況下界:當該算法被賦予最小化算法運行時間的輸入時,該函數是算法運行時函數下方的邊界。

最佳情況上限:當該算法被賦予最小化算法運行時間的輸入時,該函數是算法運行時函數之上的邊界。

大小寫邊界的例子

讓我們舉出具體的例子來說明我們什么時候可能會關心這些:

最壞情況下界:這里的經典示例是基於比較的排序,眾所周知,在最壞情況下為 Ω(n log(n))。 無論你設計什么算法,我都可以選擇一組最壞情況的輸入,其中最緊密的下界函數是對數線性的。 您無法制作出能夠超越最壞情況的算法,您也不應該費心去嘗試。 它是排序的基礎。 當然,最壞的情況有很多下界:常數、線性和次線性都是下界。 但它們不是有用的下限,因為對數線性下限是最嚴格的。

最佳情況下界插入排序的工作原理是遍歷列表,並將遇到的任何亂序插入到正確的位置。 如果列表已排序,則只需要遍歷列表一次而無需執行任何插入操作。 這意味着最好情況的最嚴格的下限是 Ω(n)。 你不能在不犧牲正確性的情況下做得更好,因為你仍然需要能夠遍歷列表(線性時間)。 然而,最好情況的下限比最壞情況的下限要好!

最壞情況上限:我們經常對在最壞情況下找到一個嚴格的上限感興趣,因為這樣我們就知道我們的算法在最壞的情況下運行得有多糟糕。 插入排序的最壞情況是一個完全無序的列表(即完全顛倒其正確順序)。 每次我們看到一個新項目時,我們必須將它移動到列表的開頭,將所有后續項目向前推(這是一個線性時間操作,執行線性次數會導致二次行為)。 然而,我們仍然知道這種插入行為在最壞情況下將是 O(n2),作為最壞情況下的嚴格上限。 這不是很好,但它比指數或階乘的上限要好! 當然,這些是最壞情況下的有效上限,但這又不如知道二次方是一個緊上限那么有用。

最佳情況上限:我們的算法在最好的情況下能做到的最壞情況是什么? 在之前在列表中查找元素的示例中,第一個元素是我們想要的元素,上限是 O(1)。 在最壞的情況下它是線性的,但在最好的情況下,可能發生的最壞情況是它仍然是恆定的。 在我看來,這個特定的想法通常不如 Worst Case Upper Bound 重要,因為我們通常更關心處理最壞的情況,而不是最好的情況。

其中一些示例實際上是 Ө,而不僅僅是 O 和 Ω。 在其他情況下,我可以選擇不緊的下​​界或上界函數,但仍然足夠近似以供使用(請記住,如果我們不緊,我有無限的井可以從中汲取!)。 請注意,可能很難找到不同 case/bound 組合的引人注目的示例,因為這些組合具有不同的效用。

誤解和術語

通常,您會看到人們對這些定義有誤解 事實上,許多非常優秀的計算機科學家會松散地互換使用這些術語。 然而,case 和 bounds 的概念是不同的,你最好確保你理解它們。 這是否意味着差異會出現在您的日常生活中? 不。但是當您在幾種不同的算法之間進行選擇時,您需要閱讀有關案例和界限的細則。 有人告訴你他們的算法有一個 O(1) 的最佳情況上界可能是想把羊毛拉到你的眼睛上 - 確保你問他們最壞情況上界是什么!

讓我通過一個例子來說明這一點:

快速排序的最壞情況運行時間是Theta(n^2) 所以一個有效的下限是Omega(n) ,上限是O(n^3) 這表示在最壞的情況下,快速排序將花費至少線性時間和最多三次時間。

現在這不是一個非常精確的陳述,但對於更復雜的算法,這樣的陳述是我們能做的最好的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM