1 / 24

第 1 章 基本數學背景與 C 程式背景 簡介

第 1 章 基本數學背景與 C 程式背景 簡介. 1.1 漸近式 O(f(n)),Ω(f(n)) 與 θ(f(n)). 粗略估計程式執行時所佔用的時間與記憶體空間大小的方式 , 其定義如下 :. 設 函數 f, g 為定義於自然數  的實值函數 . f, g:   . 定義 1: g(n) = O( f ( n) ) iff there are two positive constants c and n o such that

leone
Download Presentation

第 1 章 基本數學背景與 C 程式背景 簡介

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第 1 章 基本數學背景與 C 程式背景 簡介 1.1 漸近式 O(f(n)),Ω(f(n)) 與 θ(f(n)) 粗略估計程式執行時所佔用的時間與記憶體空間大小的方式, 其定義如下: 設函數 f, g 為定義於自然數  的實值函數. f, g:   . 定義 1:g(n) = O( f(n) )iff there are two positiveconstants c and n o such that |g(n) |  c | f(n) | for all n n o 我們稱函數 f(n) 為函數g(n) 的一個上界, 並可讀成函數g(n) 為 big-o of 函數 f(n) .

  2. 例 1: 2000 n 2 +10000 = O( n 2 ). 證明 : 取 c = 2001, N=101, 則當 n  N 時, c n 2 = 2001 n 2=2000 n 2 + n 2 2000 n 2 + 10000  0. 例 2: 1000 n log n + 10000 n + 50 = O( n 2 ). 證明 : 取 c = 1001, N=10001, 則當 n  N 時, c n 2 = 1001 n 2=1000 n 2 + n 2 =1000 n 2 + n  n 1000 n 2 + 10001  n > 1000 n log n + 10000 n + 50  0.

  3. 定理 1 :設函數fn = a m nm ... a 1 n a 0,a m > 0, 為一 m 階多項式函數, 則 f(n = O( nm ). 證明 : 令 c = (m+1)max{| a m|, | a m-1 |, …, | a 0|} 取 N = 1. 則, 當n  N 時, c nm | a m| nm | am-1 | nm-1  …  | a 0 |  | a m nma m-1 nm-1  … a0| = |f(n)|

  4. 註 1:O(1) 為一常數函數, 即 f(n) = c, n  . 註 2:O(1)< O(log n) < O(n)< O(n log n) < O(n2 ) < O(n3) < O(2n ) 註 3:我們亦可將 O(f(n)) 視為一集合, 其定義為 O(f(n)) = {g(n) |  c  0 and n o 0 |g(n)|  c |f(n)|  n n o } 註 4:因此, 註 3 可改成 O(1)  O(log n)  O(n)  O(n log n)  O( n2 ) O( n3 )O( 2n )

  5. 定義 2:g(n) = ( f(n) )iff there are two positiveconstants c and n o such that |g(n) |  c | f(n) | for all n n o 我們稱函數 f(n) 為函數g(n) 的一個下界, 並可讀成函數g(n) 為 big- omega of 函數 f(n) . 例 3: 2000 n 2 +10000 = ( n 2 ). 證明 : 取 c = 1, N= 0, 則當 n  N 時, 2000 n 2 + 10000  n 2 =c n 2  0.

  6. 例 4: 2000 n 2 +10000 = ( n log n ). 證明 : 取 c = 1, N= 1, 則當 n  N 時, 2000 n 2 + 10000  n 2  n log nc n log n  0.

  7. 定義 3:g(n) = ( f(n) )iff there are three positive constants c 1 , c 2 and n o such that c 1| f(n) |  |g(n) |  c 2| f(n) | for all n n o 我們稱函數 f(n) 與函數g(n) 為對等. 註 5: g(n) = ( f(n) )即 g(n) = O( f(n) )且 g(n) = ( f(n) ). 例 5: 2000 n 2 +10000 = ( n 2 ). 證明 : 由例 1 與 例 3, 可得 2000 n 2 +10000 = ( n 2 ).

  8. 1.2 數學遞迴關係與遞迴函數 數學遞迴關係及遞迴函數與 程式的遞迴函數有密切關係, 三者皆可用來表示同一件事, 只是所用的語言不同, 但是, 方式基本上是相似的. 經常用來說明數學遞迴關係的例子是 Fibonacci sequence. 一個 Fibonacci sequence(費氏數列) 是 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, …. 也就是說, 下一個費氏數是前兩個之和.

  9. 利用遞迴關係來表示該數列, 其關係式如下: 令 a n表第 n 個費氏數. 則 a 0 = 0, a 1 = 1, a n =a n  2 + a n  1, n  2. 以數學遞迴函數 f( n ) 表第 n 個費氏數. 則 f( 0 ) = 0, f( 1 ) = 1, f( n ) = f(n  2) + f(n  1), n  2.

  10. 欲以遞迴函數 f( n )求第4 個費氏數, 即求f(4), 其求法如下: f(4) = f(2) + f(3) = [f(0) + f(1)] + f(3) = [0 + f(1)] + f(3) = [0 + 1] + f(3) = 1 + f(3) = 1 + {f(1) + f(2)} = 1 + {1 + f(2)} = 1 + {1 + [f(0) + f(1)]} = 1 + {1 + [0 + f(1)]} = 1 + {1 + [0 + 1]} = 1 + {1 + 1} = 1 + 2 = 3

  11. f(4) f(3) f(2) f(0) f(1) f(1) f(2) f(0) f(1) 0 1 1 0 1 我們來看 f(4) 的解析樹如下: 此樹共有 9 個內點, 即執行函數 f(n) 共 9 次.

  12. 以t(n) 表示函數 f(n)執行的次數, 則 t(0) = 1, t(1) = 1, t(n) = t(n  2) + t(n  1) + 1, n  2. 因此, t(n) 的前 12 項為 1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, 287, …. 利用 generating function 或其他技巧, 我們可以得到 f(n)={ [(1+5)/2] n [(1 5)/2] n } / 5., n = 0, 1, 2, ….

  13. 1.3 C 程式迴圈與遞迴函數 本節將說明如何以 C 程式利用迴圈與遞迴函數來求第 n 個費氏數. 一般而言, 迴圈程式比遞迴函數較不易寫, 也較難懂. 但執行速度較快. 如果了解了數學上的遞迴關係與遞迴函數, C 程式的遞迴函數是相當容易寫 也較易懂. 但執行速度較慢. 其慢的基本原因是函數的呼叫, 牽扯到暫存器資料的儲存與復原. 返回地址的儲存與執行的復原, 等等額外工作. 有時也會遇到重複計算而浪費時間.

  14. 利用迴圈來計算第 n 個費氏數, 其程式如下: int f(int n){ int a0, a1, a2, i; if( n == 0 ) a2 = 0; else if( n == 1 ) a2 = 1; else { a0 = 0; a1 = 1; for( i=2; i<=n; i++) { a2 = a0 + a1; a0 = a1; a1 = a2;}} return a2;}

  15. 利用遞迴來計算第 n 個費氏數, 其程式如下: int f(int n){ if( n == 0 ) return 0; else if( n == 1 ) return 1; else return f(n-2)+f(n-1);}

  16. 已知第46 個費氏數是 1,836,311,903. 如果資料型態 int 為4 個 bytes, 則該數是我們所能求的最大費氏數. 如果是利用迴圈來計算第 46 個費氏數, 則迴圈共執行 45 次, 其執行所須時間, 遠少於一秒鐘. 但是, 如果是利用遞迴函數的方式來計算第 46 個費氏數, 則函數共呼叫了t(46) 次, 遠超過 1,836,311,903 次, 所需時間夠我們喝杯茶水.

  17. 我們再以例子來比較一下 C 程式的迴圈與遞迴程序. 考慮如何將 n 個數1, 2, …, n 依其排列順序列印出來. 如果 n = 3, 其排列順序列印出來的結果如下. 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1

  18. 其排列方式是: 依序固定前面 k 個數後, 將其餘 n  k 個數按相同方式依其排列順序一一列印. void permute(int n,int k,int a[MAXSIZE]){ int i, int b[MAXSIZE]; if (k == n) printOut(a, n); else { for(i=k; i<=n; i++){ swap(a[k], a[i]); copy(b, a, n); permute(n, k+1, b);}}}

  19. 以迴圈按 n 個數的排列順序方式來列印, 其程式如下: #include <stdio.h> #define MAXSIZE 30 void main( ) { int a[MAXSIZE], n, i, s; int b[MAXSIZE], m, j, t; int flag, temp; printf("Give me the size: "); scanf("%d", &n); for(i=1;i<=n;i++) a[i]=i; for(j=1;j<=n;j++) b[j]=0;

  20. while(1) { // get a new permutation // printOut(a, n); for(i=1;i<=n;i++) printf("%4d,", a[i]); printf("\n"); // Test for continuing the next step flag = 1; for(i=1; i<=n; i++) { if( (n-i+1) > a[i] ) { flag = 0; break; } //continue for next step } if(flag) break; // end of the loop

  21. //find next permutation b[1] = a[n]; m = 1; for(i=n-1; i>=1; i--) { flag = 0; for(j=1; j<=m; j++) { if(b[j]>a[i]) { flag = 1;// end of the inner and outer loop //swap a[i] and b[j] temp = a[i]; a[i] = b[j]; b[j] = temp;

  22. t=1; for(s=i+1; s<=n; s++) a[s] = b[t++]; break; }// if (b[j]>a[i]) }// for (j=1; j<=m; j++) if(flag) break; m++; b[m] = a[i]; } } }

  23. 以例來說明該程式是如何運作, 當n = 8, 而目前正列印出 1, 2, 3, 4, 8, 7, 6, 5 下一個將列印出的是 1, 2, 3, 5, 4, 6, 7, 8 我們採用的策略是利用兩個陣列a 與 b, 其內容變化如下:

  24. 陣列a 陣列b 1, 2, 3, 4, 8, 7, 6 6 > 5 5 1, 2, 3, 4, 8, 7 7 > 5,6 5, 6 1, 2, 3, 4, 8 8 > 5,6,7 5, 6, 7 1, 2, 3, 4 4 < 5 5, 6, 7, 8 現在因4 < 5, 所以將 4 與 5 對調, 再將陣列 b 的內容加入陣列 a, 即為下一個數列如下圖所示. 1, 2, 3, 5, 4, 6, 7, 8

More Related