簡體   English   中英

迭代算法的時間復雜度

[英]Time complexity of an iterative algorithm

我試圖找到這個算法的時間復雜度。

迭代:算法從輸入比特串產生給定漢明距離內的所有比特串。 它生成所有增加的序列0 <= a[0] < ... < a[dist-1] < strlen(num) ,並在相應的索引處恢復位。

假設向量a保持必須反轉位的索引。 因此,如果a包含當前索引i ,則我們打印1而不是0,反之亦然。 否則我們按原樣打印該位(參見else-part),如下所示:

// e.g. hamming("0000", 2);
void hamming(const char* num, size_t dist) {
    assert(dist > 0);
    vector<int> a(dist);
    size_t k = 0, n = strlen(num);
    a[k] = -1;
    while (true)
        if (++a[k] >= n)
            if (k == 0)
                return;
            else {
                --k;
                continue;
            }
        else
            if (k == dist - 1) {
                // this is an O(n) operation and will be called
                // (n choose dist) times, in total.
                print(num, a);
            }
            else {
                a[k+1] = a[k];
                ++k;
            }
}

這個算法的時間復雜度是多少?


我的嘗試說:

dist * n +(n選擇t)* n + 2

但這似乎並非如此,請考慮以下示例,所有示例均為dist = 2:

len = 3, (3 choose 2) = 3 * O(n), 10 while iterations
len = 4, (4 choose 2) = 6 * O(n), 15 while iterations
len = 5, (5 choose 2) = 9 * O(n), 21 while iterations
len = 6, (6 choose 2) = 15 * O(n), 28 while iterations

這是兩個代表性的運行(在循環開始時打印):

000, len = 3
k = 0, total_iter = 1
vector a = -1 0 
k = 1, total_iter = 2
vector a = 0 0 
Paid O(n)
k = 1, total_iter = 3
vector a = 0 1 
Paid O(n)
k = 1, total_iter = 4
vector a = 0 2 
k = 0, total_iter = 5
vector a = 0 3 
k = 1, total_iter = 6
vector a = 1 1 
Paid O(n)
k = 1, total_iter = 7
vector a = 1 2 
k = 0, total_iter = 8
vector a = 1 3 
k = 1, total_iter = 9
vector a = 2 2 
k = 0, total_iter = 10
vector a = 2 3 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gsamaras@pythagoras:~/Desktop/generate_bitStrings_HammDistanceT$ ./iter
0000, len = 4
k = 0, total_iter = 1
vector a = -1 0 
k = 1, total_iter = 2
vector a = 0 0 
Paid O(n)
k = 1, total_iter = 3
vector a = 0 1 
Paid O(n)
k = 1, total_iter = 4
vector a = 0 2 
Paid O(n)
k = 1, total_iter = 5
vector a = 0 3 
k = 0, total_iter = 6
vector a = 0 4 
k = 1, total_iter = 7
vector a = 1 1 
Paid O(n)
k = 1, total_iter = 8
vector a = 1 2 
Paid O(n)
k = 1, total_iter = 9
vector a = 1 3 
k = 0, total_iter = 10
vector a = 1 4 
k = 1, total_iter = 11
vector a = 2 2 
Paid O(n)
k = 1, total_iter = 12
vector a = 2 3 
k = 0, total_iter = 13
vector a = 2 4 
k = 1, total_iter = 14
vector a = 3 3 
k = 0, total_iter = 15
vector a = 3 4 

while循環是有點聰明和微妙的,並且(如果算上的初始化甚至三是值得商榷的,它在做兩個不同的東西a )。 這就是讓你的復雜性計算具有挑戰性的因素,而且它的效率也低於它。

在摘要中,為了逐步計算當前索引的下一組索引,我們的想法是找到最后一個索引i ,它小於n-dist+i ,遞增它,並將以下索引設置a[i]+1a[i]+2 ,依此類推。

例如,如果dist = 5,則n = 11並且您的索引是:

0, 3, 5, 9, 10

那么5是小於n-dist+i的最后一個值(因為n-dist是6,而10 = 6 + 4,9 = 6 + 3,但是5 <6 + 2)。

所以我們遞增5 ,並設置后續整數以獲得索引集:

0, 3, 6, 7, 8

現在考慮代碼如何運行,假設k=4

0, 3, 5, 9, 10
  • a[k] + 1是11,所以k變為3。
  • ++a[k]是10,所以a[k+1]變為10, k變為4。
  • ++a[k]是11,所以k變為3。
  • ++a[k]是11,所以k變為2。
  • ++a[k]是6,所以a[k+1]變為6, k變為3。
  • ++a[k]是7,所以a[k+1]變為7, k變為4。
  • ++a[k]是8,我們繼續調用print函數。

這段代碼是正確的,但它沒有效率,因為k向后和向前搜索,因為它正在搜索可以遞增而不會導致較高索引溢出的最高索引。 實際上,如果最高索引是從末尾開始的j ,則代碼使用while循環的非線性數字迭代。 如果你跟蹤n==distn不同值的while循環發生了多少迭代,你可以自己很容易地證明這一點。 只有一行輸出,但你會看到迭代次數增加了O(2 ^ n)(事實上,你會看到2 ^(n + 1)-2次迭代)。

這種破壞使你的代碼不必要地低效,而且難以分析。

相反,您可以以更直接的方式編寫代碼:

void hamming2(const char* num, size_t dist) {
    int a[dist];
    for (int i = 0; i < dist; i++) {
        a[i] = i;
    }
    size_t n = strlen(num);
    while (true) {
        print(num, a);
        int i;
        for (i = dist - 1; i >= 0; i--) {
            if (a[i] < n - dist + i) break;
        }
        if (i < 0) return;
        a[i]++;
        for (int j = i+1; j<dist; j++) a[j] = a[i] + j - i;
    }
}

現在,每次通過while循環都會生成一組新的索引。 每次迭代的確切成本並不簡單,但由於print是O(n),而while循環中的剩余代碼處於最差O(dist),因此總成本為O(N_INCR_SEQ(n,dist)* n),其中N_INCR_SEQ(n,dist)是自然數<n的長度dist的增加序列的數量。 評論中的某個人提供了一個鏈接,為此提供了一個公式。

請注意,給定n代表長度, t代表所需距離, 1n之間的t整數增加,非負序列的數量(或索引形式, 0n-1 )確實為n choose t ,因為我們挑選t不同的指數。

您生成這些系列會出現問題:

- 首先,請注意,例如在長度為4的情況下,您實際上會超過5個不同的索引,0到4。

- 其次,請注意您正在考慮具有相同索引的帳戶系列(在t=2的情況下,其0 0, 1 1, 2 2等等),通常,您將查看每個非遞減系列,而不是通過每一個增加的系列。

因此,為了計算程序的TC,請確保將其考慮在內。

提示:嘗試從這些系列的宇宙中進行一對一的對應,到一些方程的整數解的范圍。

如果您需要直接解決方案,請查看此處: https//math.stackexchange.com/questions/432496/number-of-non-decreasing-sequences-of-length-m


最終的解決方案是(n+t-1) choose (t) ,但注意到你的程序中的第一個子彈,它實際上((n+1)+t-1) choose (t) ,因為你循環一個額外的指數。 表示

((n+1)+t-1) choose (t) =: An choose t =: B

總體上我們得到O(1) + B*O(n) + (AB)*O(1)

暫無
暫無

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

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