data structure lesson02

19
23 แผนการสอนประจําบทเรียน รายชื ่ออาจารยผู จัดทํา สุณี รักษาเกียรติศักดิ์ และ สมชาย ประสิทธิ ์จูตระกูล หัวขอของเนื้อหา ตอนที่ 2.1 การสรางและการใชขอมูลแบบคัดยอ (2 คาบ) เรื ่องที 2.1.1 การสรางชนิดขอมูลแบบคัดยอ เรื ่องที 2.1.2 การใชชนิดขอมูลแบบคัดยอ ตอนที่ 2.2 มาตรวัดประสิทธิภาพของอัลกอริทึม (1 คาบ) เรื ่องที 2.2.1 แนวคิด เรื ่องที 2.2.2 การนับจํานวนครั้งของการใชงานคําสั่ง เรื ่องที 2.2.3 คําสั ่งมาตรเวลา เรื ่องที 2.2.4 การวิเคราะหเชิงเสนกํากับ เรื ่องที 2.2.5 สัญกรณโอใหญ เรื ่องที 2.2.6 ตัวอยางการวิเคราะหโปรแกรมเชิงเสนกํากับ แนวคิด 1. ในตอนที่ 1.3 ของบทเรียนที่ 1 เราไดเห็นหลักการของการสรางชนิดขอมูลตามความตองการ ของเรา โดยใชหลักการของชนิดของขอมูลแบบคัดยอ ซึ ่งมีวิธีการดําเนินการ 2 ขั้นตอนใหญๆ ขั้นตอนแรกคือ การกําหนดคุณลักษณะเฉพาะของชนิดของขอมูลที ่เราตองการสรางใหชัดเจน และขั้นตอนที2 คือการสรางชนิดขอมูลตามคุณลักษณะเฉพาะที ่กําหนด โดยในตอนที่ 1.3 ของบทเรียนที่ 1 ไดใหตัวอยางคุณลักษณะเฉพาะของชนิดขอมูลที่ตองการสราง 2 ชนิด คือ ชนิดขอมูล “Color” และชนิดขอมูล “LetterString” 2. ในตอนที่ 2.1 ของบทเรียนที่ 2 นี จะไดนําเสนอวิธีในการสรางชนิดขอมูล “Color” และ “LetterString” ตามคุณลักษณะเฉพาะที ่กําหนดในตอนที 1.3 ของบทเรียนที่ 1 โดยใช UNIT ของ Turbo Pascal เปนเครื ่องมือ พรอมทั้งเขียนโปรแกรมเพื่อทดสอบวาชนิดขอมูลที่เราสราง ขึ ้นสามารถทํางานไดถูกตอง 3. ประสิทธิภาพของการดําเนินงานที ่สราง ขึ้นอยูกับการแทนที่ขอมูลที่เลือกใชและอัลกอริทึมใน สราง ซึ่งมาตรวัดอันหนึ่งที่นิยมใชในการวัดประสิทธิภาพของอัลกอริทึม คือ สัญกรณโอใหญ (function big O)

Upload: suhatt-jantorn

Post on 20-Mar-2016

214 views

Category:

Documents


0 download

DESCRIPTION

ตอนที่ 2.1 การสรางและการใชขอมูลแบบคัดยอ (2 คาบ) เรื่องที่ 2.1.1 การสรางชนิดขอมูลแบบคัดยอ เรื่องที่ 2.1.2 การใชชนิดขอมูลแบบคัดยอ แผนการสอนประจําบทเรียน หัวขอของเนื้อหา ประเมินผล 1. ประเมินผลจากกิจกรรมที่ทํา 2. ประเมินผลจากคําถามทายบทเรียน เอกสารประกอบการสอน 1. เอกสารชุดวิชา ตอนที่ 2.1 การสรางและการใชขอมูลแบบคัดยอ เรื่องที่ 2.1.1 การสรางชนิดขอมูลแบบคัดยอ 27 โปรแ

TRANSCRIPT

Page 1: data structure lesson02

23

แผนการสอนประจําบทเรียน

รายช่ืออาจารยผูจัดทํา สุณี รักษาเกียรติศักดิ ์และ สมชาย ประสิทธ์ิจูตระกูล

หัวขอของเนื้อหา

ตอนที ่2.1 การสรางและการใชขอมูลแบบคัดยอ (2 คาบ) เร่ืองท่ี 2.1.1 การสรางชนิดขอมูลแบบคัดยอ เร่ืองท่ี 2.1.2 การใชชนิดขอมูลแบบคัดยอ

ตอนที ่2.2 มาตรวัดประสิทธิภาพของอัลกอริทึม (1 คาบ) เร่ืองท่ี 2.2.1 แนวคิด เร่ืองท่ี 2.2.2 การนับจํานวนครั้งของการใชงานคําสั่ง เร่ืองท่ี 2.2.3 คําส่ังมาตรเวลา เร่ืองท่ี 2.2.4 การวิเคราะหเชิงเสนกํากับ เร่ืองท่ี 2.2.5 สัญกรณโอใหญ เร่ืองท่ี 2.2.6 ตัวอยางการวิเคราะหโปรแกรมเชิงเสนกํากับ

แนวคดิ 1. ในตอนที่ 1.3 ของบทเรียนที่ 1 เราไดเห็นหลักการของการสรางชนิดขอมูลตามความตองการของเรา โดยใชหลักการของชนิดของขอมูลแบบคัดยอ ซ่ึงมีวิธีการดําเนินการ 2 ขั้นตอนใหญๆ ขั้นตอนแรกคือ การกําหนดคุณลักษณะเฉพาะของชนิดของขอมูลท่ีเราตองการสรางใหชัดเจน และขั้นตอนที่ 2 คือการสรางชนิดขอมูลตามคุณลักษณะเฉพาะท่ีกําหนด โดยในตอนที ่ 1.3 ของบทเรียนที่ 1 ไดใหตัวอยางคุณลักษณะเฉพาะของชนิดขอมูลที่ตองการสราง 2 ชนิด คือ ชนิดขอมูล “Color” และชนิดขอมูล “LetterString”

2. ในตอนที่ 2.1 ของบทเรียนที่ 2 น้ี จะไดนําเสนอวิธีในการสรางชนิดขอมูล “Color” และ “LetterString” ตามคุณลักษณะเฉพาะท่ีกําหนดในตอนท่ี 1.3 ของบทเรียนที่ 1 โดยใช UNIT ของ Turbo Pascal เปนเคร่ืองมือ พรอมทั้งเขียนโปรแกรมเพื่อทดสอบวาชนิดขอมูลที่เราสรางข้ึนสามารถทํางานไดถูกตอง

3. ประสิทธิภาพของการดําเนินงานท่ีสราง ขึ้นอยูกับการแทนที่ขอมูลที่เลือกใชและอัลกอริทึมในสราง ซึ่งมาตรวัดอันหนึ่งที่นิยมใชในการวัดประสิทธิภาพของอัลกอริทึม คือ สัญกรณโอใหญ (function big O)

Page 2: data structure lesson02

24

วัตถุประสงค หลังจากศึกษาบทเรียนที่ 2 แลว นักศึกษาสามารถ 1. เห็นตัวอยางและเขาใจวิธีการสรางและการทดสอบการใช ชนิดขอมูลแบบคัดยอ และสามารถประยุกตใชได

2. เขาใจการทํางานของมาตรวัดประสิทธิภาพของอัลกอริทึมได

กิจกรรมการเรียนการสอน กิจกรรมท่ีนักศึกษาตองทําสําหรับการเรียนการสอน ไดแก 1. ศึกษาเอกสารชดุวิชา/โฮมเพจชุดวิชา ตอนที่ 2.1 และตอนที ่2.2 2. ทํากิจกรรมของบทเรียนที่ 2 3. ทําแบบประเมินผลของบทเรียนที่ 2

