algorithmics the discipline of algorithms. abu ja ’ far mohammed ibn musa al khowarizmi algorithm...

42
Algorithmi cs The discipline of algorit hms

Post on 19-Dec-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

AlgorithmicsThe discipline of algorithms

Abu Ja’far Mohammed ibn Musa al Khowarizmi Algorithm comes fr

om the name of a Persian, Abu Ja’far Mohammed ibn Musa al Khowarizmi (c. 825 A. D.).

Mu ammad ibn Mūsā al-Khwḥārizmī Mu ammad ibn Mūsā al-Khwārizmī (Arabic: ḥ

was a Persian mat (محمد بن موسى الخوارزميhematician, astronomer, astrologer and geographer. He was born around 780, in either Khwarizm or Baghdad, and died around 850.

His Algebra, the first book on the systematic solution of linear and quadratic equations. Consequently he is considered to be the father of algebra.

al-Khwarizmi 演算法 (algorithm) 名稱來自於” al-Khwarizmi” ,

這是一個約在西元 780 年出生於伊拉克 ( Iraq ) 巴格達 ( Baghdad ) 城的阿拉伯數學家阿爾‧可瓦里茲米(Abu Jafar Muhammad ibn Musa al-Khwarizmi) 名字的最後一部份,此數學家將印度所發明的十進位數字記號傳入阿拉伯地區 ( 稍後傳入歐洲並成為現今我們使用的數字記號 ) ,並且著有一本名為” ilm al jabr w’al-muqabala” 的書籍,此書有系統地討論一元二次方程的解法,啟發了代數學的發展。此書在 12 世紀被翻譯為拉丁文,名為 Algebra et Almucabala , (Algebra 源自阿拉伯書名中之 al jabr) ,而成為代數學 (Algebra) 一字的由來。

What is an algorithm (1/2) Any special method of solving a certain kind of pr

oblem -- Webster’s A precise method useable by a computer for the s

olution of a problem. -- Viewed by Computer Engineers

In mathematics and computing, an algorithm is a procedure (a finite set of well-defined instructions) for accomplishing some task which, given an initial state, will terminate in a defined end-state. -- WiKipedia

What is an algorithm (2/2)

The concept of an algorithm originated as a means of recording procedures for solving mathematical problems such as finding the common divisor of two numbers or multiplying two numbers.

The concept was formalized in 1936 through Alan Turing's Turing machines and Alonzo Church's lambda calculus, which in turn formed the foundation of computer science.

What is an algorithm (2/2)

An algorithm is composed of a set of steps for solving a specific problem. It should satisfy the following properties: Finiteness (the number of steps should be

finite) Definiteness (to compute 5/0 is not definite) Effectiveness (to compute 1/3 as an infinite

decimal is not effective) Zero or more inputs and one or more outputs Termination (OS is not an algorithm)

A recipe is an algorithm Informally, the concept of an algorithm is often illustrated by the exampl

e of a recipe. 梅焗肉排

材料:(4人份)一字排 12 兩鹹話梅 6-8 粒紅椒 2 隻中國芹菜 2 條洋蔥 1 小個紅谷米少許冰糖適量生抽適量 

做法:1. 話梅連一隻切角紅椒和紅谷米以六碗水煎至一碗水,隔渣保留汁及話梅備用。中國芹菜切段;洋蔥及另一隻紅椒切角,備用。2. 一字排洗淨,切件,加適量生粉拌勻,放滾油內炸至金黃香脆,瀝乾油備用。3. 取話梅及汁,加入生抽、冰糖煮滾,再加中國芹菜、紅椒角、洋蔥略煮約1 分鐘,放一字排燜焗約 2 分鐘至入味,埋少許生粉水即可。

A flowchart is an algorithm

A program is an algorithm1. import javax.swing.*;2. public class EuclidGCDApplet extends JApplet{3. public void init( ){4. int 整數 m, 整數 n, 最大公因數 ;5. String 輸入字串 1, 輸入字串 2, 顯示字串 ;6. 輸入字串 1=JOptionPane.showInputDialog(" 請輸入正整數 m ? ");7. 輸入字串 2=JOptionPane.showInputDialog(" 請輸入正整數 n ? ");8. 整數 m=Integer.parseInt( 輸入字串 1);9. 整數 n=Integer.parseInt( 輸入字串 2);10. 最大公因數 =EuclidGCD( 整數 m, 整數 n);11. 顯示字串 =" 整數 "+ 整數 m+" 與整數 "+ 整數 n+" 的最大公因數為 "+ 最大公

因數 ;12. JOptionPane.showMessageDialog(null, 顯示字串 );13. } // 方法 :init() 定義區塊結束

Representation of Algorithms

一般我們使用自然語言 ( 中文或英文等語言 ) 、流程圖 (flow chart) 、虛擬碼 (pseudo code) 或高階程式語言 (high level programming language) 來表示演算法。

例如,以下的例子使用自然語言 ( 中文與英文 )描述一個古老的演算法 歐幾里德 (Euclid)GCD 演算法。

歐幾里德 (Euclid)GCD 演算法大約在西元前 300 年由希臘數學家歐幾里德提出,可用於求出二個整數的最大公因數 (GCD, Greatest Common Divisor) 。

Euclid GCD Algorithm

Euclid GCD 演算法 :問題:已知二個正整數 m 及 n ,找出此二數的最大公因數 ( 也就是能同時整除 m 及 n 的最大正整數 )解法:E1.[ 找出餘數 ] 求出 m 除以 n 的餘數,並記錄於 r 。

E2.[ 餘數為 0 嗎? ] 如果 r=0 則停止,輸出 n 為 GCD 。E3.[ 互換二數 ] 設定 m=n,n=r ,並跳至步驟 E1 。

Pseudo Code 虛擬碼以一種混雜著自然語言與高階程式語言結構的

方式來描述演算法,試圖達到簡潔易讀、容易分析,而且也容易轉換為高階程式語言的目的。

以下介紹Goodrich 及 Tamassia 在「 Data Structures and Algorithms in JAVA」一書中所提出的虛擬碼格式 :

Pseudo Code 宣告:以 Algorithm 方法名稱 (參數 1,參數 2,…):

來宣告一個演算法並指明其參數。例如, Algorithm Euclid-GCD(m, n): 表示我們要定義一個具有兩個參數 m 及 n 而名稱為 Euclid-GCD 的演算法,。

設定動作:以 ← 表示,用以將一個算式之值存入某一個變數中。例如, m←3+8 表示要將 3+8 的值存入變數 m 中。

相等比較:以 = 表示,可以比較二個算式是否等值。例如, m=3+8 表示要比較 3+8 的值是否與變數 m的值相等。

Pseudo Code 決策結構:以 if 條件 then 條件為真的動作 else 條

件為偽的動作 來表示,並以縮排來表示所有包含在條件為真的動作及條件為偽的動作中的所有指令。例如, if m=3+8 then

b←3+8else c←3+8表示當變數 m 的值與 3+8相等時,會執行將 3+8 的值存入變

數 b 的動作,否則即執行將 3+8 的值存入變數 c 的動作。

Pseudo Code while迴圈:以 while 條件 do迴圈指令 來表示,

並以縮排來表示所有包含在迴圈中的所有指令。當條件成立時,會持續執行所有包含在迴圈中的指令。例如, while m=3+8 do

b←3+8 c←3+8表示當變數 m 的值與 3+8相等時,會持續執行將 3+

8 的值存入變數 b與將 3+8 的值存入變數 c 的動作。

Pseudo Code repeat迴圈:以 repeat迴圈指令 until 條件 來表示,並以縮排來表示所有包含在迴圈中的所有指令。此虛擬碼會持續執行所有包含在迴圈值中的指令,直到條件成立為止。例如, repeat

b←3+8 c←3+8until m=3+8表示會持續執行將 3+8 的值存入變數 b與將 3+8 的值存入變

數 c 的動作,直到變數 m 的值與 3+8相等為止。

Pseudo Code for迴圈:以 for迴圈範圍及變動 do 迴圈指令 來表示,並以縮排來表示所有包含在迴圈中的所有指令。例如, for i←3 to 8 do

b←3+8 c←3+8表示在變數 i 的值由 3到 8( 即 i 為 3 、 4、 5 、 6 、

7 、 8) 的情況下,會持續執行將 3+8 的值存入變數 b與將 3+8 的值存入變數 c 的動作。

Pseudo Code 陣列元素索引:以 A[i] 代表陣列 A 中註標 (index)

為 i 的元素,一個有 n 個元素的陣列,其元素註標為0,1,…,n-1 。例如, A[5] 表示陣列 A 中註標為 5 的元素。

方法呼叫:以 物件 . 方法 (參數… ) 來代表。注意,當物件是明確的時候,物件可以省略不寫。例如, Math.random() 表示要呼叫Math物件無參數的 random() 方法。

方法返回 : 以 return 方法返回值 來代表。例如, return 3+8 表示要傳回 3+8 之值。

Pseudo Code for Euclid Alg.

Algorithm Euclid_GCD(m, n):Input: two integers m and nOutput: GCD of m and nr←m%nwhile r0 do m←n n←r r←m%nreturn n

Java Method for Euclid Alg. 使用虛擬碼表示演算法可以方便演算法的分析,增加演算法

的易讀性,並且可以方便的將演算法轉變成可以直接在電腦上執行的程式語言程式碼。例如,以下為將以虛擬碼表示的歐幾里德演算法轉換為 Java 語言程式碼的例子:int Euclid_GCD(int m, int n) { int r=m%n; while (r!=0) { m=n; n=r; r=m%n; } return n;}

Java Applet for Euclid Alg.範例程式 (檔名: EuclidGCDApplet.java)1. // 檔名 :EuclidGCDApplet.java 2. // 說明 : 此程式可輸入二個整數,並以歐幾里得 GCD 演算法求其最大公

因數 (GCD)3. import javax.swing.*;4. public class EuclidGCDApplet extends JApplet{5. public void init( ){6. int 整數 m, 整數 n, 最大公因數 ;7. String 輸入字串 1, 輸入字串 2, 顯示字串 ;8. 輸入字串 1=JOptionPane.showInputDialog(" 請輸入正整數

m ? ");

Java Applet for Euclid Alg.9. 輸入字串 2=JOptionPane.showInputDialog(" 請輸入正整數

n ? ");10. 整數 m=Integer.parseInt( 輸入字串 1);11. 整數 n=Integer.parseInt( 輸入字串 2);11. 最大公因數 =EuclidGCD( 整數 m, 整數 n);12. 顯示字串 =" 整數 "+ 整數 m+" 與整數 "+ 整數 n+" 的最大公因數

為 "+ 最大公因數 ;13. JOptionPane.showMessageDialog(null, 顯示字串 );14. } // 方法 :init() 定義區塊結束

Java Applet for Euclid Alg.11. static int EuclidGCD(int m, int n) {12. int r=m%n;17. while (r!=0) {18. m=n;19. n=r;20. r=m%n;21. }22. return n;23. } // 方法 :EuclidGCD() 定義區塊結束24. } // 類別 :EuclidGCDApplet 定義區塊結束

Java Applet for Euclid Alg.網頁檔案 (檔名: EuclidGCDApplet.html)1. <html>2. <h1>EuclidGCDApplet 執行中 <h1>3. <applet code="EuclidGCDApplet.class" width=350

height=100>4. </applet>5. </html>執行結果( 以瀏覽器載入檔案: EuclidGCDApplet.html)

Correctness and Efficiency

設計一個演算法,首先要考慮的就是正確性 (correctness) ,也就是演算法是否能產生正確的結果,在達到正確性的要求之後,我們就要特別考慮演算法的效能 (efficiency) 了,也就是要考慮演算法是否能夠有效率的的執行。一般而言,若是數個演算法均能夠產生相同且正確的結果,則我們大都以有效性來衡量其優劣。

An Alg. for Testing Primes

我們可以看出,輸入大於 2 的任意正整數 n ,若 n 是質數,則演算法 Prime1需要執行整數除法求餘數 (n%i)動作與整數比較 ((n%i)=0)動作 n-2 次之後,才可以知道 n 是質數。另外,若 n不是質值,則演算法 Prime1只要執行整數除法求餘數與整數比較動作 1 次,就可以知道 n不是質數了。

Algorithm Prime1(n):Input: 一個大於 2 的正整數 nOutput:true 或 false( 表示 n 是質數或不是質數 )for i←2 to n-1 do if (n%i)=0 then return falsereturn true

A Theorem for Testing Primes

n

[ 定理 ]對於任意的大於 2 的整數 n 而言,若所有小於或等於 的整數 (1除外 ) 都無法整除 n ,則 n 是一個質數。

Hint 每個整數 n 的因數都是成對出現的,例如, 16 的因數

為 1 與 16(1*16=16) 、 2 與 8(2*8=16) 、 4 與 4(4*4=16) 。成對出現的因數中,一個會小於等於 n 的平方根,而另一個則是大於等於 n 的平方根,因此,我們只要檢查小於等於 n 的平方根的所有不等於 1 的整數中是否有 n 的因數就可以知道 n 是不是質數了。

The Other Alg. for Testing Primes

我們根據上列的定理設計出另一個演算法 Prime2 :

Prime1Applet

範例程式 (檔名: Prime1Applet.java)1. // 檔名 :Prime1Applet.java 2. // 說明 : 此程式可輸入一個大於 2 的整數,並判斷此整數是否為質數 (pri

me number)3. import javax.swing.*;4. public class Prime1Applet extends JApplet {5. public void init(){6. int 整數 n;7. String 輸入字串 , 顯示字串 ;8. 輸入字串 =JOptionPane.showInputDialog(" 請輸入大於 2 的整數

n ? ");

Prime1Applet9. 整數 n=Integer.parseInt( 輸入字串 );10. boolean 是質數 ;11. long 演算法執行前時間 =System.currentTimeMillis();12. 是質數 =Prime1( 整數 n);13. long 演算法執行後時間 =System.currentTimeMillis();14. long 演算法執行時間 = 演算法執行後時間 - 演算法執行前時間 ;15. if( 是質數 ) 顯示字串 = 整數 n+" 是質數 ";16. else 顯示字串 = 整數 n+" 不是質數 ";17. 顯示字串 +=("\n 演算法執行時間為 "+ 演算法執行時間 +" 毫秒 (mill

i-seconds)");

Prime1Applet

18. JOptionPane.showMessageDialog(null, 顯示字串 );19. } // 方法 :init() 定義區塊結束20. boolean Prime1(int n) {21. for (int i=2;i<=n-1;++i) 22. if (n%i==0) return false;23. return true;24. }25. } // 類別 :Prime1Applet 定義區塊結束

Prime1Applet

網頁檔案 (檔名: Prime1Applet.html)1. <html>2. <h1>Prime1Applet 執行中 <h1>3. <applet code="Prime1Applet.class" width=350 heig

ht=100>4. </applet>5. </html>執行結果( 以瀏覽器載入檔案: Prime1Applet.html)

Prime2Applet範例程式 (檔名: Prime2Applet.java)1. // 檔名 :Prime2Applet.java 2. // 說明 : 此程式可輸入一個大於 2 的整數,並判斷此整數是否為質數 (pri

me number)3. import javax.swing.*;4. public class Prime2Applet extends JApplet {5. public void init(){6. int 整數 n;7. String 輸入字串 , 顯示字串 ;8. 輸入字串 =JOptionPane.showInputDialog(" 請輸入大於 2 的整數

n ? ");9. 整數 n=Integer.parseInt( 輸入字串 );

Prime2Applet10. boolean 是質數 ;11. long 演算法執行前時間 =System.currentTimeMillis();12. 是質數 =Prime2( 整數 n);13. long 演算法執行後時間 =System.currentTimeMillis();14. long 演算法執行時間 = 演算法執行後時間 - 演算法執行前時間 ;15. if( 是質數 ) 顯示字串 = 整數 n+" 是質數 ";16. else 顯示字串 = 整數 n+" 不是質數 ";17. 顯示字串 +=("\n 演算法執行時間為 "+ 演算法執行時間 +" 毫秒 (mill

i-seconds)");

Prime2Applet

18. JOptionPane.showMessageDialog(null, 顯示字串 );19. } // 方法 :init() 定義區塊結束20. boolean Prime2(int n) {21. for (int i=2;i<=Math.sqrt(n);++i) 22. if (n%i==0) return false;23. return true;24. }25. } // 類別 :Prime2Applet 定義區塊結束

Prime2Applet

網頁檔案 (檔名: Prime2Applet.html)1. <html>2. <h1>Prime2Applet 執行中 <h1>3. <applet code="Prime2Applet.class" width=350 heigh

t=100>4. </applet>5. </html>

執行結果( 以瀏覽器載入檔案: Prime2Applet.html)

Q&A

範例程式 1-3.質數檢查演算法Prime2 於瀏覽器中執行情形。

範例程式 1-2.質數檢查演算法Prime1 於瀏覽器中執行情形。

Result