Algorithum

You might also like

You are on page 1of 52

Data Structures

การวิเคราะห ์ความเร็วของโค ้ด


Algorithm คือ คาสังและขั ้
นตอนต่ ่ ้
างๆทีไว

ทาเพือแก ้ปัญหา

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 1


Introduction
 ทำไมต้องเรียนโครงสร ้ำงข้อมู ล
 เข้ำใจ code ต่ำง ๆ ได้ง่ำย
 เลือกใช้โครงสร ้ำงข้อมู ลได้อย่ำงถู กต้อง
เหมำะสม

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 2


ตัวอย่างเช่น เรำเลือกเก็บจำนวน
เต็ม 5 จำนวน (1 ถึง 5 ) ลงใน
โครงสร ้ำงข้ อ มู ล
Linked ist
P
1 2 3 4 5

P
Tree (Binary 2
Search Tree)
1 4

3 5
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 3
กำรเลือกเก็บข้อมู ล
(ต่อ)
5 ถ ้าต ้องการข ้อมูลที่
Heap

มากทีสุ ่ ด ก็ต ้องเลือก


4 3 โครงสร ้างการเก็บที่
ช่วยให ้หาข ้อมูลนั้นได ้
2 1 ่ ด ในทีนี
เร็วทีสุ ่ ้ Heap
จะเหมาะทีสุ ่ ด

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 4


กำรคำนวณควำมเร็วของ
โปรแกรม
 Big O
ถ ้า T ( N )  c( f ( N ))
T ( N )  ( f ( N ))

 โดยมี c กับ N0 เป็ นค่าคงทีและ่ N>=N0


 นี่ คือการบอกว่า T(N) เติบโตอย่างไร

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 5


ตัวอย่ำงกำรคำนวณ BIG O
 ถ ้า T(N) = 339N และ f(N) = N*N
ถ ้าให ้ N0 = 339 และ C = 1

เราสามารถจะเห็นได ้ทันทีวา
่ 339N0 <=
1*(N0*N0) T ( N 0)  c( f ( N 0))
T ( N )  ( f ( N ))  ( N )
2

11/17/2019
่ ้วย
ี าตอบอืนด
แต่มค
อ. ดร. วิษณุ โคตรจร ัส
-> T(N) <=
6
ตัวอย่ำงกำรคำนวณ BIG O (ต่อ)
 ดังนั้น T(N)=O(N) ก็ถก ู เหมือนกัน แล ้วจะตอบ
อะไรกันแน่
 ให ้ตอบเป็ นค่าทีน้ ่ ด เพราะค่าทีน้
่ อยทีสุ ่ อยทีสุ
่ ด

คือค่าทีเราเอามาใช ้จริงๆในการคิดความเร็วของ
โปรแกรม ฉะนั้น O(N) เป็ นคาตอบ
 ่
แล ้ว O(N) มันเกียวอะไรกั บการหาความเร็วใน
การ execute ของ code ขอให ้เราดูตวั อย่าง
ต่อไป
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 7
หำควำมเร็วของโค้ดต่อไปนี ้
แบบละเอียด
sigmaOfSquare(int n) // calculate
{ 1 unit (declare only)
1: int tempSum; 1 unit (assignment)
2: tempSum = 0; n+1 unit
n unit
3: for (int i=1;i<n;i++)
1 unit คูณ บวก และ
4: tempSum += i*i;
assignment อย่างละ
5: return tempSum; n จึง = 3n unit
} 1 unit (return)
รวมได ้ 5n+5 unit
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 8
หำควำมเร็วแบบละเอียดไม่ไหว
หรอก
 แต่วา่ โปรแกรมแค่นียั ้ งเสียเวลาในการกะ running