เอกสารประกอบการสอน 1. เอกสารชดุวิชา

สื่อการสอน 1. โฮมเพจชุดวิชา 2. สไลดประกอบการบรรยาย (Powerpoint) 3. โปรแกรมคอมพิวเตอร

ประเมินผล 1. ประเมินผลจากกิจกรรมที่ทํา 2. ประเมินผลจากคําถามทายบทเรียน

Page 3: data structure lesson02

25

ตอนท่ี 2.1 การสรางและการใชขอมูลแบบคัดยอ

หัวเรื่อง เร่ืองท่ี 2.1.1 การสรางชนิดขอมูลแบบคัดยอเชิงเด่ียว Color เร่ืองท่ี 2.1.2 การใชชนิดขอมูลแบบคัดยอเชิงเดี่ยว Color เร่ืองท่ี 2.1.3 การสรางชนิดขอมูลแบบคัดยอเชิงโครงสราง LetterString เร่ืองท่ี 2.1.4 การใชชนิดขอมูลแบบคัดยอเชิงโครงสราง LetterString

แนวคดิ 1. หลักการสรางชนิดขอมูลตามความตองการของเรา โดยใชหลักการของชนิดของขอมูลแบบคัดยอ มีวิธีการดําเนินการ 2 ขั้นตอนใหญ ๆ ขั้นตอนแรกคือ การกําหนดคุณลักษณะเฉพาะของชนิดของขอมูลที่เราตองการสรางใหชัดเจน และขั้นตอนที่ 2 คือการสรางชนิดขอมูลตามคุณลักษณะเฉพาะท่ีกําหนด

2. UNIT ของ Turbo Pascal สามารถใชเปนเครื่องมือในการสรางชนิดขอมูลแบบคัดยอตามคุณลักษณะเฉพาะท่ีกําหนดไวแลว เมื่อสรางแลวเราตองเขียนโปรแกรมเพื่อทดสอบวาชนิดขอมูลที่เราสรางข้ึนสามารถทํางานไดถูกตอง

วัตถุประสงค หลังจากที่ศึกษาตอนที่ 2.1 แลว นักศึกษาสามารถ 1. เห็นตัวอยางและเขาใจวิธีการสรางและการทดสอบการใชชนิดขอมูลแบบคัดยอ ชนิด “Color” และชนิด “LetterString”

2. สามารถประยุกตวิธีการไปใชได ในการสรางและทดสอบชนิดขอมูลแบบอ่ืน ๆ

เรื่องที่ 2.1.1 การสรางชนิดขอมูลแบบคัดยอ

การสรางชนิดขอมูลแบบคัดยอเชิงเดี่ยว Color

ตามคุณลักษณะเฉพาะที่กําหนดของชนิดขอมูลแบบคัดยอ “Color” ในเรื่องที่ 1.3.1 ของบทเรียนที่ 1 น้ัน หากเราตองการจะสรางชนิดขอมลู “Color” โดยใช Turbo Pascal เปนเคร่ืองมือ เราจะตองนึกถึงการดําเนินการ 2 สวน สวนที่ 1 คือ การเลือกการแทนท่ีขอมูลของ domain ของ Color ซึ่งเราอาจจะใชขอมูลชนิด enumerated ในภาษาปาสคาลได เม่ือเลือกการแทนท่ีขอมูลแลว เราก็สามารถจะสรางการดําเนินงานตาง ๆ ตามท่ีระบุในคุณลักษณะเฉพาะของ “Color” ได ดังตัวอยางของโปรแกรม 2.1

Page 4: data structure lesson02

26

คําอธิบายโปรแกรม 2.1 UNIT ในปาสคาลจะแบงเปนสองสวน สวนแรกเราเรียกวาสวนของ INTERFACE ซ่ึงก็คือสวนท่ีจะ

ติดตอกับผูใช (สวนซึ่งผูใชมองเห็น) ซึ่งประกอบดวยการแทนที่ขอมูลซึ่งในที่นี้ คือ Color ในบรรทัดท่ี 5 และการดําเนินงานท่ีสามารถทําไดกับ Color ไดแก Mix, Primary, Form ในบรรทัดท่ี 6, 7, 8 ตามลําดับ สวนที่สองเราเรียกวาสวนของ IMPLEMENTATION จะเปนสวนรายละเอียดของการสรางการดําเนินงานซ่ึงสวนน้ีจะเปนสวนที่ผูใชจะมองไมเห็น (information hiding)

ในหลักการของขอมูลแบบคัดยอนั้นจริง ๆ แลวการแทนที่ขอมูลควรจะเปนสวนที่ซอนจากผูใชดวย แต UNIT ของ TURBO PASCAL ยังไมสามารถซอนจากผูใชไดเพราะกําหนดอยูในสวนของ INTERFACE ทําใหยังไมาสามารถสนับสนุนคุณสมบัติของ integrity ไดอยางสมบูรณ ภาษาโปรแกรมในยุคที่ 3 ท่ีสนับสนุนการทํางานของหลักการของขอมูลแบบคัดยอคือภาษา Ada

การสรางชนิดขอมูลแบบคัดยอเชิงโครงสราง Letterstring

เราสามารถสรางชนิดขอมูลแบบคัดยอ Letterstring ไดดวยวิธีการทํานองเดียวกันกับการสรางชนิดขอมูลแบบคัดยอ Color น่ันคือ การเลือกการแทนท่ีขอมูลของ Letterstring ซึ่งอาจจะใชแถวลําดับหรืออะเรยก็ได หลังจากน้ันก็สรางการดําเนินงานตาง ๆ ของ Letterstring

กิจกรรม 2.1 ฝกการสรางชนิดขอมูลแบบคัดยอ 1. จงคอมไพล UNIT ColorU ตามตัวอยาง และตั้งชื่อไฟลชื่อ ColorU.pas เม่ือคอมไพลแลวและ

ไมเกิด error ระบบจะสราง object code ไฟลชื่อ ColorU.TPU ใหในไดเร็กทอรีเดียวกับ ColorU.pas 2. จงสราง UNIT StingU ตามคุณลักษณะเฉพาะ 2.2 และตั้งชื่อไฟลชื่อ StringU.pas

Page 5: data structure lesson02

27

UNIT ColorU; 1{**************************} 2INTERFACE 3{**************************} 4TYPE Color=(Red,Blue,Yellow,Green,Violet,Orange); 5FUNCTION Mix(C1,C2:Color):Color; 6

FUNCTION Primary(C:Color):boolean; 7

PROCEDURE Form(C:Color;VAR C1,C2:Color); 8

{**************************} 9

IMPLEMENTATION 10

{**************************} 11

FUNCTION Mix(C1,C2:Color):Color; 12

BEGIN 13

IF ((C1=Red)and(C2=Yellow))or((C1=Yellow)and(C2=Red)) THEN 14

Mix:=Orange 15ELSE IF ((C1=Red)and(C2=Blue))or((C1=Blue)and(C2=Red)) THEN 16

Mix:=Violet 17ELSE IF ((C1=Yellow)and(C2=Blue))or((C1=Blue)and(C2=Yellow))18

THEN Mix:=Green 19END; 20

21

FUNCTION Primary(C:Color):boolean; 22

BEGIN 23

IF (C=Red)or(C=Yellow)or(C=Blue) THEN Primary:=True 24

ELSE Primary:=False; 25

26

END; 27

28

PROCEDURE Form(C:Color;VAR C1,C2:Color); 29

BEGIN 30

IF C=Orange THEN 31

BEGIN 32

C1:=Red; C2:=Yellow; 33

END 34

ELSE IF C=Green THEN 35

BEGIN 36

C1:=Yellow; C2:=Blue; 37

END 38

ELSE IF C=Violet THEN 39

