什麼是算法?它有什麼特點?
算法是一組規則或過程,用於解決特定問題或完成特定任務。算法通常包括一系列的步驟和操作,可以將輸入數據轉換爲輸出數據。算法可以應用於各種領域,如計算機科學、數學、工程等,用於解決計算、優化、搜索、排序、加密等問題。
算法有以下幾個特點:
精確性:算法必須準確無誤地描述每一個步驟和操作,以便實現正確的結果。
確定性:算法必須是確定性的,即對於相同的輸入數據,算法的輸出結果應該是唯一的。
可行性:算法必須能夠在有限的時間和空間內完成計算任務。
有限性:算法必須在有限的時間內終止,並給出結果,不能無限循環或死循環。
通用性:算法必須適用於一般情況,而不是特定的輸入數據或問題。
算法分析題
(1) 假設某算法的輸入規模爲\(n\)時計算時間爲 \(3\times 2^n\) 在某臺計算機上實現並完成該算法的時間爲t秒。現有另一臺計算機其運行速度爲第一臺的\(64\)倍,那麼在這臺新機器上用同一算法在t秒內能解輸入規模爲多大的問題?
有64倍的算力,又有 \(2^6=64\),則在\(t\)秒內,可以處理規模爲\(n+6\)的方案。
(2) 若上述算法的計算時間改進爲 \(T(n) = n^2\) 其餘條件不變,則在新機器上用t秒時間能解輸入規模爲多大的問題?
設可以解決規模爲\(m\)的問題
則有 \(3\times 2^n = m^2\),得 \(m = \sqrt{3*2^n}\)
則可以解決規模爲m的問題
(3) 若上述算法的計算時間改進爲 \(T(n)= 8\) 其餘條件不變,則在新機器上用\(t\)秒時間能解輸入規模爲多大的問題?
能夠解決任意大規模的問題
利用求極限的方法(洛必達法則)分析下列函數對的漸進關係,並用漸進符號 \(\Theta\), \(\Omega\), \(O\) 表示:
(1)\(f(n) = \sqrt[3]{n} + 5\log{n}; \ g(n) = \sqrt[5]{n}\log{n} + 390\)
所以\(f(n) = \Omega(g(n))\)
(2)\(f(n) = 20n^2 + 20n + n\log{n}; \ g(n) = 100n^{1.9} + 1000\)
所以\(f(n) = \Omega(g(n))\)
(3)\(f(n) = n(\log(\log{n}))^{10}; \ g(n) = n(\log{n})^2 + 1.8n\)
所以\(f(n) = O(g(n))\)
(4) \(f(n) = 145n^4 + 20n + n\log{n}; \ g(n) = \frac{1}{n}(1.01)^n + 1.8n + 505\)
所以\(f(n) = O(g(n))\)
利用複雜度漸進階的定義證明下列性質:
1,\(O(f) + O(g) = O(f + g)\)
首先,我們可以將\(O(f)\)和\(O(g)\)中的常數和低階項去掉,因爲它們對於漸進複雜度沒有影響。因此,我們可以寫出:
\(O(f) + O(g) = k_1 \cdot f(n) + k_2 \cdot g(n)\)
其中\(k_1\)和\(k_2\)是兩個常數。現在我們需要分析\(k_1 \cdot f(n) + k_2 \cdot g(n)\)的複雜度。
根據大O符號的定義,我們可以得出:
\(k_1 \cdot f(n) + k_2 \cdot g(n) \leq (k_1 + k_2) \cdot max(f(n), g(n))\)
因此,我們可以得出:
\(O(f) + O(g) = k_1 \cdot f(n) + k_2 \cdot g(n) = O(max(f(n), g(n))) = O(f + g)\)
2,\(O(f)O(g) = O(fg)\)
由於\(O(f(n))\)和\(O(g(n))\)分別表示\(f(n)\)和\(g(n)\)的上界,因此我們可以將它們表示爲:
\(O(f(n)) \leq c_1 f(n)\),其中\(c_1\)是一個正常數 \(O(g(n)) \leq c_2 g(n)\),其中\(c_2\)是一個正常數
將這兩個不等式相乘,我們得到:
\(O(f(n))O(g(n)) \leq c_1c_2f(n)g(n)\)
這說明\(O(f(n))O(g(n))\)是\(O(f(n)g(n))\)的上界。因此,我們可以得出:
\(O(f(n))O(g(n)) = O(f(n)g(n))\)
3,如果 \(g(n) = O(f(n))\), 則 \(O(g(n)) + O(f(n)) = O(f(n))\)
如果\(g(n) = O(f(n))\),那麼存在一個常數\(c>0\)和\(n_0 > 0\),使得對於所有\(n \geq n_0\),有\(g(n) \leq cf(n)\)。
根據\(O\)符號的加法規則,\(O(g(n)) + O(f(n)) = O(max(g(n), f(n)))\)。
因此,我們需要證明\(O(max(g(n), f(n))) = O(f(n))\)。
根據\(g(n) = O(f(n))\)的定義,我們有\(g(n) \leq cf(n)\)。因此,\(max(g(n), f(n)) = f(n) + (g(n) - f(n)) \leq f(n) + cf(n) = (c+1)f(n)\)。
4,\(O(Cf(n)) = O(f(n))\), 其中 \(C\) 是任意正常數
假設存在一個函數\(h(n) = Cf(n)\),我們要證明\(h(n) = O(f(n))\)。
根據大O符號的定義,我們需要找到一個正常數\(C_1\)和一個正整數\(N_1\),使得對所有n > N_1,有\(Cf(n) \leq C_1 \cdot f(n)\)。
我們可以選取\(C_1 = C\),此時我們得到\(Cf(n) \leq C \cdot f(n)\)。這個條件對所有n都成立,所以我們可以取\(N_1 = 1\)。
現在我們已經找到了正常數\(C_1\)和正整數\(N_1\),使得對所有n > N_1,有\(Cf(n) \leq C_1 \cdot f(n)\)。因此,我們可以得出\(h(n) = Cf(n) = O(f(n))\)。
5,如果 \(f = O(g)\), 那麼 \(g = \Omega(f)\)
如果\(f = O(g)\),那麼我們可以得出\(g = \Omega(f)\),因爲f(n)的增長速度被g(n)所限制,同時g(n)的增長速度至少是f(n)。換句話說,當f(n)是O(g(n))時,我們可以得出g(n)是函數f(n)的一個漸進下界。
6,如果 \(f = O(g)\), \(g = O(f)\), 那麼 \(f = \Theta(g)\)
根據大Θ符號的定義,如果存在兩個正常數\(C_1\)和\(C_2\)以及一個正整數\(N\),使得對所有\(n > N\),有\(C_1 \cdot g(n) \leq f(n) \leq C_2 \cdot g(n)\),那麼我們可以說\(f = \Theta(g)\)。
由於\(f = O(g)\)和\(g = O(f)\),我們可以找到一個整數\(N = \max(N_1, N_2)\),使得當\(n > N\)時,\(C_1 \cdot g(n) \leq f(n)\)以及\(C_2 \cdot f(n) \geq g(n)\)。這意味着我們已經滿足了大Θ符號的條件。因此,我們可以得出結論:\(f = \Theta(g)\)。
7,如果 \(f = O(g)\), \(f = \Omega(g)\), 那麼 \(f = \Theta(g)\)
- 如果\(f = O(g)\),那麼根據大O符號的定義,存在一個正常數\(C_1\)和一個正整數\(N_1\),使得對所有\(n > N_1\),有\(f(n) \leq C_1 \cdot g(n)\)。這意味着函數f(n)的增長速度被函數\(C_1 \cdot g(n)\)所限制,即f(n)在漸進意義上小於等於g(n)。
- 如果\(f = \Omega(g)\),那麼根據大Ω符號的定義,存在一個正常數\(C_2\)和一個正整數\(N_2\),使得對所有\(n > N_2\),有\(f(n) \geq C_2 \cdot g(n)\)。這意味着函數f(n)的增長速度至少是函數\(C_2 \cdot g(n)\),即f(n)在漸進意義上大於等於g(n)。
現在我們知道\(f = O(g)\)且\(f = \Omega(g)\),所以我們可以說\(f(n)\)和\(g(n)\)在漸進意義上是相互約束的。換句話說,f(n)和g(n)在漸進意義上既不快於也不慢於彼此。
5,一般有三種估計算法時間複雜度函數的方法:迭代次數估計(循環體的循環次數)、基本操作次數估計(在差一個常數倍數情況下出現頻度最高的基本運算)、遞歸函數法(用遞歸函數來表達時間複雜度函數)。請用上述方法估計下列算法的時間複雜度函數的漸近階。
Algorithm A Count
\(Input\) \(A\) \(positive\) \(integer\) \(n\)
\(Output\) \(count\) \(=\) \(number\) \(of\) \(times\) \(that\) \(step\) \(5\) \(is\) \(executed\)
\(\quad count\) \(\gets\) \(0\)
\(\quad for\) \(i\) \(\gets\) \(1\) \(to\) \(n\)
\(\quad \quad m\) \(\gets\) \(\left\lfloor{\frac{n}{i}}\right\rfloor\)
\(\quad \quad for\) \(j\) \(\gets\) \(1\) \(to\) \(m\)
\(\quad \quad \quad count\) \(\gets\) \(count\) \(+\) \(1\)
\(\quad \quad endfor\)
\(\quad endfor\)
\(return\) \(count\)
請統計迭代次數作爲時間複雜度, 並估計漸近階。
經過統計,得到了迭代次數\(T(n)=\sum\limits_{i=1}^{n} \lfloor \frac{n}{i} \rfloor\)
則有\(T(n)≤ n\sum\limits_{i=1}^{n} \frac{1}{i} ≤ n\log(n-1)\)
又有\(\lfloor \frac{n}{i}\rfloor>\frac{n}{i} - 1\)
則有\(T(n)≥-n + n\sum\limits_{i=1}^n \frac{1}{i}≥-n + n \log(n-1)\)
則有\(T(n) = O(n\log n)\)
Algorithm B ModifyInsertionSort
\(Input\) \(An\) \(array\) \(of\) \(A[1..n]\) \(of\) \(n\) \(elements\)
\(Output\) \(A[1..n]\) \(sorted\) \(in\) \(nondecreasing\) \(order\)
\(\quad for\) \(i\) \(\gets\) \(2\) \(to\) \(n\)
\(\quad \quad x\) \(\gets\) \(A[i]\)
\(\quad \quad k\) \(\gets\) \(ModifyBinarySearch\) \((A\left[1..i\right], x)\)
\(\quad \quad for\) \(j\) \(\gets\) \(i-1\) \(downto\) \(k\)
\(\quad \quad \quad A[j+1]\) \(\gets\) \(A[j]\)
\(\quad \quad endfor\)
\(\quad \quad A[k]\) \(\gets\) \(x\)
\(\quad endfor\)
其中\(ModifyBinarySearch(A\left[1..i\right],x)\)是改進的二分查找函數,無論x是否在\(A\left[1..i\right]\)中,它返回\(A\left[1..i\right]\)中比x小的元素個數加1。
請分別用\(ModifyBinarySearch(A\left[1..i\right],x)\)中的比較運算和語句5中的賦值運算作爲基本運算統計算法的時間複雜度,並給出漸近階。你認爲哪個漸近階是正確的?
假設序列A中,每個元素的值都相等。
則有k一直等於1。
則迭代次數\(T(n) = \sum\limits_{i=1}^{n} \log i + i\)
求完漸進得到\(T(n) = O(n^2)\)