time ขนาดนี ้ ดังนั้น โปรแกรมใหญ่ ๆ ยิงไม่ ่ ต ้องพูด
ถึง ดังนั้น ถ ้าจะคานวณ running time ของ
โปรแกรมให ้รวดเร็วเราจาเป็ นต ้องใช ้การประมาณ
อย่างคร่าว ๆ กว่านี ้ นั่นคือต ้องใช ้ Big O นั่นเอง
 จากหน้าทีแล ่ ้ว เรากะได ้จาก loop เวลาในการ

run ส่วนอืนจะน้ อยมากเมือเที ่ ยบกับส่วนทีเป็
่ น
loop ซึงท ่ าซาไปเป็
้ น ผลคูณของ n ครง้ั
 ฉะนั้น เมือคิ่ ดจากตัว loop โปรแกรมนี ้ จะมีBig O
11/17/2019 = O(n) อ. ดร. วิษณุ โคตรจร ัส 9
กำรหำ BIG O จำก loop ต่ำงๆ
 ้ั ่ loop
For loop ค่า Big O คือ จานวนครงที
ทาซา้
Nested loop
n รอบ

n รอบ
1: for (i = 1; i <= n; i++)
2: for (j = 1; j <= n; j++)
statements; Big O จะเป็ น
11/17/2019
O(n2)
อ. ดร. วิษณุ โคตรจร ัส 10
กำรหำ BIG O จำก loop ต่ำงๆ
(ต่อ)
 นิ ยามของการคิด Nested loop เป็ นดังนี ้
ถ ้า T1(N)=O(f(N)) และ T2(N)= O(g(N))
แล ้วละก็
T1(N)* T2(N)= O(f(N)*g(N))

จากตัวอย่างนั้น f(n) = g(n) = n


จึงตอบเป็ น O(n2)

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 11


กำรหำ BIG O จำก loop ต่ำงๆ (ต่อ
2)
 ่ ยงต่อกันเป็ นบรรทัด
Statement ทีเรี
1: for (i = 0; i <= n; i++) O(n)
2: statement1;
3: for (j = 0; j <= n; j++)
4: for (k = 0; k <= n; k++) O(n2)
5: statement2;

เอาตัวมากสุดมาตอบ นั่น
คือ O(n2)
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 12
กำรหำ BIG O จำก loop ต่ำงๆ (ต่อ
3)
 นิ ยามของการหา running time จาก