BEGIN 40

C1:=Red; C2:=Blue; 41

END; 42

END; 43

44

END. 45

โปรแกรม 2.1 การสรางขอมูลแบบคัดยอชนิด “Color”

Page 6: data structure lesson02

28

เรื่องที่ 2.1.2 การใชชนิดขอมูลแบบคัดยอเชิงเดี่ยว Color

UNIT เปรียบเสมือนชนิดขอมูลท่ีเราสรางข้ึนมาเปน library และผูอ่ืนสามารถนําไปใชได ดังน้ันเพ่ือใหแนใจวา UNIT ท่ีเราสรางข้ึนมาถูกตอง เราตองมีการทดสอบ (ซ่ึงเปรียบเสมือนเปนผูใช) ดังนั้นผูใชเพียงแตทราบวาชนิดขอมูลคัดยอที่สรางมานี้มีชนิดเปน Color ซ่ึงเปน enumerated type ประกอบดวยขอมลู 6 ตัว คือ Red, Blue,Yellow,Green,Violet,Orange และมีการดําเนินงานใหใชได 3 การดําเนินงานคือ Mix, Primary, และ Form ซึ่งมีรูปแบบการใชดังปรากฎในบรรทัดที่ 6, 7, 8 เง่ือนไขและผลลัพธในการดําเนินงานดังท่ีกําหนดไวในคุณลักษณะเฉพาะ ผูใชสามารถเรียกการดําเนินงานทั้งสามนี้ไปใชได โดยไมตองสนใจในรายละเอียดวาการดําเนินงานเหลาน้ีสรางมาไดอยางไร (mplementation independence)

ตัวอยางโปรแกรมการทดสอบการดําเนินงานดังแสดงในโปรแกรม 2.2 PROGRAM ColorT; 1 USES ColorU,wincrt; 2

VAR C,C1,C2:Color; 3

CS,CS1,CS2:string; 4

Choice:char; 5

6

PROCEDURE GetChoice(VAR Ch:char); 7

BEGIN 8

write('Input choice of operation: '); readln(Ch); 9

END; 10

11

PROCEDURE ConvertColor(S:string;VAR C:Color); 12

BEGIN 13

IF S='red' THEN C:=Red 14

ELSE IF S='yellow' THEN C:=Yellow 15

ELSE IF S='blue' THEN C:=Blue 16

ELSE IF S='green' THEN C:=Green 17

ELSE IF S='orange' THEN C:=Orange 18

ELSE IF S='violet' THEN C:=Violet 19

