Algorithms Analysis Sanchai Yeewiyom School of Information & Communication Technology University of Phayao
สิ่งที่ต้องพิจารณา คือ ต้องการ Resource ใดบ้าง เช่น เวลา หน่วยความจำ Algorithms เซ็ตของคำสั่งง่ายๆ ที่ระบุไว้ชัดเจนเพื่อใช้แก้ปัญหาต่างๆ (วิธีการที่ใช้ในการแก้ปัญหา) สิ่งที่ต้องพิจารณา คือ ต้องการ Resource ใดบ้าง เช่น เวลา หน่วยความจำ โดยทั่วไปเน้นในเรื่อง เวลา
ปัจจัยที่สำคัญในการวิเคราะห์ คือ เวลาที่ใช้ในการทำงานของโปรแกรม Algorithms Analysis ปัจจัยที่สำคัญในการวิเคราะห์ คือ เวลาที่ใช้ในการทำงานของโปรแกรม ปัจจัยที่ส่งผลกระทบต่อเวลา ได้แก่ Compiler Software ประสิทธิภาพของเครื่องคอมพิวเตอร์ ประสิทธิภาพของระบบเครือข่าย etc.
พิจารณาจากขนาดของ input เป็นหลัก Exp. Algorithms Analysis ปัจจัยที่สำคัญที่สุด คือ อัลกอริทึมที่ใช้ในการแก้ปัญหา และ input ที่ใช้สำหรับอัลกอริทึม พิจารณาจากขนาดของ input เป็นหลัก Exp.
Tavg(n) = เวลาเฉลี่ยที่ใช้ในการจัดเรียง Algorithms Analysis ถ้า ให้ฟังก์ชัน T(n) แทนเวลาที่ใช้ในการทำงานของโปรแกรม ตัวอย่างเช่น โปรแกรมการเรียงลำดับข้อมูล ดังนั้น จะมี 2 ฟังก์ชัน ถ้ากำหนดขนาด input = n ได้แก่ Tavg(n) = เวลาเฉลี่ยที่ใช้ในการจัดเรียง Twost(n) = เวลาที่ใช้สูงสุดในการจัดเรียง ซึ่ง Tavg(n) <= Twost(n) เสมอ
เวลาที่ใช้ในการค้นหา = จำนวนข้อมูลทั้งหมด Algorithms Analysis Exp. การค้นหาข้อมูลใน array ขนาด n โดยค้นหาแบบเรียงลำดับ เกิดเหตุการณ์ได้ 2 กรณี Worst Case = จำนวนครั้งสูงสุดของการค้นหา ข้อมูลอยู่ตำแหน่งสุดท้ายของ array Tworst(n) = n เวลาที่ใช้ในการค้นหา = จำนวนข้อมูลทั้งหมด
Algorithms Analysis Average Case = เวลาเฉลี่ยที่ใช้ค้นหา ข้อมูลอยู่ที่ตำแหน่งใดๆ บน array จำนวนการค้นหาอาจเป็น 1, 2, 3, … , n แต่ละครั้งความน่าจะเป็นในการค้นหาเป็น p = ½ ดังนั้น จะได้
Tavg(n) = 1*1/n + 2*1/n + 3*1/n + … +n*1/n = (1+2+3+…+n) * 1/n Algorithms Analysis Tavg(n) = 1*1/n + 2*1/n + 3*1/n + … +n*1/n = (1+2+3+…+n) * 1/n = n(n+1)/2 * 1/n = (n+1)/2 จะได้ค่าเฉลี่ยประมาณครึ่งหนึ่งของจำนวนข้อมูลทั้งหมด
Running Time Calculation Algorithm ที่ใช้มักมีมากกว่าหนึ่ง ต้องเลือกเอาวิธีที่มีประสิทธิภาพที่สุด คือ เร็วที่สุด และใช้หน่วยความจำน้อยที่สุด การวัดประสิทธิภาพของอัลกอริทึมจะวัดเป็นหน่วยเวลา (n) ความซับซ้อนของอัลกอริทึมจะอยู่ในรูปฟังก์ชัน f(n) ที่แทนค่าของเวลาที่ใช้ในอัลกอริทึม ซึ่งขึ้นกับขนาดของ n เรียกฟังก์ชันนี้ว่า Big O ใช้สัญลักษณ์ O(n)
Running Time Calculation Big O คืออัตราความเร็วการทำงานของโปแกรม ซึ่งขึ้นกับค่า n การคำนวณหา จะได้จากจำนวนครั้งในการเปรียบเทียบในอัลกอริทึม การวิเคราะห์จะคิดเฉพาะเทอมที่เป็นค่ามาก ส่วนเทอมที่เป็นค่าน้อยจะตัดทิ้งไป
Running Time Calculation ความซับซ้อน f(n) ของอัลกอริทึมจะมากขึ้นถ้า n เพิ่ม แสดงได้จาก ตารางแสดงอัตราการเติบโต จากตาราง Big O เรียงจากน้อยไปมาก คือใช้เวลาน้อยไปมาก Function Name c Constant log n Log arithmatic log2 n Log square n Linear n log n n2 Quadratic n3 Cubic 2n Exponenetial
Running Time Calculation ตัวอย่างอัตราการเติบโตของ Big O Algorithm 1 2 3 4 5 6 n time O(log n) O(n) O(n log n) O(n2) O(n3) O(2n) 40 25 125 32 10 100 103 7 700 104 106 1030 1000 109 10300
Running Time Calculation Big O ที่มีประสิทธิภาพดีที่สุด คือ O(1) แต่ถ้าเป็น O(n3) แสดงว่าอัลกอริทึมประสิทธิภาพไม่ค่อยดี แต่ถ้ากรณีที่มีข้อมูลขนาดไม่มาก ค่าที่ได้จะไม่แตกต่างกันมากนัก อัลกอริทึมที่มีประสิทธิภาพดีที่สุด คืออัลกอริทึมที่มีอัตราการเติบโตน้อยที่สุดเมื่อมีจำนวนข้อมูลมากขึ้น
Running Time Calculation Exp. การคำนวณหาค่า Big O ของโปรแกรมการคำนวณหาค่า i3 int sum(int n) { int i, p_sum; p_sum = 0; // 1 unit for(i=1; i<=n; i++) // 2n+2 units p_sum += i*i*i; // 3n units return(p_sum); // 1 unit } ดังนั้น สมการที่ได้คือ f(n) = 5n+4 , O(n).
General Rule for Calculation Rule#1 for loop Rule#2 nested loop Rule#3 Consecutive Statement Rule#4 if/else
Rule#1 for loop for loop คือ เวลาการทำงานทั้งในส่วนการทำ statement ทั้งหมดใน loop รวมทั้งเวลาในการทดสอบเงื่อนไข คูณด้วยจำนวนรอบ เช่น for(i=1; i<=n; i++) // 1+(n+1)+n=2n+2 -> 2n+2+3n=5n+2 p_sum += i*i*i; // 3n ดังนั้น รวมเวลาที่ใช้ทั้งหมด f(n) = 2n+2+3n = 5n+2 , O(n) โดยสรุป for loop มีค่าเป็น O(n)
ต้องวิเคราะห์จากข้างในไปข้างนอก Rule#2 nested loop for loop ซ้อน for loop ต้องวิเคราะห์จากข้างในไปข้างนอก เวลาทั้งหมดที่ใช้ คือ running time ของ statements คูณด้วย product ของขนาด for loop ทั้งหมด เวลาในการทำงานทั้งหมดเป็น O(n2)
for(i=0; i<n; i++) //1+n+1+n=2n+2 Rule#2 nested loop Exp. for(i=0; i<n; i++) //1+n+1+n=2n+2 for(j=0; j<n; j++) //1+n+1+n=2n+2 k++; //n loop ใน = 2n+2+n, รวม loop นอก = (3n+2)*(2n+2) สรุป f(n) = (3n+2)*(2n+2) = 6n2+6n+4n+4 , O(n2)
Rule#3 Consecutive Statement กรณีที่มีหลายๆ for loop เรียงลำดับกัน จะนำผลรวมของเวลาการทำงานทั้งหมดภายในแต่ละ loop มารวมกัน
Rule#3 Consecutive Statement Exp. for(i=0; i<n; i++) 3n+2 a[i] = 0; for(i=0; i<n; i++) 2n+2=(2n+2)*(5n+2) for(j=0; j<n; j++) //2n+2 5n+2 a[i] += a[j]+i+j; //3n รวมเวลาที่ใช้ f(n) = 3n+2+(2n+2)*(5n+2) = 10n2+17n+6 Big O(n2)
จะใช้เวลาในการทำงานโดยไม่สนใจว่าจะทำ statement ถูกหรือไม่ Rule#4 if/else จะใช้เวลาในการทำงานโดยไม่สนใจว่าจะทำ statement ถูกหรือไม่ พิจารณาจากกรณีเลวร้ายที่สุด เวลาในการทำงาน จะไม่มากกว่าเวลาในการทดสอบเงื่อนไขรวมกับเวลาที่ใช้ในการทำ statement สรุป if/else มีค่า Big O = O(1)
Rule#4 if/else Exp. if (condition) S1 else S2 เวลาที่ใช้ คือ O(1)
Exercise sum =0; for (i=0; i<n; i++) sum++; sum = 0; จงวิเคราะห์ Running Time (Big-O) ของส่วนโปรแกรมต่อไปนี้ sum =0; for (i=0; i<n; i++) sum++; sum = 0; for (j=0; j<n*n; j++)