簡體   English   中英

這個for循環的時間復雜度是多少(與`n`有關)?

[英]What is the time complexity of this for loop (be related to `n`)?

這個for循環的時間復雜度是多少(與n有關)?

for(int i = 1, j; i <= n; i = j + 1)
{
        j = n / (n / i);
}

請注意, ijn是整數變量,它們遵循整數運算。 特別是,循環內的表達式n/(n/i)應解釋如下:

在此輸入圖像描述

如果我們使用j = i; 而不是j = n / (n / i); ,時間復雜度為O(n)。 現在它是j = n / (n / i); ,假設n = i * k + r ,其中k和r都是整數, r = n%i 因此j =(i * k + r)/((i * k + r)/ i)=(i * k + r)/ k = i + r / k> = i,這意味着我將比你使用j = i; 所以至少時間復雜度小於O(n),我想這給你另一個O(n)。

除了大O表示法之外,還有另外兩種符號(Θ和Ω),這意味着O(n)的下限和上限。 通過找到這兩個邊界,您可以獲得時間復雜性。 如果我沒記錯的話還有另一條規則,O(k * n)= O(n),系數k無論多大都無關緊要。

正如taotsi闡述的 ,每次迭代中i的增量為

inc = 1 + r/k

其中r=n%ik=n/i 由於r<i ,只要i<sqrt(n) ,增量就是1(因為那時i*i/n<1在整數除法中變為0 )。 此后,增量為(典型地) 2只要i<2*sqrt(n) 這繼續類似於幾何級數,給出因子2超過sqrt(n) ,即2 sqrt(n)次迭代。

如果我們用整數0 <= b <= 2*a (即a=int(sqrt(n))b=na*a )寫n = a*a+b ,那么簡單實驗中的迭代總數是總是

b < a?  2*a-1 : 2*a

因此,復雜度為O(√n)(假設在循環內部完成了一些有用的工作,例如計算總迭代次數,這樣就不允許編譯器忽略整個循環)。

由於@Walter已經提供了一個證明,我對這個部分來說太遲了,但這里是你的代碼的Python3版本和迭代次數的圖,它是n2*sqrt(n)函數的函數。 它們看起來大致相同(最多n = 1e9 )。

import matplotlib.pyplot as plt
from numba import jit
import math

@jit
def weird_increment_loop(n):
    i = 1
    j = 0
    iterations = 0
    while i <= n:
        j = n // (n // i)
        i = j + 1
        iterations = iterations + 1

    return iterations

iterations = []
func_2sqrt = []
domain = range(0,1000000001,1000000)
for n in domain:
    iterations.append(weird_increment_loop(n))
    func_2sqrt.append(math.sqrt(n)*2)

plt.plot(domain,iterations)
plt.plot(domain,func_2sqrt)
plt.xlabel("n")
plt.ylabel("iterations(n) and 2*sqrt(n)")
plt.show()

這是情節: 在此輸入圖像描述

如果你沒有看到差異,那是因為幾乎沒有:D當然,人們應該始終信任數學;)

嚴格按照C ++的規則,它是O(1) 循環在經過一些有限量的不可觀察的工作之后終止,或者它永遠循環(這是未定義的行為)。 一致的實現可能假設未遇到未定義的行為,因此我們可以假設它終止。

因為程序的可觀察效果不依賴於循環內部發生的事情,所以允許實現“假設”它為虛無。

暫無
暫無

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

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