ELSE writeln('Invalid Color, 20

please primary color again'); 21

END; 22

23

FUNCTION WriteColor(C:Color):string; 24

BEGIN 25

IF C=Red THEN WriteColor:='red' 26

ELSE IF C=Yellow THEN WriteColor:='yellow' 27

ELSE IF C=Blue THEN WriteColor:='blue' 28

ELSE IF C=Green THEN WriteColor:='green' 29

ELSE IF C=Orange THEN WriteColor:='orange' 30

ELSE IF C=Violet THEN 31

WriteColor:='violet'; 32

END; 33

34

BEGIN 35

Page 7: data structure lesson02

29

Clrscr;writeln('****************************'); 36

writeln('Test operations of ADT Color'); 37

writeln('****************************'); 38

writeln('1 Mix'); 39

writeln('2 Primary'); 40

writeln('3 Form'); 41

writeln('9 Quit'); 42

writeln('******************************************'); 43

writeln('All possible colors that can be input are:'); 44

writeln('red, yellow, blue, green, orange, violet'); 45

writeln('******************************************'); 46

47

Getchoice(Choice); 48

49

WHILE (Choice<>'9') DO 50

BEGIN 51

CASE Choice OF 52

'1' : BEGIN 53

write('Input primary color1 : '); readln(CS1); 54

write('Input primary color2 : '); readln(CS2); 55

ConvertColor(CS1,C1); 56

ConvertColor(CS2,C2); 57

C:=Mix(C1,C2); 58

CS:=WriteColor(C); 59

writeln('The result of mixing ', CS1, ' and ', 60

CS2, ' is ', CS); 61

END; 62

63

'2' : BEGIN 64

write('Input color : '); readln(CS); 65

ConvertColor(CS,C); 66

IF Primary(C) THEN writeln(CS, 67

' is a primary color') 68

ELSE writeln(CS, ' is not a primary color'); 69

END; 70

71

'3' : BEGIN 72

write('Input a non primary color : '); 73

readln(CS); 74

ConvertColor(CS,C); 75

Form(C,C1,C2); 76

CS1:=WriteColor(C1); 77

CS2:=WriteColor(C2); 78

writeln(CS1, ' and ',CS2,' are two primary 79

colors that form the input color', CS); 80

END; 81

ELSE BEGIN 82

writeln('Not a correct choice, try again'); 83

GetChoice(Choice); 84

Page 8: data structure lesson02

30

END; 85END {CASE}; 86

87

writeln('******************************************'); 88

GetChoice(Choice); 89

90

END {WHILE}; 91

92

writeln('!!! End of program !!! '); 93

94

END. 95

โปรแกรม 2.2 การทดสอบการใชขอมูลแบบคัดยอชนิด “Color”

คําอธิบายโปรแกรม 2.2 1. เมือ่มีการเรียกใช UNIT ColorU ในบรรทัดท่ี 2 ชื่อ (identifier) ของ UNIT ColorU ที่โปรแกรม

ColorT จะรูจักและเรียกใชไดทันที คือ Color, Mix, Primary, และ Form 2. เนื่องจากในการทดสอบนี้จะใหมีการรับขอมูลจากคียบอรด ซึ่งขอมูลที่มีชนิดเปน Color เปน

ชนิดแบบ enumerated ซ่ึงไมสามารถรับคาจากคียบอรดได จึงตองใหมีการรับคาเปน string แลวใชโพรซีเจอร ConvertColor แปลงชนิด string เปน Color

3. ในทํานองเดียวกันเน่ืองดวยเราไมสามารถแสดงผลขอมูลชนิด enumerated ดวยคําส่ัง write หรือ writeln ได เราจึงตองมีการแปลงขอมูลจากชนิด Color ไปเปน string ดวยฟงกชัน WriteColor

4. ในโปรแกรมนี้มีการเรียกใชการดําเนินงานของ ADT Color ฟงกชัน Mix ในบรรทัดท่ี 58, ฟงกชัน Primary ในบรรทัดท่ี 67, โพรซีเจอร Form ในบรรทัดท่ี 76

กิจกรรม 2.2 ฝกการทดสอบการใชงานขอมูลแบบคัดยอ 1. จงคอมไพลและรันโปรแกรม ColorT ตามตัวอยาง และตั้งชื่อไฟลชื่อ ColorT.pas และศึกษาตร

รกการทํางานของโปรแกรม 2. จงสรางการดําเนินงานข้ึนอีก 1 การดําเนินงานคือ Assign ใน UNIT ColorU และจงทดสอบการ

ดําเนินงาน Assign ในโปรแกรม ColorT ดวย 3. จงเขียนโปรแกรม StringT เพื่อทดสอบการใชงานชนิดขอมูล LetterString และตั้งชื่อไฟลชื่อ

StringT.pas

Page 9: data structure lesson02

31

ตอนท่ี 2.2 การวิเคราะหเชิงเสนกํากับและสัญกรณโอใหญ

หัวเรื่อง เร่ืองท่ี 2.2.1 แนวคิด เร่ืองท่ี 2.2.2 การนับจํานวนครั้งของการใชงานคําสั่ง เร่ืองท่ี 2.2.3 คําส่ังมาตรเวลา เร่ืองท่ี 2.2.4 การวิเคราะหเชิงเสนกํากับ เร่ืองท่ี 2.2.5 สัญกรณโอใหญ เร่ืองท่ี 2.2.6 ตัวอยางการวิเคราะหโปรแกรมเชิงเสนกํากับ

แนวคดิ 1. การวิเคราะหประสิทธิภาพเชิงเวลา อาศัยการนับจํานวนครั้งของการใชงานคําสั่งตางๆ ในโปรแกรม โดยเขียนจํานวนครั้งนี้เปนฟงกชันของขนาดของขอมูลขาเขา 2. การวิเคราะหจะงายขึ้น ถาพิจารณานับเฉพาะคําสั่งมาตรเวลาในโปรแกรม ซึ่งคือคําสั่งที่ถูกใชทํางานมากที่สุดในโปรแกรม โดยเวลาการทํางานโดยรวมจะแปรโดยตรงตามจํานวนครั้งที่คําสั่งมาตรเวลาถูกใชงาน 3. การวิเคราะหเชิงกํากับเปนการศึกษาพฤติกรรมของอัตราการเติบโตของฟงกชันเวลาการทํางานของโปรแกรม เมื่อขอมูลขาเขามีขนาดใหญมาก 4. เราใชแนวคิดของสัญกรณโอใหญในการแทนฟงกชันเวลาการทํางานที่ซับซอน ดวยฟงกชันที่ซับซอนนอยกวาเพื่อใหเขาใจและงายตอการเปรียบเทียบอัตราการเติบโตของเวลาการทํางาน

วัตถุประสงค หลังจากที่ศึกษาตอนที่ 2.3 แลว นักศึกษาสามารถ 1. เขาใจการวิเคราะหประสิทธิภาพเชิงเวลาของโปรแกรม 2. เขาใจวิธีการใชสัญกรณโอใหญในการวิเคราะหเวลาการทํางานของโปรแกรมเชิงเสนกํากับ

เรื่องที่ 2.2.1 แนวคดิ

ปญหาที่นักโปรแกรมควรถามตัวเองเสมอก็คือวา โปรแกรมที่ตนเขียนนั้นมีประสิทธิภาพเชิงเวลาการทํางานอยางไร และเมื่อเทียบกับอีกโปรแกรมที่ใชแกปญหาเดียวกันแลวเราจะรูไดอยางไรวาของใครเร็วกวากัน คําตอบที่มักพบบอยๆ ก็คือ “ก็ลองใชงานจริงแลวจับเวลาดูจริงๆ กันเลยก็จะรูเอง” ปญหาของการลองใชงานจริงเลย จะอยูตรงที่วาแลวจะใชชุดขอมูลขาเขาใดเปนชุดทดสอบ และเราจะทราบไดอยางไรวาชุดขอมูลตางๆ ที่นํามาทดสอบนั้นครอบคลุมจุดเดนจุดดอยของโปรแกรมที่เขียนขึ้น

Page 10: data structure lesson02

32

การวิเคราะหการทํางานเชิงเวลาโดยทั่วไปอาศัยการนับจํานวนครั้งของการใชงานคําสั่งตางๆ ในโปรแกรมระหวางการทํางาน ซึ่งเขียนบรรยายจํานวนครั้งที่นับไดนี้ใหเปนฟงกชันของขนาดของขอมูลขาเขาของปญหา อัตราการเติบโตของฟงกชันนี้เองจะสะทอนใหเห็นถึงแนวโนมการเพิ่มของเวลาการทํางานเมื่อขนาดของขอมูลเพิ่มขึ้นวามีลักษณะอยางไร โดยเรามักวิเคราะหเวลาการทํางานสําหรับขอมูลขาเขากรณีเลวสุด (worst case) และกรณีเฉล่ีย (average case)

เพื่อใหการวิเคราะหกระทําไดงายขึ้น โดยทั่วไปจะอาศัยวิธีการนับเฉพาะ “คําส่ังมาตรเวลา” ตางๆ ซ่ึงคือคําส่ังท่ีจะทํางานเปนจํานวนคร้ังไมนอยกวาคําส่ังอ่ืนๆ ดังนั้นจึงใชเปนตัวแทนเพื่อศึกษาแนวโนมของเวลาการทํางานโดยรวมได และยังอาศัยการวิเคราะหเชิงเสนกํากับ (asymptotic analysis) โดยใชสัญกรณเชิงเสนกํากับโอใหญ (Big O) ในการแทนฟงกชัน เพื่อลดรูปฟงกชันใหสามารถตีความไดงายขึ้น อีกทั้งชวยจัดการวิเคราะหไดงายขึน้ดวย ซ่ึงจะไดนําเสนอในรายละเอียดตอไป

เรื่องที่ 2.2.2 การนับจํานวนครั้งของการใชงานคําสั่ง

วิธีหนึ่งที่ใชในการวิเคราะหเชิงเวลาคือการหาผลรวมของเวลาการทํางานของคําสั่งตางๆ ในโปรแกรมซึ่งถูกใชงาน ลองดูตัวอยางโปรแกรมสั้นๆ ขางลางนี้ กําหนดใหเวลาการทํางานของคําสั่งในบรรทัดที ่i เปน ti วินาท ี

01: function sum( var x : vector; n : integer ) : integer;02: var i, s : integer;03: begin04: s := 0;05: for i:=1 to n do06: s := s + x[i];07: sum := s;08: end;

sum ทําหนาท่ีหาผลรวมของจาํนวนในเวกเตอร x (ซ่ึงสรางดวยแถวลําดับ) ตั้งแตชองที่ 1 ถึง n โดย ใชเวลารวมทั้งสิ้นเทากับ

Φ Γ 8751

654321 tttttttttn

iΙΙΙΙΙΙΙΙ �

[

นักศึกษาอาจรูสึกตอนน้ีวา ถึงแมวาสามารถเขียนออกมาไดดังแสดงขางบนนี้ แลวสรุปไดวาอะไร เพราะเวลาการทํางานก็ยังข้ึนกับคา ti ท้ังหลายในนิพจน ตองขอบอกตอนน้ีเลยวาจุดประสงคของการวิเคราะหประสิทธิภาพเชิงเวลาก็เพื่อวิเคราะหใหเห็นแนวโนมของเวลาการทํางานของโปรแกรมเมื่อขนาดของขอมูลเพิ่มขึ้น นั่นคือทําใหเราประมาณไดวาถาขอมูลเพิ่มขึ้น k เทาแลวเวลาการทํางานจะเพิ่มเทาไร

กําหนดให ti ℑ c1 สําหรับทุกๆ i หมายความวาให c1 เปนคาคงตัวซ่ึงมีคาเทากับเวลาการทํางานของคําส่ังท่ีทํางานนานสุดในโปรแกรม ดังน้ันจากตัวอยางเวลาการทํางานท่ีแสดงขางบนน้ี เราสามารถลดรูปใหแลดูกระทัดรัดข้ึนไดเปน

Φ Γ

Φ Γ72

324

1

11

118751

654321

Ι[

Ι

���

���

�ΙℑΙΙΙΙΙΙΙΙ ��

[[

nc

ccctttttttttn

i

n

i

สรุปไดวา sum ใชเวลาการทํางานไมเกิน c1 (2n + 7) ซึ่งเปนฟงกชันแปรผันโดยตรงแบบเชิงเสนกับ n

Page 11: data structure lesson02

33

ตองขอเนนวาการท่ีเรากําหนดให "c1 เปนคาคงตัวมีคาเทากับเวลาการทํางานของคําสั่งที่ทํางานนานสุดในโปรแกรม" ในการวิเคราะหขางบนนี้ คําสั่งตางๆ ที่ใชจะตองเปนคําสั่งซึ่งใชเวลาการทํางานไมแปรตามจํานวนขอมูล เรียกวาเปนคําส่ังมูลฐานซ่ึงคือคําส่ังงายๆ เชน บวก ลบ คูณ หาร เปรียบเทียบ หรืออ่ืนๆ ที่ใชเวลาไมแปรตามจํานวนขอมูล ถึงตรงนี้บางคนอาจสงสัยวาการบวกก็ใชเวลาแปรตามจํานวนบิต ซ่ึงก็เปนความเขาใจที่ถูกตอง แตเนื่องจากในที่นี้เราใชการบวกขอมูลแบบ integer ซึ่งจํานวนหนึ่งๆ มีขนาดจํากัด เชน 16 บิต จึงถือไดวาใชเวลาคงตัว เพราะบวกอยางไรก็ไมเกิน 16 บิต

การวิเคราะหเชิงเวลาท่ีกระทํามาน้ันอาจดูคลายการนับจํานวนคร้ังท่ีคําส่ังมูลฐานตางๆ ในโปรแกรมถูกเรียกใชงาน จากตัวอยาง คําสั่งตางๆ ใน sum ทํางานเปนจํานวน 2n + 7 คร้ัง แตละครั้งใชเวลาไมเกิน c1 ไดผลรวมเปน c1(2n + 7) การนับจํานวนคร้ังท่ีคําส่ังมูลฐานตางๆ ในโปรแกรมถูกเรียกใชงานนี่เองจึงเปนกลวิธีหลักในการวิเคราะหประสิทธิภาพเชิงเวลา

มาดูอีกสักตัวอยาง matrixMult ขางลางนี้มีหนาที่หาผลคูณของเมทริกซ x และ y ซึ่งมีขนาด n∑n ไดผลลัพธเก็บไวในเมทริกซ z (ในท่ีน้ีเราสรางเมทริกซตางๆ ดวยแถวลําดับสองมิต)ิ

01: procedure matrixMult( var x, y, z : matrix; n : integer );02: var i, j, k : integer;03: begin04: for i:=1 to n do05: for j:=1 to n do06: z[i,j] := 0.0;07: for i:=1 to n do08: for j:=1 to n do09: for k:=1 to n do10: z[i,j] := z[i,j] + x[i,k]*y[k,j];11: end;

นับจํานวนครั้งที่แตละคําสั่งถูกใชงานจะไดดังตารางขางลางนี้ บรรทัดท่ี จํานวนครั้งที่ทํางาน

1 1 2 1 3 1 4 n+1 5 n(n+1)

6 n2

7 n+1 8 n(n+1) 9 n2(n+1)

10 n3

11 1

รวมจํานวนครั้งของการทํางานของคําสั่งในแตละบรรทัดเขาดวยกัน และคูณกับ c2 ซึ่งกําหนดใหเปนเวลาการทํางานของคําส่ังท่ีทํางานนานสุดในโปรแกรม จะไดวาเวลาการทํางานของโปรแกรมนี้ไมเกิน

c2⌡ ( 2n3 + 4n2 + 4n + 6 )

ถากลับไปดูท่ีตัว matrixMult อีกทีหนึ่ง หลายคนอาจรูสึกวานาจะยุบรวมวงวน for ท่ีซอนกันสองชั้นในบรรทัดที่ 4 ถึง 6 ไปเปนสวนหนึ่งของวงวนขางลาง น่ันคือยายคําส่ังท่ี 6 ไปอยูหลังคําสั่งที่ 8 กลายเปนโปรแกรมใหมขางลางนี้

Page 12: data structure lesson02

34

01: procedure matrixMult( var x, y, z : matrix; n : integer );02: var i, j, k : integer;03: begin04: for i:=1 to n do05: for j:=1 to n do06: begin07: z[i,j] := 0.0;08: for k:=1 to n do09: z[i,j] := z[i,j] + x[i,k]*y[k,j];10: end;11: end;

เมื่อวิเคราะหโปรแกรมขางบนนี้จะไดวาใชเวลาการทํางานไมเกิน c2⌡ ( 2n3 + 5n2 + 2n + 5 ) แลวอยางนี้หมายความวาที่เขียนแบบใหมนี้ชากวาแบบเกาหรือ ? ทั้งๆ ที่แรงจูงในของการเขียนใหมนี้ ก็เพราะรูสึกวานาจะไดแบบที่เร็วกวา ตองขอบอกตรงน้ีวาเราคงนําผลลัพธของการวิเคราะหท้ังสองมาเปรียบเทียบกันโดยดูที่สัมประสิทธิ์เห็นจะลําบาก เพราะเรานับทุกบรรทัด ซึ่งแตละบรรทัดใชเวลาการทํางานตางกัน (ที่ไมเกิน c2) การคูณดวยคาคงตัว c2 ตามที่ทํามาบอกเราเพียงแคขอบเขตบนของเวลาการทํางาน (น่ันคือบอกวาเวลาการทํางานไมเกินผลท่ีวิเคราะหได) นอกจากนี้หลายคนอาจตั้งคําถามวาทําไมตองนับบรรทัดที่เปนการประกาศตัวแปร begin และ end ดวย ซึ่งดูเหมือนวาจะไมไดถูกแปลเปนคําสั่งเครื่องแตอยางใด การท่ีสัมประสิทธ์ิของพจน n2 ตางกันนิดหนอย (4 กับ 5 สําหรับตัวอยางขางตน) จึงบอกอะไรเราไมไดหรอกวาแบบใดจะเร็วกวากัน อีกทั้งเมื่อ n มีคาเพิ่มขึ้น พจน n2 นั้นก็เปนพจนที่มีคาเพิ่มขึ้นนอยกวาคาที่เพิ่มขึ้นของพจน n3 ความแตกตางของสัมประสิทธิ์ที่พจน n2 ยิ่งไมคอยมีผลโดยรวม สรุปไดวาเรานาใหความสนใจกับพจนที่มีการเติบโตเร็วกวาพจนอื่นๆ และสัมประสิทธิ์ที่เปนคาคงตัวที่คูณอยูนั้นนํามาเปรียบเทียบไดไมคอยชัดเจนนักถาตางกันไมมาก จึงเปนที่มาของกลวิธีการวิเคราะหดวยการนับคําสั่งมาตรเวลา และการวิเคราะหเชิงเสนกํากับ เพ่ือชวยใหการวิเคราะหกระทําไดงายขึ้น

เรื่องที่ 2.2.3 คําสั่งมาตรเวลา

หลายคําสั่งในโปรแกรมที่เขียนขึ้นนั้น บางคําสั่งถูกเรียกใชงานเปนจํานวนคงตัวไมขึ้นกับขนาดของขอมูล บางคําสั่งก็ถูกเรียกใชนอยกวาคําสั่งอื่นอยางเห็นไดชัด หมายความวาคําสั่งเหลานี้ไมไดไปมีสวนเปนตัวกําหนดอัตราการเติบโตของเวลาการทํางานโดยรวมเอาเลย แตเราก็ตองเสียเวลาไปนับจํานวนครั้งที่มันถูกใชงานอยูดี เพ่ือลดภาระการนับคําส่ังเหลาน้ี กอนจะเร่ิมนับ เราควรพิจารณาเสียกอนวาคําส่ังใดในโปรแกรม ท่ีเปนตัวกําหนดเวลาการทํางานโดยรวม เราเรียกคําส่ังประเภทน้ีวาเปนคําส่ังมาตรเวลา (ซึ่งมีไดมากกวาหนึ่งคําส่ังในโปรแกรม) คําสั่งมาตรเวลาเปนคําสั่งที่ถูกใชทํางานมากที่สุดในโปรแกรม น่ันคือเวลาการทํางานโดยรวมจะแปรโดยตรงตามจํานวนครั้งที่คําสั่งมาตรเวลาถูกใชงาน จาก sum ในหัวขอที่แลวนั้น คําส่ัง for (บรรทัดท่ี 5) เปนคําสั่งมาตรเวลาของโปรแกรมนี้ คําสั่งนี้ถูกเรียกใชงานเปนจํานวน n+1 คร้ัง (เน่ืองจากเปนวงวนแบบ for ซึ่งให i เริ่มที่ 1 เพิ่มทีละหนึ่งจนกระทั่งเมื่อมีคาเทากับ n+1 จึงหลุดจากวงวน) หรือจะใชคําสั่งที่บรรทัดที ่6 ภายในวงวน for ก็ได เมื่อกําหนดให n > 0 ถาเรานับเฉพาะคําส่ังท่ีบรรทัดท่ี 6 จะไดจํานวนครั้งที่ถูกเรียกใชงานเปนจํานวน n คร้ัง สรุปไดวา sum ใชเวลาการทํางานเปนฟงกชันเชิงเสนของ n

Page 13: data structure lesson02

35

ถามาดูที่ matrixMult แบบแรก จะไดคําสั่งที่บรรทัดที่ 10 เปนคําส่ังมาตรเวลา (บรรทัดท่ี 9 ก็ใชไดเหมือนกัน) เพราะเปนบรรทัดท่ีถูกเรียกใชมากกวาบรรทัดอ่ืนๆ บรรทัดท่ี 10 นี้อยูภายในวงวนสามวงซอน

กันซ่ึงแตละวงหมุนเปนจาํนวน n รอบ จึงถูกเรียกใชเปนจํานวน 3

1 1 1

1 nn

i

n

j

n

k[���

[ [ [

คร้ัง ตีความไดวา

matrixMult ใชเวลาการทํางานเปนฟงกชันแบบ n3 ขอใหสังเกตตรงนี้วาเราไมสนใจคําสั่งที่บรรทัดที่ 4 ถึง 6 เลย ท่ีเปนเชนน้ีเพราะวาคําส่ังท่ีบรรทัดท่ี 6 อยูภายในวงวนสองวงซอนกันซึ่งเพิ่มคาตั้งแต 1 ถึง n ซึ่งหมุนเปนจํานวน n2 คร้ังท่ีนอยกวาคําส่ังมาตรเวลาท่ีเราเลือก

กิจกรรม 2.2 พิจารณาคําสั่งมาตรเวลา ขอใหนักศึกษาพิจารณาดูวาคําส่ังใดควรเปนคําส่ังมาตรเวลาสําหรับ matrixMult แบบท่ีสอง จะ

พบวาเมื่อนับแลวจะไดผลเชนเดียวกัน

เรื่องที่ 2.2.4 การวิเคราะหเชิงเสนกํากับ

เนื่องจากเราใชจํานวนครั้งที่คําสั่งตางๆ ในโปรแกรมที่ถูกใชงาน (หรือจะพิจารณาเฉพาะคําสั่งมาตรเวลาก็ได) เปนตัวสะทอนถึงเวลาการทํางาน การนําผลการวิเคราะหของหลายๆ โปรแกรมมาเปรียบเทียบกันเปนส่ิงท่ีตองระวังเปนพิเศษ เพราะคําสั่งแตละคําสั่งของโปรแกรมตางๆ อาจใชเวลาการทํางานจริงซึ่งตางกัน แตเราจะมีความมั่นใจสูงมากในการเปรียบเทียบผล ถาเราเลือกใชการเปรียบเทียบเมื่อขอมูลมีจํานวนมาก (ซึ่งหมายถึงคาของตัวแปร n ที่ใชในตัวอยางที่ผานมามีคาสูง) เรียกวาการศึกษาพฤติกรรมของเวลาการทํางานของโปรแกรมเชิงเสนกํากับ น่ันคือศึกษาการเติบโตของเวลาการทํางานเม่ือ n มีคามาก มีคามากแบบเขาใกลอนันตไปเลย ตัวอยางเชนถาตองการเปรียบเทียบฟงกชัน 1000n กับ 0.1n2 ก็ลองวาดกราฟเสนของทั้งสองฟงกชันดูจะไดดังภาพประกอบ 2.1 จะเห็นไดวา 1000n ใหคามากกวา 0.1n2 เมื่อ n ℑ 10000 แตเมื่อ n มีคาเกิน 10000 ฟงกชัน 0.1n2 จะใหคามากกวาเสมอ ท้ังน้ีเพราะ n2 มีอัตราการเติบโตที่เร็วกวา n มาก

0.E+00

1.E+07

2.E+07

3.E+07

4.E+07

5.E+07

0 5000 10000 15000 20000 25000

1000n0.1n^2

Page 14: data structure lesson02

36

ภาพประกอบ 2.1 กราฟเสนของฟงกชัน 1000n กับ 0.1n2

หรือจะใชเรื่องของลิมิตเพื่อเปรียบเทียบการเติบโตของฟงกชันโดยไมตองวาดกราฟเสน ก็จะไดวา

010000lim1.0

1000lim2

�

���

�ν�

��

����

√⇓√⇓ nn

nnn

แสดงใหเห็นวาเมื่อ n มีคามากเปนอนันต สัดสวนของ 1000n กับ 0.1n2 มีคาเขาใกลศูนย หมายความ 0.1n2 นั้นใหคาที่เพิ่มขึ้นเมื่อ n เพิ่มมากกวาคาของ 1000n มาก จึงมีอัตราการเติบโตที่เร็วกวา ภาพประกอบ 2.2 แสดงตัวอยางฟงกชันที่มักพบบอยๆ ซึ่งมีอัตราการเติบโตแตกตางกัน

n

nn22n

log n

nn22n

ภาพประกอบ 2.2 ตัวอยางฟงกชันที่มีอัตราการเติบโตแตกตางกัน

ดังนั้นเมื่อตองการเปรียบเทียบการเติบโตของฟงกชัน f(n) กับ g(n) (ตองขอเนนวาในท่ีน้ีเราสนใจเฉพาะ n และฟงกชันของ n ที่ใหคาไมติดลบ เพราะฟงกชันนี้แทนเวลาการทํางานของโปรแกรม) ก็เพียงแตหาคาลิมิตของ f(n) / g(n) เมื่อ n ⊂℘ ซึ่งสามารถตีความผลที่ไดดังนี้

ถา 0)()(lim [

℘⊂ ngnf

n แสดงวา f(n) โตชากวา g(n)

ถา ℘[

℘⊂ )()(lim

ngnf

n แสดงวา f(n) โตเร็วกวา g(n)

ถา cngnf

n[

℘⊂ )()(lim โดยที่ c ⋅ 0 และ c ⋅ ℘ แสดงวา f(n) โตในอัตราที่เทากับ g(n)

เมื่อมีการใชลิมิต ก็ขอใหนึกถึงกฎของโลปตาล (l'Hôpital's Rule) ที่เคยเรียนกันในวิชาแคลคูลัส จะชวยหาคําตอบจัดการไดงายขึ้น ขอเขียนทบทวนใหดูโดยไมพิสูจนที่มาดังนี้ กฎของโลปตาล ถา f(n) และ g(n) เปนฟงกชันท่ีหาอนุพันธได โดยที่ ⊗∴

⊗⊆

)(lim nfn

และ

⊗∴

⊗⊆

)(lim ngn

แลว)()(lim

)()(lim

ngnf

ngnf

nn ℑ

ℑ∴

⊗⊆⊗⊆

ตัวอยาง 2.1 จงเปรียบเทยีบอตัราการเติบโตของ 100n2 + 5n + 1 กับ n2

ใชกฎของโลปตาลไดวา 1002

200lim2

5200lim15100lim2

2∴∴

ϑ∴

ϑϑ

⊗⊆⊗⊆⊗⊆ nnn nn

n

nn แสดงวาฟงกชันทั้ง

สองโตเร็วเทากัน

Page 15: data structure lesson02

37

ตัวอยาง 2.2 จงเปรียบเทยีบอตัราการเติบโตของ ln9 n กับ n0.1 ใชกฎของโลปตาลไดดังน้ี

0)1.0(

ln189lim

...)1.0(

ln89lim

1.0

ln9lim1.0

)/1)(ln9(limlnlim

1.09

0

1.02

7

1.0

8

)11.0(

8

1.0

9

∴∴

⊗⊆

⊗⊆

⊗⊆Λ

⊗⊆⊗⊆

n

n

n

nn

n

n

nn

n

n

n

n

nnn

สรุปไดวา ln9 n โตชากวา n0.1 อยากจะขอเนนย้ําตรงนี้เลยวาถา f1(n) และ f2(n) เปนฟงกชันของเวลาการทํางานของโปรแกรมที่ 1

และโปรแกรมที่ 2 ตามลําดับ โดยที่ n ขนาดของขอมูลของปญหาที่โปรแกรมทั้งสองรับเขาไปประมวลผล และถา f1(n) เปนฟงกชันที่โตเร็วกวา f2(n) ยอมสรุปไดวาโปรแกรมที่ 1 ทํางานชากวาโปรแกรมที่ 2 เมื่อ n มีคามาก ขอใหนักศึกษาอานขอความนี้ใหมอีกครั้ง สังเกตตรงท่ีขีดเสนใตอีกคร้ัง เพ่ือกันความสับสน และในทางกลับกัน เมื่อ f1(n) เปนฟงกชันที่โตชากวา f2(n) ยอมสรุปไดวาโปรแกรมที่ 1 ทํางานเร็วกวาโปรแกรมที่ 2 เมื่อ n มีคามาก

เรื่องที่ 2.2.5 สัญกรณโอใหญ

การบรรยายเวลาการทํางานของโปรแกรมดวยฟงกชันซึ่งวิเคราะหมาไดจากการนับคําสั่งมาตรเวลาตามท่ีไดนําเสนอมาน้ัน บางทีอาจไดผลท่ีดูลุมลาม เชน f(n) = 10n2 + n log n + 27n + 4 เปนตน เราสามารถแทนตัวฟงกชันที่แลดูยุงๆ ยาวๆ ใหกระทัดรัดมากขึ้นไดดวยการใชสัญกรณโอใหญ (Big O notation) โดยเราเขียน f(n) = O(g(n)) เมื่อ f(n) เปนฟงกชันที่โตไมเร็วกวา g(n) เชิงเสนกํากับ น่ันคือ

f(n) = O(g(n)) เมื่อ cngnf

n[

℘⊂ )()(lim โดยที่ c ∇ 0 และ c ⋅ ℘

เชน 10n2 + n log n + 27n + 4 = O(n2) ตีความงายๆ วา 10n2 + n log n + 27n + 4 เปนฟงกชันที่โตไมเร็วกวา n2 เชิงเสนกํากับ ซึ่งใหความรูสึกกับผูอานไดทันทีวาโปรแกรมที่ใชเวลาการทํางานแบบ O(n2) มีอัตราการเติบโตของเวลาการทํางานไมเลวไปกวาแบบ n2 เมื่อ n มีคามาก ดังน้ันการเปรียบเทียบประสิทธิภาพเชิงเวลาระหวางโปรแกรมตางๆ จึงกระทําไดงายขึ้น

เราสามารถใหนิยามกับสัญกรณโอใหญไดในอีกรูปแบบหนึ่ง โดยกําหนดให O(g(n)) คือเซตของฟงกชันตางๆ ที่โตไมเร็วกวา g(n) เขยีนไดดังน้ี

µ(g(n)) = { f(n) | มีคาคงตัวบวกสองตัวคือ c และ n0 ที่ทําให f(n) ℑ cg(n) เมื่อ n ∇ n0 } หมายความวาถา f(n) µ(g(n)) แสดงวาการเติบโตของ f(n) จะถูกกําหนดขอบเขตดานบนไวดวย

ลักษณะการเติบโตของ g(n) นั่นคือเราสามารถหาคาคงตัวบวก c ที ่f(n) ℑ cg(n) เมื่อ n ∇ n0 แสดงเปนตัวอยางไดดังภาพประกอบ 2.3

Page 16: data structure lesson02

38

n

f (n)

c g(n)

n0 ภาพประกอบ 2.3 f(n) µµµµ(g(n))

ตัวอยาง 2.1 จงแสดงใหเห็นจริงวา 2n2 + 500n + 1000log n = O(n2) ตองหาคา c และ n0 ที่ทําให 2n2 + 500n + 1000log n ℑ cn2 เปนจริงเสมอเมือ่ n ∇ n0 กําหนด

ให c = 2+500+1000 = 1502 ก็สบายใจไดเลยวาอสมการนี้เปนจริงแนเมื่อ n ∇ 1

ตัวอยาง 2.2 จงแสดงใหเห็นจริงวา loga n = O( logb n ) สําหรับคาคงตัว a, b > 1 เน่ืองจากเราสามารถแปลงฐานของ log จากฐาน a ไปเปนฐาน b ไดดวยการหารดวยคาคงตัว

logb a น่ันคือ loga n = (logb n) / (logb a) ดังน้ันสรุปไดวา loga n = O( logb n ) ตัวอยางนี้ชี้ใหเห็นวาเรามักจะไมใสฐานของ log ในสัญกรณเชิงเสนกํากับ เชน O(log n) เพราะวานอกจากจะสะดวกแลว ยังไมมีผลใดๆ ดวย ดังน้ันในเชิงเสนกํากับแลว log1.1 n กับ log100 n มีอัตราการเติบโตเทากัน

ตัวอยาง 2.3 : จงแสดงใหเห็นจริงวา log n! = O( n log n ) จากนิยาม n! = n⌡ (n–1) … 2⌡1 แทนทุกๆ พจนทางขวาดวย n จะไดวา n! ℑ nn หาคา log ทั้ง

สองขางได log n! ℑ n log n = µ(n log n)

ตัวอยาง 2.4 : จงแสดงใหเห็นจริงวา Φ Γ1

1

Ι

[

[�k

n

i

k nOi โดยที่ k เปนคาคงตัว

เนื่องจากภายในผลบวกนั้น i มีคาตั้งแต 1 ถึง n แสดงวา i ℑ n สรุปไดวา ik ℑ nk ดังน้ันเม่ือรวมทุกๆ ik ตั้งแต 1 ถึง n ยอมไดวา ��

[[

ℑni

kni

k ni11

= nk+1 = O(nk+1) การใชสัญกรณโอใหญเพื่อแทนประสิทธิภาพเวลาการทํางานนั้น มีประเด็นที่ตองเขาใจดังนี้ 1. หลายคนอาจถามตอนนี้แลววาทําไมบางทีเขียน f(n) = µ(g(n)) บางทีก็เขียน f(n) µ(g(n)) แลวจะตองใช = หรือ กันแน ? แบบที่ถูกตองใช เพราะวาตามนิยามแลว O(g(n)) น้ันเปนเซต แตเรากลับพบกันบอยมากๆ เลยวาเขาใชเคร่ืองหมาย = กัน เพราะวาสะดวกดี อีกท้ังอาน

Page 17: data structure lesson02

39

ไดราบร่ืน โดยทั่วไปเราอาน f(n) = µ(g(n)) วา "f(n) เปนโอใหญของ g(n)" จึงตองคํานึงไวเสมอวาเปน = ทางเดียว หมายความวา f(n) = O(g(n)) ไมไดหมายความวา O(g(n)) = f(n)

2. โดยทั่วไปแลวเราจะใชโอใหญเพื่อแทนฟงกชันที่ซับซอนดวยฟงกชันที่แลดูงายๆ เชนเขียน 10n2 + n log n + 27n + 4 = O(n2) สวน 10n2 = O(25n2 + n log n + 93n + 5) ถึงแมจะถูกตองตามนิยาม แตก็จะไมเขียนกัน เพราะจุดประสงคของการใชสัญกรณโอใหญก็เพื่อแทนสิ่งที่ยุง ดวยสิ่งที่เขาใจงายกวา

3. จากตัวอยาง 10n2 + n log n + 27n + 4 = O(n2) จะพบวา 10n2 + n log n + 27n + 4 ก็เปน O(n3) เปน O(n90) หรือเปน O(2n) ดวยเชนกัน เพราะ n3, n90 และ 2n ลวนแลวแตเปนฟงกชันที่โตเร็วกวา n2 เชิงเสนกํากับท้ังส้ิน แตเรามักเลือกใช g(n) ที่โตชาๆ ชาสุดเทาที่จะชาไดในการแทน f(n) ดวย O(g(n)) ลองคิดก็แลวกันวาสมมติวาโปรแกรม A เรียกใชคําสั่งมาตรเวลาเปนจํานวน 10n2 + n log n + 27n + 4 ก็คงไมมีเหตุผลที่จะโฆษณาใหคนในวงการทราบวา A ใชเวลาการทํางานเปน O( n90 ) ถึงแมจะไมผิดที่จะบอกวา A ใชเวลาการทํางานไมเลวกวา n90 เชงิเสนกํากับ แตก็นาจะอวดวา A ใชเวลาการทํางานไมเลวกวา n2 เชิงเสนกํากับ จะดีกวา

4. เราใช O(1) แทนเซตของฟงกชันที่ไมโต ซึ่งรวมถึงคาคงตัวทั้งหลายดวย นอกจากวิธีการใชลิมิตและการใชนิยามของขอบเขตบนมาชวยเขียนบรรยายฟงกชันที่ยุงดวย

ฟงกชันที่งายในโอใหญแลว มีอีกวิธีหนึ่งที่มักใชไดผลอยางรวดเร็ว ก็คือการตัดพจนที่โตชากวา และการตัดสัมประสิทธ์ิท่ีเปนคาคงตัวออก เชน f(n) = 10n2 + n log n + 27n + 4 พบวาประกอบดวยพจนยอยๆ ที่เมื่อเรียงลําดับตามอัตราการเติบโตจากมากไปนอยจะไดลําดับดังนี้คือ 10n2, n log n, 27n, 4 (อยาลืมวา n โตเร็วกวา log n ดังน้ัน n2 ก็ยอมโตเร็วกวา n log n) ดังน้ันก็เลือกสนใจเฉพาะพจนท่ีโตเร็วสุด เพราะในการวิเคราะหเชิงเสนกํากับพจนที่โตเร็วสุดจะเปนตัวที่มีอิทธิพลสูงสุดในการกําหนดคาของฟงกชัน เมื่อ n มีคามาก จึงสามารถเขียนไดเลยวา 10n2 + n log n + 27n + 4 = O(10n2) และเมื่อมาดูที่พจน 10n2 จะพบวาสัมประสิทธ์ิซ่ึงเปนคาคงตัว 10 น้ันสามารถตัดท้ิงได เพราะไมมีผลใดๆตออัตราการเติบโต (คาลิมิตของ f(n) / g(n) จะไมเปลี่ยนแปลงเลยไมวาจะม ี10 อยูหรือไม) ดังนั้นจะไดวา 10n2 + n log n + 27n + 4 = O(n2)

เรื่องที่ 2.2.6 ตัวอยางการวิเคราะหโปรแกรมเชิงเสนกํากับ

ตัวอยาง 2.5 : จงวิเคราะหเวลาการทํางานเชิงเสนกํากับของสวนของโปรแกรมขางลางนี ้01: for i:=1 to 100 do02: for j:=1 to i do03: s := s + 1;

ในที่นี้บรรทัดที่ 3 เปนคําส่ังมาตรเวลา ซึ่งถูกเรียกใชงานเปนจํานวน

50502

)1100(1001100

1

100

1 1[

Ι[[���

[[ [ ii

i

ji คร้ัง หมายความวาใชเวลาคงตัวไมขึ้นกับขนาดของขอ

มูลขาเขาแตอยางใด ดังนั้นสวนของโปรแกรมนี้ใชเวลาเปน O(1)

Page 18: data structure lesson02

40

ตัวอยาง 2.6 : จงวิเคราะหเวลาการทํางานเชิงเสนกํากับของสวนของโปรแกรมขางลางนี ้01: for i:=1 to n do02: for j:=1 to i do03: s := s + 1;

ในที่นี้บรรทัดที่ 3 เปนคําส่ังมาตรเวลา จะพบวาถูกเรียกใชงานเปนจํานวน

222

)1(12

11 1

nnnnin

i

n

i

i

jΙ[

Ι[[���

[[ [

คร้ัง ดังนั้นจึงใชเวลาเปน O(n2)

ตัวอยาง 2.7 : จงวิเคราะหเวลาการทํางานเชิงเสนกํากับของสวนของโปรแกรมขางลางนี ้01: while n > 0 do02: n := n div 2;

ในที่นี้บรรทัดที่ 3 เปนคําส่ังมาตรเวลา ใหสังเกตวาวงวนนี้จะเลิกทํางานเมื่อ n ℑ 0 ก็ตองมาดูวาคาของ n เปล่ียนแปลงอยางไร คาของ n น้ันลดลงทีละคร่ึง (ปดเศษทิ้ง) ก็แสดงวา n จะตองจบลงที่ศูนยอยางแนนอน (ในที่นี้ถือวา n มีคาเริ่มดวยจํานวนไมติดลบ) การท่ีมีคาลดลงทีละคร่ึงน้ัน n ในรอบที่ k ยอมมีคา n / 2k โดยกอนที่ n จะมีคาเปนศูนยแลวเลิกทํางานน้ัน n ก็ตองเทากับ 1 ดังนั้นรอบที่ทําให n มีคาเปน 1 ก็คือ k = log2 n สรุปไดวาวงวน while หมุนเปนจํานวน 1+log2 n รอบ ดังน้ันเวลาการทํางานเปน O( log2 n )

ตัวอยาง 2.8 : จงวิเคราะหเวลาการทํางานเชิงเสนกํากับของสวนของโปรแกรมขางลางนี ้01: i := 1; j := n;02: while i < j do03: begin04: i := i + 3;05: j := j – 5;06: end;

วงวน while ทํางานตราบเทาที่ i < j โดยที่ i มีคาเริ่มตนที่นอยกวา j คาของ i เพ่ิมทีละสาม ในชณะท่ีคา j ลดลงทีละหา แสดงวาจะตองมีชวงที่ i ∇ j แลวหลุดจากวงวนแน และคาของ i และ j จะเขยิบเขาหากันทีละ 8 แสดงวา จํานวนรอบที่หมุนในวงวนมีคาอยางมาก n/8 รอบ ดังน้ันเวลาการทํางานเปน O( n )

โดยสรุปหาก n มาก มาตรวัดประสิทธภิาพสําหรับสัญกรณโอใหญ จากมากไปนอย ดังแสดงในตารางที่ ตาราง 2.1

Page 19: data structure lesson02

41

ตาราง 2.1 มาตรวัดประสิทธิภาพสําหรับสัญกรณโอใหญ จากมากไปนอย

n = 8 n =128 n = 1024 O(1) 1 1 1 O(log2n) 3 7 10

O(n) 3 11 32

O(n) 8 128 1,024

O(n⌡log2n) 24 896 10,240

O(n2) 64 16,192 1,048,576 O(n3) 512 2,097,152 1,073,741,824 O(2n) 256 3.40 x 1038 1.79 x 10308