簡體   English   中英

大O符號-增長率

[英]Big O Notation - Growth Rate

我想了解我的推理是否正確:

如果我得到以下代碼片段,並被要求查找它是Big O:

 for(int i = 3; i < 1000; i++)
    sum++;

我想說O(n)是因為我們正在處理一個for循環,並且sum ++被迭代了n次,但是看着這個我意識到我們根本不處理n,因為我們得到了這個for循環的次數迭代...但是我認為這有一個O(1)的大O是錯誤的,因為增長是線性的並且不是恆定的,並且取決於此循環的大小(盡管循環是“恆定的”) 。 我說這是O(n)正確嗎?

另外,另一個讓我思考的問題也有類似的設置:

 for(int i = 0; i < n * n * n; i++)
    for(int j = 0; j < i; j++)
       sum++;

現在我再次知道,當處理包含內部和外部循環以及內部循環的嵌套循環時,我們將使用乘法規則來得出我們的BigO。讓我們假設內部循環實際上是j <n,那么我會說Big O這段代碼的代碼是O(n ^ 4),但不是,我們有第二個循環在i而不是n上運行其迭代,那么將其稱為O(n ^的大階數)是正確的3)?

我認為讓我感到困惑的是,沒有出現“ n”的地方,並且給了我們一個常量或另一個變量,突然間,我假設那部分代碼中不應考慮n。 但是,說完我的推理的另一部分是告訴我,盡管沒有看到'n',但無論變量如何,增長率都一樣,我還是應該將代碼視為存在n呢?

如果您認為代碼始終位於函數內,則該函數最好用函數的參數來計算復雜度。 從而:

// this is O(1), since it always takes the same time
void doSomething() {
    for(int i = 3; i < 1000; i++)
        sum++;
}

// this is O(n^6), since it only takes one argument
// and if you plot it, the curve matches t = k * n^6
void doSomethingElse(int n) {
  for(int i = 0; i < n * n * n; i++)
     for(int j = 0; j < i; j++)
        sum++;
}

最后,big-O的全部要點是要說明隨着問題規模的增大 ,運行時間 (或內存占用量;但是如果您什么也沒說,您是指運行時間)的樣子 無關緊要的是內部發生了什么(盡管您可以使用它來估計復雜性)-真正重要的是您將在外部進行度量。

仔細查看您的第二個片段,它是O(n ^ 6),因為:

  • 外循環正好運行n ^ 3次; 內部循環平均運行n ^ 3/2次。
  • 因此,內部和運行n ^ 3 * k * n ^ 3次(ka常數)。 用big-O表示法是O(n ^ 6)。

首先是O(1)或僅僅是一個錯誤的問題,就像您理解它一樣。

第二個是O(n 6 嘗試想象內部循環的大小。 在第一次迭代中,它將是1。在第二次迭代中,將是2。在第i個迭代中,它將是i ,而在最后一次迭代中,它將是n * n * n 因此它將是n * n * n / 2 ,但這是O(n * n * n) 即,外部O(n 3 )的總次數O(n 6

盡管其他人對您的問題的O()的計算可能是正確的,但這里有一些更多的見識可以幫助您描述整個漸近分析故事的概念前景。

我認為讓我感到困惑的是,沒有出現“ n”的地方,並且給了我們一個常量或另一個變量,突然間,我假設那部分代碼中不應考慮n。

理解這一點的最簡單方法是確定一行代碼的執行是否受n的當前值影響/與之相關。 假設內部循環是j <10而不是j <i,那么復雜度應該是O(n ^ 3)。

為什么將任何常量視為O(1)?

乍一看,這聽起來似乎有點違反直覺,但是,這里有一個小的概念摘要可以使您大開眼界。 假設您的第一個循環運行了1000次。 然后將其設置為10 ^ 1000次,並嘗試相信,不再需要相同的時間了。 很公平! 即使現在您的計算機可能需要5秒多的時間才能運行同一段代碼,但時間復雜度仍為O(1)。 這實際上意味着您實際上可以計算計算機執行該代碼段所花費的時間,並且該時間將永遠保持不變(對於相同的配置)。

Big-Oh實際上是輸入函數 ,而不是離散值本身(時間/空間)的量度。

我希望以上解釋也有助於弄清楚為什么我們實際上忽略了O()表示法中的常量。

為什么Big-Oh這么泛化,為什么首先使用它?

我本來想包含這些額外的信息,因為我本人在初次學習該主題時就想到了這個問題。 漸近時間復雜度是對任何算法的先驗分析,以了解該程序的最壞(Big-Oh)行為(時間/空間),而不管輸入的大小如何。 例如。 您的第二個代碼的性能不能比O(n ^ 6)差。 之所以這樣概括是因為,從一台計算機到另一台計算機,只有不斷變化,而不是Big-Oh。

有了更多的經驗,您將意識到,實際上,您希望算法的時間復雜度盡可能地漸近變小。 直到多項式函數都可以。 但是對於大量輸入,例如,如果您嘗試以O(k ^ n)或O(n ^ n)的指數時間復雜度運行算法,今天的計算機就會開始咳嗽。 旅行商和其他NP-C / H問題。

希望這會增加信息。 :)

暫無
暫無

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

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