Statement ทีเรี ่ ยงต่อกัน
ถ ้า T1(N)=O(f(N)) และ T2(N)= O(g(N))
แล ้วละก็
T1(N)+ T2(N)= max(O(f(N),O(g(N)))

จากตัวอย่าง f(n) = O(n), g(n) =


O(n2)
จึงตอบเป็ น O(n2)
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 13
กำรหำ BIG O จำก loop ต่ำงๆ (ต่อ
4)
 ประโยคแบบมีเงื่อนไข
1: if (condition)
O(f(n))
2: Statement1
3: Else
O(g(n))
4: Statement2

เอาตัวมากสุดมาตอบ นั่น
คือ max(O(f(n),O(g(n)))
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 14
กำรหำ BIG O จำก recursion
1:mymethod (int n) {
2: if (n == 1) {
3: return 1;
4: } else {
5: return 2*mymethod(n – 1) + 1;
6: }
7:}
้ั big O = O(n)
n ครง,

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 15


Maximum Subsequence Sum,
่ Big
ตัวอย่ำงกำรเลือก code ทีให้
ี่ ด
O ดีทสุ
 Maximum Subsequence Sum คือ
 ถ ้ามีจานวนเต็ม A1,A2, … ถึง An j

 Maximum Subsequence Sum คือค่า  Ak


่ ่ ่
ทีมีคา่ มากทีสุด (คือส่วนทีติดกัน ทีให ้ผลบวกมาก ่ k i

ทีสุ่ ด)
ติดกัน
 ตัวอย่างเช่น -2, 11, -6, 16, -5, 7

ผลรวมของ 11, -6, 16 คือ 21 (ดูมาก ตาม


สัญชาติญาณ) แต่ทมากที ี่ ่ ด ก็คอื จากช่วง 11, -
สุ

6, 16, -5, 7 ซึงรวมแล ้วได ้ 23 นี่ แหละคือ
11/17/2019
Maximum Subsequence
อ. ดร. วิษณุ โคตรจร ัส
Sum 16
ี ำรแก้ max sub sum แบบที่ 1
วิธก
1: int maxSubSum01 ( int [] a) {
2: int maxSum = 0; index แรก
3: for (int i = 0; i < a.length; i++) {
4: for (int j = i; j < a.length; j++) { index
5: int theSum = 0; สุดท ้าย
6: for (int k = i; k <= j; k++) {
บวกตังแต่ ้
7: theSum += a[k];
8: } แรกถึง
9: if (theSum > maxSum) { สุดเลืทอ้าย
กเก็บ
10: maxSum = theSum;
ผลที ่
มาก
11: }
ทีสุ่ ด
12: }
13: return maxSum;
14: }
15: }
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 17
ี ำรแก้ max sub sum แบบที่ 1
วิธก
(ต่อ)
 วิธท ่ ้
ี ี 1 นี มี big O = O(n ) ดูจาก
3

โปรแกรม
 แต่แค่นียั้ งไม่ดพี อ เพราะมีการคานวณ
่ าซ
ทีซ ้ ้อนมากเกินไป
ถ ้าบวกจากตาแหน่ ง 0 ถึง2 ไปแล ้ว ตอนที่
บวกจากตาแหน่ งที่ 0 ถึง 3 กลับต ้องเริมบวก


ใหม่หมด แทนทีจะใช ้ผลจากการบวกจาก
ตาแหน่ ง 0 ถึง2 ได ้
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 18
ี ำรแก้ max sub sum แบบที่ 2
วิธก
1: int maxSubSum02 (int [] a) {
2: int maxSum = 0; ตัวเริม่
3: for (int i = 0; i < a.length; i++) {
4: int theSum = 0;
5: for (int j = i; j < a.length; j++) {
6: บวก theSum += a[j];
7: จากตัว if (theSum > maxSum) {
8: ่
เริมและ maxSum = theSum;
9: สะสม }
10: }
ค่า BIG O = O(n2)

11: }
12: เรือยๆ return maxSum;
13: }

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 19


ี ำรแก้ max sub sum แบบที่ 2
วิธก
(ต่อ)
-2 11 -6 4
่ i=0, j=0:
เมือ theSum = -2
maxSum = 0

่ i=0, j=1:
เมือ theSum = -2 + 11 = 9
maxSum กลายเป็ น 9

่ i=0, j=2:
เมือ theSum = 9 + (-6) = 3
maxSum ยังคงเป็ น 9

่ i=0, j=3:
เมือ
11/17/2019 theSum = ัส 3 + 4
อ. ดร. วิษณุ โคตรจร 20
ี ำรแก้ max sub sum แบบที่ 3
วิธก
 ใช ้ divide and conquer
 คาตอบอาจจะอยูใ ่น
ครึงซ ่ ้ายของการแบ่งปัญหา หรือ

ครึงขวาของการแบ่ งปัญหา หรือ
อยูท ้ั
่ งสองข ้าง (ต ้องมีตวั สุดท ้ายจาก
่ ้ายและตัวแรกจากครึงขวา)
ครึงซ ่

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 21


ี ำรแก้ max sub sum แบบที่ 3
วิธก
(ต่อ)
1 -2 7 -6 2 8 -5 4

้ อ
Max sub sum ข ้างนี คื ้ อ 10
Max sub sum ข ้างนี คื
7

่ ้ายทีมี
ของครึงซ ่ ตวั สุดท ้าย (-6) คืของครึ ่
อ 1 งขวาที
มี่ ตวั แรก (2) คือ
10

่ ่
ยวข
Max sub sum ทีคาบเกี ้างซ ้ายและขวา คือ 1 +10 = 11 นี่
คือคาตอบ

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 22


ี ำรแก้ max sub sum แบบที่ 3
วิธก
(ต่อ 2)
1:int maxSumDivideConquer (int [] array, int leftindex, int
rightindex {
2: // ต ้องถือว่าขนาดของอาร ์เรย ์หารสองลงตัวพอดีจะได ้แบ่งได ้เท่ากัน
ไม่เช่นนั้นโปรแกรมจะยุ่งยาก
3: if (leftindex == rightindex) { // Base Case T(n)
5: if (array[leftindex] > 0 )
6: return array[leftindex];
7: else
8: return 0; // maxSubSum มีคา่ ต่าสุดคือ 0
เท่านั้น T(n/2)
9: }
10: int centerindex = (leftindex + rightindex)/2; T(n/2)
12: int maxsumleft = maxSumDivideConquer(array,
leftindex, centerindex);
13: int maxsumright = maxSumDivideConquer
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส ( array, 23
วิธกี ำรแก้ max sub sum แบบที่ 3
(ต่อ 3)
14: int maxlefthalfSum = 0, lefthalfSum = 0;
15: ่
// เก็บผลรวมทีมากที ่ ดนับจากตัวสุดท ้ายของครึงซ
สุ ่ ้าย
ลงไปถึงตัวแรก
16: for (int i = center; i >= leftindex; i--) {
17: lefthalfSum = lefthalfSum + array[i];
18: if (lefthalfSum > maxlefthalfSum) {
19: maxlefthalfSum = lefthalfSum;
20: }
21: } O(n/2)

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 24


ี ำรแก้ max sub sum แบบที่ 3
วิธก
(ต่อ 4)
22: int maxrighthalfSum = 0, righthalfSum = 0;

23: // เก็บผลรวมทีมากที ่ ด นับจากตัวแรกของครึงขวาไปถึ
สุ ่ ง
ตัวสุดท ้าย
24: for (int i = centerindex + 1; i <= rightindex; i++) {
25: righthalfSum = righthalfSum + array [i];
26: if (righthalfSum > maxrighthalfSum) {
27: maxrighthalfSum = righthalfSum;
28: }
29: } O(n/2)

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 25


ี ำรแก้ max sub sum แบบที่ 3
วิธก

(ต่้
อ 5) ่
30: // จากนันหา max ของทัง 3 กรณี คือ ของครึงซ ้าย, ของ

ครึงขวา, ่ ท
และของทีอยู ่ ง้ั 2 ครึง่
31: return max3 (maxsumleft, maxsumright,
maxlefthalfSum + maxrighthalfSum)
}
้ max จากสามตัว ใช ้เวลาคงที่ เราไม่ต ้องสนใจ
ส่วนนี หา

ดังนั้น เวลารวมทังหมดจะเป็
้ น
T(n) = 2T(n/2) + 2O(n/2)

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 26


ี ำรแก้ max sub sum แบบที่ 3
วิธก
(ต่อ 6) ้
 หลังจากได ้ unit time มาแล ้ว คราวนี เอามาหา
BIG O เลย
T(n) = 2T(n/2) + 2O(n/2)
= 2T(n/2) + O(n)
เพราะ O(n) <= c*n ตามนิ ยาม
= 2T(n/2) + cn
เอา n หารตลอดจะได ้
n
T( )
T ( n)
 2 c (1)
n n
11/17/2019
2
อ. ดร. วิษณุ โคตรจร ัส 27
ี ำรแก้ max sub sum แบบที่ 3
วิธก
(ต่อ 7)
 ่ าไปเรือยๆ
เมือท ่ จะได ้
n n
T( ) T( )
2  4 c
(2)
n n
2 4
n n
T( ) T( )
4  8 c (3)
n n
4 8
.................
T (2) T (1)
 c (X)
2 1
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 28
วิธกี ำรแก้ max sub sum แบบที่ 3

(ต่อ 8)
 เมือเอา (1) + (2) + (3) +…..+ (x) จะได ้
T (n) T (1)
  c * log 2 (n)
n 1
เพราะว่าด ้านซ ้ายและขวาตัดกันได ้เยอะส่วน c
้ั งไงล่ะ
ก็บวกกันได ้เป็ นจานวน log2 n ครงยั
เอา n คูณหมด จะได ้
T (n)  n *T (1)  c * n * log 2 (n)
และเพราะ T(1) เป็ นค่าคงที่ เราจึงรู ้ได ้ทันทีวา่
T(n) มี Big O = O(n log n)
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 29
ี ำรแก้ max sub sum แบบที่ 4
วิธก
 คือการเอาวิธท ี ี่ 2 มาปร ับปรุง โดยมีข ้อสังเกตที่
หนึ่ งว่า
ตัวแรกของ maximum subsequence sum
จะเป็ นค่าลบไม่ได ้ อย่างเช่น 3, -5, 1, 4, 7, -4

ค่า -5 จะเป็ นตัวแรกของ sequence ของ


คาตอบไม่ได ้ แค่เราให ้ตัวแรกเป็ นเลขตัวต่อไป
(ในทีนี่ คื
้ อเลข 1) เราก็จะได ้ค่ารวมมากขึนแล ้ ้ว
(อย่าลืมว่าเราใช ้สมมติฐานว่า maximum
subsequence sum มี ค า
่ น้ อ ยที
สุ่ ดคือ 0)
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 30
ี ำรแก้ max sub sum แบบที่ 4
วิธก

(ต่อ )
 ข ้อสังเกตทีสองคือ
subsequence ทีมี ่ ผลรวมเป็ นลบ ไม่สามารถ
่ ้นของ maximum
เป็ นส่วนเริมต
subsequence sum ได ้
ให ้เราอยู่ระหว่างการทาลูปลูปหนึ่ ง โดยที่ i เป็ น
index ของตัวแรกของ subsequence และ j
เป็ น index ของตัวสุดท ้ายของ subsequence
(ซึ ่ วสุ
3 งตั 4 ดท ้ายนี
1 ท ้ าให
-3 ้ subsequence
-9 1 5 มีคา ่ เป็ น
ลบ) และ p เป็ น index ใด ๆ ระหว่าง i+1 กับ j
i p j

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 31


ี ำรแก้ max sub sum แบบที่ 4
วิธก
่ (ต่
อ 2)
 ข ้อสังเกตทีสอง (ต่อ)
้ อไปของลูปก็น่าจะเป็ นการเลือน
ขันต่ ่ j ออกไป ซึง่
• ถ ้า a[j] เป็ นลบ เราก็ไม่ได ้ maximum
subsequence sum ทีดี ่ ขน ึ ้ ค่าของ
maximum subsequence sum ก็จะยังคง

ไม่เปลียน
• ถ ้า a[j] เป็ นบวก เราก็จะได ้ค่า a[i]+…+a[j]

ทีมากขึ ้
นกว่า a[i]+…+a[j ตัวเก่า] แต่เพราะ
a[i]+…+a[j ตัวเก่า] เป็ นลบ ค่าผลรวมจึงไม่
มีทางสู ้ค่าของ maximum subsequence
sum ทีเก็ ่ บสะสมมาได ้ หรือแม้แต่จะสูค่้ า a[j
ตัวใหม่] เพียวๆก็ไม่ได ้ ดังนั้นจึงสรุปได ้ว่า ถ ้ามี
subsequence เป็ นลบแล ้วละก็ เราไม่ต ้องทา
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 32
ี ำรแก้ max sub sum แบบที่ 4
วิธก
(ต่ อ 3)
แต่ควรจะเลือน i ไปแค่หนึ่ งช่องเท่านั้นหรือ?

จากสมมติฐาน เรารู ้ว่า a[j] เท่านั้นทีท่ าให ้
a[i]+…+a[j] มีคา่ เป็ นลบ เพราะฉะนั้น การเลือน ่

i เพิมไปหนึ ่ งตาแหน่ งในช่วง i ถึง p ก็มแี ต่ทาให ้
ค่าผลรวมจาก a[i] ถึง a[p] (โดย p เป็ นค่าทีอยู ่ ่
ระหว่าง i ถึง j) ลดลงจากค่ามากทีสุ ่ ดทีเคยมี
่ นั่น
่ j จาก i ในขอบเขตนี ้ ยังไงก็ไม่มท
คือ ถ ้าเลือน ี าง
เพิม่ max sub sum ได ้
เพราะฉะนั
3 ้นถ ้าจะให ้ max sub sum มีคา่ มาก
้ ้อีก มีทางเดียวคือเราต ้องเริมคิ ่ ดจาก
4 1 -3 -9 1 5
ขึนได
ตาแหน่ งi ที่ j+1 นั่นคืpอเลือน่ i ไปที่ j+1 เลย
j

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 33


วิธก ี ำรแก้ max sub sum แบบที่ 4
(ต่อ 4)
1: int maxsubsumOptimum (int[] array) {
2: int maxSum = 0, theSum = 0;
3: for (int j = 0; j < a.length; j++) {
4: theSum = theSum + array [j];
5: if ( theSum > maxSum) {
6: maxSum = theSum;
7: } else if (theSum < 0) { ่ าให ้ทัง้
// ถ ้าเจอ a[j] ทีท
8: //sequence เป็ นลบ
9: theSum = 0; // นี่ คือจะมาเริมคิ
่ ดใหม่จาก
10: // j+1
11: }
12: }
13: return maxSum;
14: }
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 34
กำรมี log ใน BIG O
 ถ ้าเราสามารถใช ้เวลาคงที่ (O(1)) ในการแบ่ง
ปัญหาปัญหาหนึ่ งออกเป็ นส่วน ๆ เท่า ๆ กัน (วิธ ี
ที่ 3 ของ maximum subsequence sum)
ปัญหานั้นจะมี Big O เป็ น O(log n)
 เรามักสมมติให ้มีการอ่านข ้อมูลเข ้าเรียบร ้อย
แล ้ว มิฉะนั้นแค่การอ่านข ้อมูลเข ้าก็เป็ น O(n)
แล ้ว
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 35
่ น O(log n)
ตัวอย่ำงโปรแกรมทีเป็
 ่ การจัดเรียงตัวเลขจากน้อย
หา 5 ในอาร ์เรย ์ทีมี
ไปมากเรียบร ้อยแล ้ว
 ถ ้าใช ้การไล่หาจากสมาชิกอาร ์เรย ์ตัวแรก (Big
O คือ O(n)) จะเสียเวลาได ้
 ก็ดตู รงกลางแล ้วแบ่งข ้างหาดีกว่า (Binary
Search)

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 36


int binarySearch (int[] a, int x) {
int left = 0, right = a.length – 1;
while (left <=right) {
int mid = (left + right)/2;
if (a[mid] < x ) {
left = mid + 1;
Big O = O(log2 n)
} else if (a[mid] > x) {
right = mid – 1;
} else {
return mid;
}
}

return -1; // ถึงตรงนี แสดงว่าไม่เจอเลย
}11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 37
ตัวอย่ำง O(log n) (ต่อ)
 หาตัวหารร่วมมาก
long gcd (long m , long n) {
while (n!=0) {
long rem = m%n;
m = n;
n = rem;
}
return m; แล ้ว Big O จะหายังไง?
}

การลดลงของเศษจะบอกว่า Big O (การวนลูป)


่ าเศษลดลงอย่างไม่เป็ นสัดส่วนเลย
เป็ นเท่าไร ซึงค่
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 38
กำรหำ big O ของโปรแกรมหำร
ร่วมมำก
 ต ้องใช ้นิ ยามดังข ้างล่าง
 ู น์ได ้ดังนี ้
ถ ้า M > N แล ้ว M mod N < M/2 เราพิสจ
 ถ้ำ N <= M/2: เนื่ องจำกเศษต้องน้อยกว่ำ N
เพรำะฉะนัน ้ เศษก็มค ่ น้อยกว่ำ M/2 โดยปริยำย
ี ำ
 ถ้ำ N > M/2: M หำร N จะได้ 1 กับเศษ M-N นั่นคือ
1 ก ับเศษ M – (> M/2) เพรำะฉะนัน ้ เศษจะน้อยกว่ำ
M/2 โดยปริยำย
 จากนิ ยามนี ้ เศษของลูปที่ n จะถูกนามาใช ้เป็ น m
่ ้นของลูปที่ (n+2) เศษจากลูปที่ (n+2) จะต ้องมี
เริมต
่ ่ งของเศษจากลู
ค่าน้อยกว่าครึงหนึ
11/17/2019 ัส ที่ n นี่ แสดงว่าเมือ
อ. ดร. วิษณุ โคตรจร ป ่ 39
ตัวอย่ำง O(log n) (ต่อ2)
 การยกกาลังเลข xn ด ้วยวิธแี บ่งแยกและเอาชนะ
long power (long x, int n) {
if (n==0) Big O คือ O (log2 n)
return 1;
ปั ญหำถูกแบ่งเป็ น 2
if (isEven (n)) ครึง่ (ประมำณ) เท่ำก ัน
return power (x*x,ในแต่
n/2); ละกำรเรียกใช้
else method
return power (x*x, n/2)*x;
}
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 40

นิ ยำมเกียวกั
บ O(log n)
 logk n = O(n) เมือ ่ k เป็ นค่าคงที่

(นิ ยามนี บอกเราว่ า logarithm function มี
อัตราการเพิมต ่ ่ามาก)
 ่ ั f(n) = loga n มีคา่ big O เป็ น
ฟังก ์ชน
O(logb n) (a และ b เป็ นจานวนบวกทีไม่ ่ ใช่ 1)
(สรุปคือ log function มี growth rate
เท่ากัน)
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 41
พิสูจน์นิยำมทีว่่ ำ log มี growth
rate เท่ำกัน
 ให ้ loga n  x logb nและ y
a x  n , b y  n
 x ln a  y ln b  ln n
x ln a  y ln b
loga n * ln a  logb n * ln b
ln b
loga n  logb n *  (logb n ) * c
ln a
 loga n  O (logb n )
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 42
Runtime -น้อย(บน)ไปมำก(ล่ำง)
 c
 log n
 logk n
 n
 n log n
 n2
 n3
 2n
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 43
่ ๆ นอกเหนื อจำก Big O
นิ ยำมอืน
 Big Omega ( )
T(N)= (g(N)) ถ ้ามีคา่ คงที่ C และ N0 ซึง่
T(N) >= C g(N) โดย N>=N0

 จากนิ ยาม ถ ้า f(N)


 = (N2) แล้วล่ะก็  f(N) =
(N) = (N1/2) แต่เราควรเลือกอันทีค่ ่ าใกล ้
่ ด
ความจริงทีสุ

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 44


่ ๆ นอกเหนื อจำก Big O
นิ ยำมอืน
(ต่อ)
 Big Theta ( )
 T(N)  = (h(N)) ก็ตอ ่ T(N) = O(h(N))
่ เมือ 
และ T(N) = (h(N))
 (คือมี c1, c2, N0 ที่ c1*h(N) <= T(N) <=
c2*h(N) สาหร ับ N >= N0

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 45


่ ๆ นอกเหนื อจำก Big O
นิ ยำมอืน
(ต่อ 2)
 small O
 T(N) = o(p(N)) ถ ้า T(N) = O(p(N))
  แต่
T(N) (p(N))

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 46



ข้อสังเกตจำกนิ ยำมทังหลำย
 T(N) = O(f(N)) มีความหมายเหมือนกับ f(N)
= (T(N))
 เราสามารถเรียกได ้ว่า f(N) เป็ น “upper bound”
ของ T(N) และ T(N) ก็ถอื ได ้ว่าเป็ น lower
 bound
ของf(N)
 f(N) = N2 และ g(N) = 2N2 มีคา่ Big O และ
Big เท่ากัน นั่นคือ f(N) = (g(N))
 f(N) = N2 มี Big O  ได ้หลายค่า (เช่น O(N3),
่ ทสุ
O(N4)) แต่คา่ ทีดี ี่ ดคือ O(N2)
 เราสามารถใช ้สมการ f(N) = (N2) เป็ นการ
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 47
จำกข้อสังเกต เรำได้นิยำมล่ำสุด
ดังนี ้
 ถ ้า T(N) คือ Polynomial degree k แล ้ว
T(N) 
= (Nk)

 จากนิ ยามนี ้ ถ ้า T(N) = 5N4 + 4N3 + Nเรา


จะได ้ว่า T(N) = (N4)

11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 48


Best case Worst case และ
Average case
 ่
worst case คือ เวลาเมือการ run ต ้องใช ้

จานวนขันตอนมากที ่ ด
สุ
 ส่วน best case คือ เวลาในการ run ทีน้่ อย
่ ดทีเป็
ทีสุ ่ นไปได ้
 average case (เวลาเฉลีย)่ ล่ะ?
่ มีก ี่
 ดูวา input (ข ้อมูลเข ้า) เข ้าโปรแกรม
 สาหร ับแต่ละ input ดูวา ่ โปรแกรมใช ้กีขั ่ นตอน
้ (unit
time) ในการ run
 ค่าเฉลีย
11/17/2019 ่ (average case อ. ดร.running
วิษณุ โคตรจร ัส time) = ผลรวมของ49
Average case (ต่อ)
 แต่การหาค่าเฉลียอย่ ่ ้ บ
างง่ายนี ้ ตังอยู ่ นสมมติฐาน
ว่า
input แต่ละแบบมีอต ั ราการเกิดขึนเท่ ้ ากัน
 ถ ้าจะให ้ไม่ต ้องมีสมมติฐานนี ้

เราต ้องเอาค่าความน่ าจะเป็ นในการเกิดของ

input แบบต่าง i ๆ เข ้ามาคิดด ้วยนั่นคือ


 Average case = ความน่ าจะเป็ น
ของ inputi * ค่า unit time เมือใช ่ ้ inputi
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 50
ตัวอย่ำงกำรหำ Average case
 ถ ้าเราต ้องการหา x ในอาร ์เรย ์ขนาด n
 Best case เกิดขึนเมื้ อเจอ
่ x ในช่องแรก
 Worst case เกิดขึนเมื ้ อ ่ x อยูช
่ อ่ งสุดท ้ายใน
อาร ์เรย ์ (หรืออาจไม่อยูเ่ ลย)
 Average case
 สมมติวา ่ x เท่ากัน
่ แต่ละช่องอาร ์เรย ์มีโอกาสทีจะมี
 เพราะฉะนั้น โอกาสที่ x จะอยู่ในช่องช่องหนึ่ ง คือ
1/n
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 51
ตัวอย่ำงกำรหำ Average case
(ต่อ)
 Average Case running time = 1/n *

(จานวนขันตอนที ่ ้ในการหาเมือ
ใช ่ x อยูช ่ อ่ งที่ 1)
+ 1/n * (จานวนขันตอนที ้ ่ ้ในการหาเมือ
ใช ่ x อยู่
ช่องที่ 2) + ... + 1/n * (จานวนขันตอนที
้ ่ ้ใน
ใช
การหาเมือ ่ x อยูช
่ อ่ งที่ n หรืออาจไม่อยูเ่ ลย)
 = (1 + 2 +… + n) / n = (n+1)/2
 = O(n) = big O ของ worst
case
11/17/2019 อ. ดร. วิษณุ โคตรจร ัส 52

You might also like