2. Algorithm Analysis.

Slides:



Advertisements
งานนำเสนอที่คล้ายกัน
พีชคณิตบูลีน Boolean Algebra.
Advertisements

Texture การประมวลผลภาพแบบดิจิตอล Ian Thomas
จำนวน สถานะ NUMBER OF STATES. ประเด็นที่ สนใจ The number of distinct states the finite state machine needs in order to recognize a language is related.
รายวิชา ง40206 โครงสร้างข้อมูลและขั้นตอนวิธี
ครั้งที่ 12 การค้นหาข้อมูล (Searching)
อาจารย์ มธ. อธิบายการใช้ โมเดลของ
Data Structures and Algorithms
Data Structures and Algorithms
Stack.
ฟังก์ชัน(Function).
AVL Tree.
ออโตมาตาจำกัด FINITE AUTOMATA
Asst.Prof. Dr.Surasak Mungsing
Asst.Prof. Dr.Surasak Mungsing
CSC201 Analysis and Design of Algorithms Greedy, Divide and Conquer
MAT 231: คณิตศาสตร์ไม่ต่อเนื่อง (3) Function Growth & Time-Complexity
การวิเคราะห์ประสิทธิภาพของอัลกอริธึม (Performance Analysis)
ให้ประหยัดการใช้หน่วยความจำ (space) ด้วยความรวดเร็ว (time)
8/3/2014The Realities of software Testing1 Software testing Realities What is the realities of software testing Why does the software testing not complete.
Algorithm Efficiency There are often many approaches (algorithms) to solve a problem. How do we choose between them? At the heart of computer program.
โครงสร้างควบคุมการทำงาน
Liang, Introduction to Java Programming, Sixth Edition, (c) 2007 Pearson Education, Inc. All rights reserved Java Programming Language.
List ADTs By Pantharee S..
Chapter 3 Simple Supervised learning
Chapter 1/1 Arrays. Introduction Data structures are classified as either linear or nonlinear Linear structures: elements form a sequence or a linear.
หลักสูตรอบรมครู คอมพิวเตอร์ หลักสูตรอบรมครู คอมพิวเตอร์ หลักสูตรที่ ๑ ทักษะการโปรแกรม เบื้องต้น วันที่สาม.
In-Class Exercises Discrete Mathematics
สาขาวิชาเทคโนโลยี สารสนเทศ คณะเทคโนโลยีสารสนเทศ และการสื่อสาร.
Mathematical Model of Physical Systems. Mechanical, electrical, thermal, hydraulic, economic, biological, etc, systems, may be characterized by differential.
ว เคมีพื้นฐาน พันธะเคมี
ภาษาอังกฤษ ชั้นมัธยมศึกษาปึที่ 4 Grammar & Reading ครูรุจิรา ทับศรีนวล.
Trees Hierarchical Structures. Outlines Definition of trees Modeling by trees Properties of trees Applications – Binary search trees – Prefix codes –
Timed Math Quiz. โปรแกรมสุ่มคำนวณเลขแข่งกับ เวลา.
1 exit() and break C++ provides a way to leave a program early (before its natural finish) with the exit() function. The format of exit() is as follows:
Page : Stability and Statdy-State Error Chapter 3 Design of Discrete-Time control systems Stability and Steady-State Error.
สื่อการเรียนรู้ด้วยตัวเอง ชุดฝึกเขียนสรุป (Writing Summary)
อัลกอริทึมและผังงาน อาจารย์สมเกียรติ ช่อเหมือน
(Data Structure) CSI2202 โครงสร้างข้อมูล
Chapter 9 ตัวชี้ pointer.
INC 161 , CPE 100 Computer Programming
Data Structure & Algorithm Concept
การวิเคราะห์และออกแบบขั้นตอนวิธี
Computer Programming การเขียนโปรแกรมคอมพิวเตอร์
Complexity Lecturers : Boontee Kruatrachue Room no Kritawan Siriboon Room no. 913 Text : Data Structures & Algorithm.
CPE 332 Computer Engineering Mathematics II
13 October 2007
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 13: การคำนวณได้และการตัดสินใจของปัญหา ที่ยากต่อการแก้ไข.
บทที่ 4 ตัวแปร (Variables)
Linked List Lecturer : Kritawan Siriboon, Room no. 913
การวัดอัลกอริทึม (Analysis of Algorithm)
Asst.Prof. Dr.Surasak Mungsing
Data Structure and Algorithm
Dr.Surasak Mungsing CSE 221/ICT221 Analysis and Design of Algorithms Lecture 04: Time complexity analysis in form of Big-Oh.
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 04: การวิเคราะห์หาความซับซ้อนด้านเวลา ในรูป.
Problem Solving ขั้นตอนวิธีและการแก้ปัญหาสำหรับวิทยาการคอมพิวเตอร์
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 11: เทคนิคการออกแบบขั้นตอนวิธีตอนวิธี Greedy,
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 05: การวิเคราะห์ความซับซ้อนของ ขั้นตอนวิธีการเรียงลำดับข้อมูล.
Data Structures and Algorithms 2/2561
Algorithms Analysis Sanchai Yeewiyom
แล้วไงเกี่ยวกับความจริง What About Truth?
Data Structures and Algorithms 2/2561
1. พระเยซูทรงต้องการให้เราเป็น เหมือนพระองค์
การวิเคราะห์และออกแบบขั้นตอนวิธี
4.4 AVL Trees AVL (Adelson-Velskii and Landis) tree เป็น binary search tree กำกับด้วยเงื่อนไขของการสมดุล และประกันว่า depth ของ tree จะเป็น O(log n) อย่างง่ายที่สุดคือกำหนดว่า.
4.7. B-Trees โครงสร้าง tree ที่กล่าวถึงมาแล้วนั้น อยู่บนสมมติฐานที่ว่าโครงสร้างทั้งหมดสามารถจัดเก็บอยู่ในหน่วยความจำของเครื่องคอมพิวเตอร์ได้ ถ้า จำนวนข้อมูลมีปริมาณมากเกินกว่าที่จะเก็บไว้ใน.
การวิเคราะห์โจทย์ปัญหา (Problem Analysis)
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 03: ขั้นตอนวิธีและการวิเคราะห์ขั้นตอนวิธี Dr.Surasak.
การวิเคราะห์และออกแบบขั้นตอนวิธี
Dr.Surasak Mungsing CSE 221/ICT221 การวิเคราะห์และออกแบบขั้นตอนวิธี Lecture 12: เทคนิคการออกแบบขั้นตอนวิธีตอนวิธี Dynamic.
Color Standards A pixel color is represented as a point in 3-D space. Axis may be labeled as independent colors such as R, G, B or may use other independent.
ใบสำเนางานนำเสนอ:

2. Algorithm Analysis

2 Algorithm Analysis Algorithm ก็คือ set ของ instructions (อย่างง่าย) ที่ต้องดำเนินการเพื่อแก้ปัญหา คำ algorithm ที่ใช้ในแวดวงวิทยาการคอมพิวเตอร์ หมายถึงวิธีการซึ่งประกอบด้วยขั้นตอนที่ใช้ในการแก้ปัญหาที่เหมาะสำหรับการใช้คอมพิวเตอร์โปรแกรม สิ่งที่ต้องทำหลังจากมี algorithm แล้ว คือ พิจารณาหาว่าalgorithm นั้นจะต้องใช้ทรัพยากร (resources) มากน้อยแค่ไหน เช่น เนื้อที่หรือเวลาที่ใช้

2 Algorithm Analysis ปกติแล้ว algorithms ที่เราสนใจนั้นมักจะเกี่ยวข้องอยู่กับวิธีการจัดรูปของข้อมูลที่เกี่ยวข้องในบัญหานั้น ๆ เสมอ รูปแบบของข้อมูลที่ได้รับการจัดรูปดังกล่าวนี้ เรียกว่า โครงสร้างข้อมูล (data structures) ดังนั้น algorithms และ data structures จะมักจะปรากฏอยู่ด้วยกันเสมอ algorithms ง่าย ๆ อาจทำให้ต้องใช้โครงสร้างข้อมูลที่ซับซ้อน และในทางตรงกันข้าม algorithms ที่ซับซ้อนอาจสามารถใช้โครงสร้างข้อมูลง่าย ๆ ได้

ในบทนี้จะได้กล่าวถึง Asymptotic notation, functions 2 Algorithm Analysis ในบทนี้จะได้กล่าวถึง Asymptotic notation, functions การประเมินเวลาที่โปรแกรมใช้ในการทำงาน การลดเวลาที่โปรแกรมต้องใช้ (เรียกว่า running time) ผลของการใช้ recursion อย่างไม่ระมัดระวัง ตัวอย่างของอัลกอริทึมที่มีประสิทธิภาพที่ใช้ในการหาค่ายกกำลังและการหาค่า ห.ร.ม.

Asymptotic notation, functions 𝛰 𝑔 𝑛 ={ 𝑓 𝑛 :there exist positive constants c and 𝑛 0 such that 0≤𝑓(𝑛)≤𝑐𝑔 𝑛 for all 𝑛≥ 𝑛 0 }. 𝛺 𝑔 𝑛 ={ 𝑓 𝑛 :there exist positive constants c and 𝑛 0 such that 0≤𝑐𝑔 𝑛 ≤𝑓(𝑛) for all 𝑛≥ 𝑛 0 }. 𝛩 𝑔 𝑛 ={ 𝑓 𝑛 :there exist positive constants 𝑐 1 , 𝑐 2 and 𝑛 0 such that 0≤ 𝑐 1 𝑔 𝑛 ≤𝑓(𝑛) ≤ 𝑐 2 𝑔 𝑛 for all 𝑛≥ 𝑛 0 }.

𝒇 𝒏 =𝛩 𝑔 𝑛 For all values of n at and to the right of n0, the value of 𝑓(𝑛) lies at or above 𝑐 1 𝑔(𝑛) and at or below 𝑐 2 𝑔(𝑛) . In other words, for all 𝑛≥ 𝑛 0 , the function f(n) is equal to g(n) to within a constant factor. We say that g(n) is an asymptotically tight bound for f(n). 𝒇 𝒏 =𝚶 𝑔 𝑛 g(n) is an asymptotically upper bound for f(n). 𝒇 𝒏 =𝛀 𝑔 𝑛 g(n) is an asymptotically lower bound for f(n).

2.1. พื้นฐานคณิตศาสตร์ เบื้องหลังของนิยามเหล่านี้คือ การสร้างสิ่งที่เรียกว่า relative order ระหว่างฟังก์ชันต่าง ๆ นั่นเอง นั่นคือ เพื่อเปรียบเทียบ rates of growth ระหว่างฟังก์ชัน เช่น ถึงแม้ว่า 1000n มีค่ามากกว่า n2 เมื่อ n มีค่าน้อย ๆ อย่างไรก็ตาม n2 จะมีค่าโตขึ้นด้วยอัตราที่เร็วกว่าเมื่อ n มีค่าเพิ่มขึ้น ดังนั้น จึงกล่าวว่า n2 เป็นฟังก์ชันที่มีขนาดใหญ่กว่า ดังนั้น เราสามารถกล่าวได้ว่า 1000n = O(n2) (เรียกว่ามันมี order เป็น n-squared) สัญลักษณ์ที่ใช้นี้เรียกว่า Big-Oh notation และปกติจะใช้คำว่า "Big-Oh . . . ." แทนคำว่า "order . . . ,"

2.1. พื้นฐานคณิตศาสตร์ ตัวอย่าง n3 โตเร็วกว่า n2, ดังนั้นเราอาจกล่าวได้ว่า n2 = O(n3) หรือ n3 = (n2) f(n) = n2 และ g(n) = 2n2 โตด้วยอัตราที่เท่ากัน ดังนั้น f(n) = O(g(n)) และ g(n) = (f(n)) จึงเป็นจริง

o-notation to denote an upper bound that is not asymptotically tight o-notation to denote an upper bound that is not asymptotically tight. We formally define 𝜊 𝑔 𝑛 (“little-oh of g of n”) as the set 𝜊 𝑔 𝑛 ={ f n : for any positive constant c > 0, there exists a constant n0 > 0 such that 0≤𝑓 𝑛 <𝑐𝑔 𝑛 for all n > n0} For example, 2𝑛=𝜊( 𝑛 2 ) but 2 𝑛 2 ≠𝜊( 𝑛 2 ) . 𝑓 𝑛 =𝜊(𝑔 𝑛 ) imply lim 𝑛→∞ 𝑓(𝑛) 𝑔(𝑛) =0 The main difference is that in 𝑓 𝑛 =𝛰 𝑔 𝑛 , the bound 0≤𝑓 𝑛 ≤𝑐𝑔 𝑛 holds for some constant c > 0, but in 𝑓 𝑛 =𝜊 𝑔 𝑛 , the bound 0≤𝑓 𝑛 ≤𝑐𝑔 𝑛 holds for all constants c > 0.

𝜔 𝑔 𝑛 “little-omega of g of n”) as the set 𝜔 𝑔 𝑛 ={ f n : for any positive constant c > 0, there exists a constant n0 > 0 such that 0≤𝑐𝑔 𝑛 <𝑓 𝑛 for all n > n0 }: For example, 𝑛 2 2 =𝜔(𝑛), but 𝑛 2 2 ≠𝜔( 𝑛 2 ). 𝑓 𝑛 =𝜔(𝑔 𝑛 ) 𝑖𝑚𝑝𝑙𝑦 lim 𝑛→∞ 𝑓(𝑛) 𝑔(𝑛) =∞

Transitivity: Reflexivity: Symmetry: Transpose symmetry: 𝑓 𝑛 =𝜃 𝑔 𝑛 𝑎𝑛𝑑 𝑔 𝑛 = 𝜃 ℎ 𝑛 𝑖𝑚𝑝𝑙𝑦 𝑓 𝑛 = 𝜃(ℎ 𝑛 ) 𝑓 𝑛 =𝛰 𝑔 𝑛 𝑎𝑛𝑑 𝑔 𝑛 = 𝛰 ℎ 𝑛 𝑖𝑚𝑝𝑙𝑦 𝑓 𝑛 = 𝛰(ℎ 𝑛 ) 𝑓 𝑛 =𝛺 𝑔 𝑛 𝑎𝑛𝑑 𝑔 𝑛 = 𝛺 ℎ 𝑛 𝑖𝑚𝑝𝑙𝑦 𝑓 𝑛 = 𝛺(ℎ 𝑛 ) 𝑓 𝑛 =𝜊 𝑔 𝑛 𝑎𝑛𝑑 𝑔 𝑛 = 𝜊 ℎ 𝑛 𝑖𝑚𝑝𝑙𝑦 𝑓 𝑛 = 𝜊(ℎ 𝑛 ) 𝑓 𝑛 =𝜔 𝑔 𝑛 𝑎𝑛𝑑 𝑔 𝑛 = 𝜔 ℎ 𝑛 𝑖𝑚𝑝𝑙𝑦 𝑓 𝑛 = 𝜔(ℎ 𝑛 ) Reflexivity: 𝑓 𝑛 =𝜃 𝑓 𝑛 𝑓 𝑛 =𝛰 𝑓 𝑛 𝑓 𝑛 =𝛺 𝑓 𝑛 Symmetry: 𝑓 𝑛 =𝜃 𝑔 𝑛 𝑖𝑓 𝑎𝑛𝑑 𝑜𝑛𝑙𝑦 𝑖𝑓 𝑔 𝑛 = 𝜃 𝑓 𝑛 Transpose symmetry: 𝑓 𝑛 =𝛰 𝑔 𝑛 𝑖𝑓 𝑎𝑛𝑑 𝑜𝑛𝑙𝑦 𝑖𝑓 𝑔 𝑛 = 𝛺 𝑓 𝑛 𝑓 𝑛 =𝜊 𝑔 𝑛 𝑖𝑓 𝑎𝑛𝑑 𝑜𝑛𝑙𝑦 𝑖𝑓 𝑔 𝑛 = 𝜔 𝑓 𝑛

Sn = 3n2 + 15n satisfies Sn = O(n2) 2.1. พื้นฐานคณิตศาสตร์ Sn defined by Sn = 3n2 + 15n satisfies Sn = O(n2) because n < n2 for n > 1 and thus |Sn| < 3n2 + 15n2 = 18 n2 for all large enough n

2.1. พื้นฐานคณิตศาสตร์ Polynomial s(n) 𝑠 𝑛 = 𝑎 𝑚 𝑛 𝑚 + 𝑎 𝑚−1 𝑛 𝑚−1 +…+ 𝑎 0 𝑤𝑖𝑡ℎ 𝑎 𝑚 ≠0 Here n is a variable, and m and the coefficients a0, a1, …am are constants. Since |aknk| < |ak|nm for k = 0, 1,…, m – 1 , we have |s(n)| < |amnm| + |am – 1 nm – 1| +…+ |a0| < (|am| + |am – 1| +…+ |a0|) nm and hence s(n) = O(nm) and the first inequality holds because |x1 + x2 + … + xi| < | x1| + | x2| + … + | xi | for any finite sequence x1, x2 , … , xi in 

Let 𝑓 𝑛 =50 𝑛 3 −6 𝑛 2 +23. Show that 𝑓 𝑛 =𝛰( 𝑛 3 ). Sol 𝑓 𝑛 =50 𝑛 3 −6 𝑛 2 +23 Therefor , 𝑓 𝑛 = 50 𝑛 3 −6 𝑛 2 +23 ≤ 50 𝑛 3 + −6 𝑛 2 + 23 ≤50 𝑛 3 +6 𝑛 2 +23 ≤50 𝑛 3 +6 𝑛 3 +23 𝑛 3 , 𝑤ℎ𝑒𝑛 𝑛 ≥1 ≤79 𝑛 3 Thus, by taking c=79 and n0=1 it follows that 𝑓 𝑛 =𝛰( 𝑛 3 ).

2.1. พื้นฐานคณิตศาสตร์ ถ้า g(n) = 2n2, นั่นคือ g(n) = O(n4), g(n) = O(n3), และ g(n) = O(n2) ในทางเทคนิค ล้วนถูกต้องทั้งสิ้น แต่แน่นอนว่าคำตอบสุดท้ายย่อมเป็นคำตอบที่ดีที่สุด การเขียนว่า g(n) = (n2) ไม่เพียงแต่กล่าวว่า g(n) = O(n2) เท่านั้นแต่ยังหมายถึงว่ามันเป็นคำตอบที่ดีที่สุดเท่าที่จะเป็นได้ด้วย (tight)

If T1(n) = O(f(n)) and T2(n) = O(g(n)), then 2.1. พื้นฐานคณิตศาสตร์ RULE 1: If T1(n) = O(f(n)) and T2(n) = O(g(n)), then (a) T1(n) + T2(n) = max (O(f(n)), O(g(n))), (b) T1(n) * T2(n) = O(f(n) * g(n)) RULE 2: ถ้า T(n) เป็น polynomial ที่มี degree k แล้ว T(n) = (nk) RULE 3: logk n = O(n) สำหรับค่าคงที่ k ใด ๆ ซึ่งหมายความว่า logarithms เป็นฟังก์ชันที่โตช้ามาก

ให้ n0 = max(n1, n2) ดังนั้น ที่ n  n0 แล้ว 2.1. พื้นฐานคณิตศาสตร์ สำหรับ rule 1(a) นิยามมีค่าคงที่ 4 ตัว คือ c1, c2, n1, และ n2 ที่ T1(n)  c1 f(n) สำหรับ n  n1 และ T2(n)  c2g(n) สำหรับ n  n2 ให้ n0 = max(n1, n2) ดังนั้น ที่ n  n0 แล้ว T1(n)  c1f(n) และ T2(n)  c2g(n) จะได้ T1(n) + T2(n)  c1f(n) + c2g(n) ให้ c3 = max(c1, c2) จะได้

2.1. พื้นฐานคณิตศาสตร์ T1(n) + T2(n)  c3f(n) + c3g(n)  c3(f(n) + g(n))  2c3 max(f(n), g(n))  c max(f(n), g(n)) เมื่อ c = 2c3 และ n  n0

2.1. พื้นฐานคณิตศาสตร์ Function Name --------------------------------- c Constant log n Logarithmic log2n Log-squared n Linear n log n n2 Quadratic n3 Cubic 2n Exponential n! Factorial

Approximate values of some of the order functions. lg n n n lg n n2 3 10 30 100 6 600 10,000 9 1,000 9,000 100,000 13 130,000 100,000,000 16 1,600,000 10,000,000,000 19 1,000,000 19,000,000 1,000,000,000,000

Show that n! = O(n n) and lg n! = O(n lgn). SOLUTION: n! = n(n-1) ... 54321 < n  n . . . nnn , where n > 1 = nn = O(nn) Since n! < nn from above, lg n! < n lg n = O(n lg n) (Note: If 0 < x < y, then lg x < lg y.)

เมื่อ n มีค่ามากพอจะพบว่า order functions เปรียบเทียบกันดังนี้ : O(1) < O(lg n) < O(n) < O(n lg n) < O(n2) < O(n3) < O(2n) < O(n!). ถ้ามี 2 algorithm ในการแก้ปัญหาหนึ่ง โดยตัวหนึ่งใช้เวลาเป็น O(n) และอีกตัวใช้เวลาเป็น O(lg n), โดยมีองค์ประกอบอื่น ๆ เหมือนกันทุกอย่าง เรากล่าวได้ว่า อัลกอริทึมที่สองทำงานได้เร็วกว่า ในเทอมของ Big-O จะไม่เขียนระบุค่าคงที่และไม่เขียนระบุเทอมที่มีกำลังน้อยกว่า ดังนั้น จึงไม่เขียน T(n) = O(2n2) หรือ T(n) = O(n2 + n) ทั้งสองกรณีนี้เขียนได้เป็น T(n) = O(n2)

ค่า limit อาจเป็นไปได้ 4 ทาง ดังนี้ 2.1. พื้นฐานคณิตศาสตร์ เราสามารถพิจารณาหา relative growth rates ของฟังก์ชันสองฟังก์ชัน เช่น f(n) และ g(n) ได้ด้วยการคำนวณ lim 𝑛→∞ 𝑓(𝑛) 𝑔(𝑛) ถ้าจำเป็น* ค่า limit อาจเป็นไปได้ 4 ทาง ดังนี้ ถ้า limit เป็น 0: หมายความว่า f(n) = o(g(n)) ถ้า limit เป็นค่าคงที่ c  0: หมายความว่า f(n) = (g(n)) ถ้า limit เป็น : หมายความว่า f(n) = (g(n)) ถ้า limit ขึ้นลง oscillates: หมายความว่า ไม่มีความสัมพันธ์กัน (this will not happen in our context)

2.1. พื้นฐานคณิตศาสตร์ แสดง log n = o(n) เนื่องจากทั้ง log n และ n เข้าสู่  เมื่อ n เข้าสู่  จึงใช้ L’Hopital’s rule กับ (log n)/n เนื่องจาก log n = (log e)*(loge n) ดังนั้น derivative ของ log n คือ (log e)(1/n) นั่นคือ limn-> (log n)’/n’ = limn-> (log e)(1/n)/1 = 0 ดังนั้น log n = o(n). L’Hopital’s rule: ถ้า limn-> f(n) = limn-> g(n) =  หรือ limn-> f(n) = limn-> g(n) = 0 แล้ว limn-> f(n)/g(n) = limn-> f’(n)/g’(n)

2.2. โมเดล (Model) โมเดลที่ใช้ในการคำนวณเพื่อวิเคราะห์อัลกอริทึม การทำงานตาม instructions เป็นแบบ sequential (non-parallel) มี instructions มาตรฐาน เช่น addition, multiplication, comparison, และ assignment ที่ใช้เวลาในการทำงานเป็นหนึ่งหน่วยเวลา (one time unit) เท่านั้น มี fixed size (เช่น 32-bit) integers และไม่มีการทำงานที่ซับซ้อนอื่น ๆ เช่น matrix inversion หรือ sorting ซึ่งแน่นอนว่าไม่สามารถทำให้แล้วเสร็จได้ในหนึ่งหน่วยเวลา มีหน่วยความจำไม่จำกัด (infinite memory)

2.3. สิ่งที่ต้องวิเคราะห์ การใช้ทรัพยากรที่สำคัญที่สุดที่ต้องทำการวิเคราะห์ คือ running time ปัจจัยที่มีผลต่อ running time ของโปรแกรม compiler และ computer ที่ใช้ ซึ่งจะไม่กล่าวถึงในที่นี้ เนื่องจากไม่เกี่ยวข้องกับโมเดลที่เราได้กล่าวไปแล้ว ปัจจัยที่สำคัญ คือ algorithm ที่ใช้และ input โดยทั่วไปแล้วขนาดของ input เป็นสิ่งที่เราจะให้ความสนใจเป็นเรื่องหลัก

2.3. สิ่งที่ต้องวิเคราะห์ กำหนดนิยามสำหรับฟังก์ชัน 2 ตัว คือ Tavg(n) สำหรับ average case running time และ Tworst(n) สำหรับ worst-case running time ของ algorithm ที่ใช้สำหรับอินพุตที่มีขนาดเป็น n และชัดเจนว่า Tavg(n)  Tworst(n) function ข้างบนนี้อาจมีหลาย argument ได้ถ้า algorithm มีหลาย input โดยทั่วไปแล้วค่าที่ต้องหา คือ worst-case time ยกเว้นบางกรณีเท่านั้น

ตัวอย่างปัญหา MAXIMUM SUBSEQUENCE SUM: 2.3. What to Analyze ตัวอย่างปัญหา MAXIMUM SUBSEQUENCE SUM: กำหนดเลขจำนวนเต็มให้ (อาจเป็นค่าลบได้) เป็น a1, a2, . . . , an, หาค่าที่มากที่สุดของ 𝑘=𝑖 𝑗 𝑎 𝑘 (เพื่อความสะดวก กำหนดให้ maximum subsequence sum มีค่าเป็น 0 ถ้าค่าที่กำหนดให้ทั้งหมดมีค่าติดลบ) เช่น: อินพุต -2, 11, -4, 13, -5, -2, จะได้คำตอบ 20 (a2 ถึง a4) มีอัลกอริทึมหลายแบบที่ใช้แก้ปัญหานี้ได้ และแต่ละอัลกอริทึมก็มีประสิทธิภาพแตกต่างกันมาก

Running time ของ 4 อัลกอริทึม (in second): 2.3. What to Analyze Running time ของ 4 อัลกอริทึม (in second): Algorithm Time Input Size 1 2 3 4 O(N3) O(N2) O(NlogN) O(N) N=100 0.000159 0.000006 0.000005 0.000002 N=1,000 0.095857 0.000371 0.000060 0.000022 N=10,000 86.67 0.033322 0.000619 0.000222 N=100,000 NA 3.33 0.006700 0.002205 N=1,000,000 0.074870 0.022711 Note 1: สำหรับอินพุตขนาดเล็กก็ไม่จำเป็นต้องใช้ความพยายามในการคิดหาอัลกอริทึมให้ยุ่งยาก อย่างไรก็ตามมีโปรแกรมในอดีตจำนวนมากที่เขียนขึ้นด้วยการใช้อัลกอริทึมที่อยู่บนสมมุติฐานว่าจำนวนข้อมูลมีปริมาณน้อยซึ่งไม่เป็นจริงในภาวะปัจจุบัน 2: เวลาที่แสดงในตารางไม่นับรวมเวลาในการอ่านข้อมูลอินพุต

2.4 การคำนวณ Running Time เหตุผลที่ต้องทำการวิเคราะห์อัลกอริทึม: ขจัดอัลกอริทึมที่ไม่ดีออกไปตั้งแต่ต้น ทำให้เห็นประสิทธิภาพของอัลกอริทึมได้ชัดเจนขึ้น ทำให้สามารถหาจุดที่เป็นคอขวดของวิธีการแก้ปัญหาซึ่งทำให้ระมัดระวังในการเขียนโปรแกรมในจุดคอขวดต่าง ๆ ได้

2.4. Running Time Calculations เพื่อให้ง่ายแก่การวิเคราะห์ เราจะไม่ระบุหน่วยของเวลาที่ใช้ ไม่นำค่าคงที่ที่อยู่โดด ๆ มาใช้ ไม่นำค่าของเทอมที่มี order ต่ำมาใช้ นั่นคือการคำนวณ Big-Oh running time นั่นเอง

ส่วนของโปรแกรมข้างล่างใช้ในการคำนวณหาค่า 𝑖=1 𝑁 𝑖 3 2.4.1. ตัวอย่างอย่างง่าย ส่วนของโปรแกรมข้างล่างใช้ในการคำนวณหาค่า 𝑖=1 𝑁 𝑖 3 public static int sum( int n ) { int partialsum; /*1*/ partialsum = 0; /*2*/ for (int i = 1; i <= n; i++) /*3*/ partialsum += i * i * i; /*4*/ return (partialsum); }

บรรทัด 1 และ 4 นับเป็นหนึ่งหน่วยเวลาต่อบรรทัด 2.4.1. ตัวอย่างอย่างง่าย การประกาศไม่นับเวลา บรรทัด 1 และ 4 นับเป็นหนึ่งหน่วยเวลาต่อบรรทัด บรรทัด 3 นับเป็น 4 หน่วยเวลาต่อการทำงานหนึ่งครั้ง ( การคูณ 2 ครั้ง บวก 1 ครั้ง และ assignment อีก 1 ครั้ง) และบรรทัดนี้มีการทำงานทั้งสิ้น n ครั้ง, รวมเป็น 4n หน่วยเวลา

ดังนั้นเรากล่าวว่าอัลกอริทึมนี้มี running time เป็น O (n) 2.4.1. A Simple Example บรรทัด 2 ใช้เวลา initializing ตัวแปร i, ทดสอบเงื่อนไข i  n, และการเพิ่มค่า i ดังนั้นรวมเวลา คือ 1 สำหรับการ initialize, n + 1 สำหรับการทดสอบเงื่อนไข และ n หน่วยเวลาสำหรับการเพิ่มค่า ซึ่งเท่ากับ 2n + 2 หน่วยเวลา ถ้าไม่สนใจเวลาที่ใช้ในการเรียกใช้ฟังก์ชันและเวลาในการส่งค่ากลับ แล้ว อัลกอริทึมนี้ก็จะใช้ running time เป็น 6n + 4. ดังนั้นเรากล่าวว่าอัลกอริทึมนี้มี running time เป็น O (n)

จากที่กล่าวมานี้นำมาซึ่งกฎเกณฑ์ทั่วไปที่จะใช้ต่อไป 2.4.1. A Simple Example จากตัวอย่างข้างบน ถ้ากล่าวในแง่ของ Big-Oh ก็มีวิธีลัดที่ง่ายกว่าแต่ให้ผลลัพธ์เช่นเดียวกัน คือ บรรทัด 3 เป็นคำสั่งที่เป็น O (1) (ต่อการทำงานหนึ่งครั้ง), ดังนั้นจึงไม่จำเป็นต้องนับหน่วยเวลาว่าจะมีเท่าใด บรรทัด 1 ใช้หน่วยเวลาที่น้อยมากจนไม่มีความสำคัญเมื่อเทียบกับหน่วยเวลาที่ต้องใช้ทำงานการวนรอบ (for loop), ดังนั้นจึงไม่มีความจำเป็นต้องใส่ใจมัน จากที่กล่าวมานี้นำมาซึ่งกฎเกณฑ์ทั่วไปที่จะใช้ต่อไป

2.4.2. กฎทั่วไป RULE 1-FOR LOOPS: Running time ของ for loop หนึ่ง มีค่ามากที่สุดเท่ากับ running time ของคำสั่งภายใน loop (รวมคำสั่งทดสอบเงื่อนไขด้วย) คูณด้วยจำนวนครั้งของการวนรอบ loop

RULE 2-NESTED FOR LOOPS: 2.4.2. กฎทั่วไป RULE 2-NESTED FOR LOOPS: วิเคราะห์จากภายใน loop ออกมา Running time ทั้งสิ้นของกลุ่มคำสั่งใน loop ซ้อน คือ running time ของคำสั่งคูณด้วยผลคูณของขนาดของ for loops ทั้งหมด ส่วนของโปรแกรมต่อไปนี้มี running time เป็น O(n2): for( i=0; i<n; i++ ) for( j=0; j<n; j++ ) k++;

RULE 3-CONSECUTIVE STATEMENTS: 2.4.2. กฎทั่วไป RULE 3-CONSECUTIVE STATEMENTS: รวม running time ของแต่ละส่วนเข้าด้วยกัน (ซึ่งหมายความว่าจะได้ผลลัพธ์เป็นค่าของตัวที่มากที่สุดนั่นเอง ) ส่วนโปรแกรมต่อไปนี้มี running time O(n) ตามด้วย O(n2) ดังนั้น ทั้งหมดจึงมี running time O (n2) for ( i = 0; i < n; i++) a[i] = 0; //O(n) for ( i = 0; i < n; i++ ) for ( j = 0; j < n; j++ ) a[i] += a[j] + i + j; //O(n2)

2.4.2. กฎทั่วไป RULE 4-lF/ELSE: สำหรับ if( cond ) S1 else S2 Running time ของคำสั่ง if/else หนึ่งจะไม่มากไปกว่า running time ของ การทดสอบเงื่อนไขบวกกับ running time ตัวที่มากระหว่างของ S1 กับ S2

กรณีที่มีการเรียกใช้ routine ให้ทำการวิเคราะห์ routine นั้น ๆ ก่อน 2.4.2. กฎทั่วไป วิธีที่ใช้ในการวิเคราะห์คือ ให้ทำการวิเคราะห์จากส่วนที่อยู่ภายในที่สุดของกลุ่มคำสั่งออกมา กรณีที่มีการเรียกใช้ routine ให้ทำการวิเคราะห์ routine นั้น ๆ ก่อน กรณีเป็น recursive procedures มีทางเลือกในการวิเคราะห์หลายทาง ถ้า recursion นั้นเป็นเพียง routine ที่ใช้ for loop แทนได้ ก็ใช้วิธีที่กล่าวมาแล้ว

นี่เป็นตัวอย่างที่ไม่ดีของการใช้ recursion 2.4.2. กฎทั่วไป ความจริงแล้วฟังก์ชันข้างล่างนี้แทนได้ด้วย loop ง่าย ๆ ดังนั้นมันจึงมี running time เป็น O (n): public static long factorial ( int n ) { if ( n <= 1 ) return 1; else return ( n * factorial(n-1) ); } นี่เป็นตัวอย่างที่ไม่ดีของการใช้ recursion

ให้ T(n) เป็น running time ของฟังก์ชัน fib(n) 2.4.2. กฎทั่วไป โดยทั่วไปแล้วการวิเคราะห์ recursion จะเกี่ยวข้องกับการแก้ปัญหา recurrence relation ดังตัวอย่างต่อไปนี้ public static long fib( int n ) { /*1*/ if ( n <= 1 ) /*2*/ return 1; else /*3*/ return ( fib(n-1) + fib(n-2)); } ให้ T(n) เป็น running time ของฟังก์ชัน fib(n)

2.4.2. กฎทั่วไป ถ้า n = 0 หรือ n = 1, running time คือ ค่าคงที่ ซึ่งคือเวลาที่ใช้ในการทดสอบเงื่อนไขในบรรทัดที่ 1 และการ return ค่า ดังนั้น จึงกล่าวว่า T(0) = T(1) = 1 ได้เนื่องจากค่าคงที่ไม่มีความหมายที่สำคัญ ค่า running time สำหรับค่าอื่น ๆ ของ n จึงหาได้จากการเทียบกับ running time ของ base case สำหรับ n > 2, เวลาที่ใช้ในการทำงานของฟังก์ชันคือ ค่าคงที่ในบรรทัด 1 บวกกับเวลาทำงานในบรรทัด 3

บรรทัด 3 ประกอบด้วยการบวกหนึ่งครั้งและเรียกใช้ฟังก์ชัน 2 ครั้ง 2.4.2. กฎทั่วไป บรรทัด 3 ประกอบด้วยการบวกหนึ่งครั้งและเรียกใช้ฟังก์ชัน 2 ครั้ง เนื่องการเป็นการเรียกใช้ฟังก์ชัน ดังนั้นจึงต้องทำการวิเคราะห์ฟังก์ชันที่ถูกเรียกนั้น ฟังก์ชันที่เรียกใช้ครั้งแรกคือ fib(n - 1) และดังนั้นด้วยนิยามของ T, การเรียกใช้นี้จึงใช้ T(n - 1) หน่วยเวลา ในทำนองเดียวกัน การเรียกใช้อีกครั้งหนึ่งจึงใช้ T(n - 2) หน่วยเวลา

2.4.2. กฎทั่วไป ดังนั้นเวลาทั้งหมดที่ต้องใช้ คือ T(n - 1) + T(n - 2) + 2, เมื่อ 2 คือค่าเวลาที่ใช้ในบรรทัดที่ 1 บวกด้วยเวลาการบวกในบรรทัดที่ 3. ดังนั้น สำหรับ n  2, จะได้สมการของ running time ของฟังก์ชัน fib(n) เป็น: T(n) = T(n - 1) + T(n - 2) + 2 T(0) = T(1) = O(1) T(N) < (5/3)N T(N) = O((5/3)N)

Power(x,n) compute 𝑥 𝑛 = 𝑥∙𝑥∙𝑥⋯𝑥 𝑛 assume x and n are integer n > 0 public static int pow(int x,int n) { int i; int y=1; for(i=1;i<=n;i++) y *=x; return y; } Runtime O(n)

Power(x,n) compute 𝑥 𝑛 = 1 𝑤ℎ𝑒𝑟𝑒 𝑛=0 𝑥∙ 𝑥 𝑛−1 public static int pow(int x,int n) { if(n==0) return 1; return x * pow(x,n-1); } Runtime T(n) = T(n-1) + 1 T(0) = 1

T(n) = T(n-1) + 1 T(n-1) = T(n-2) + 1 … T(0) = 1 T(n) = T(n-2) + 1 + 1 = T(n-3) + 1 + 1 + 1 = T(0) + 1+1+ … + 1 = n = O(n)

Power(x, n) compute 𝑥 𝑛 = 1 𝑤ℎ𝑒𝑟𝑒 𝑛=0 𝑥 𝑛 2 ∙ 𝑥 𝑛 2 assume x and n are integer public static int pow( int x, int n) { if(n==0) return 1; return ( pow(x,Math.floor(n/2.0)) * pow(x,Math.ceil(n/2.0))); } Runtime 𝑇 𝑛 =𝑇 𝑛 2 +𝑇 𝑛 2 +1 T(n) = 2T(n/2) + 1

public static int pow( int a, int n) { if ( n == 0 ) { return 1; } if ( n % 2 == 1 ) { // Odd n return x * pow( x, n/2 ) * pow(x, n/2 ); } else { // Even n return pow( x, n/2 ) * pow( x, n/2 ); } Runtime T(n) = 2T(n/2) + 2

T(n) = 2T(n/2) + c T(n/2) = 2T( (n/2)/2 ) + c T(n/4) = 2T( (n/4)/2 ) + c … T(0) = 1 T(n) = 2 (2T( (n/2)/2 ) + c) + c = 22 T(n/4) + 2c + c = 22 (2T( (n/4)/2 ) + c) + 2c + c = 23T(n/8)+ 22 c+ 2c + c

T(n) = 2T(n/2) + c T(n) c T(n/2) c c T(n/4) c T(n/4)

Height of the tree(h) = lg(n) Number of leaves = 2h=2lg(n)=n T(n)=C+2∗C+22∗C+⋯+2lg(n)∗C + nT(1) T(n)=(2n−1)*C + n = O(n) 𝑖=0 𝑁 2 𝑖 = 2 𝑁+1 −1

public static int pow( int a, int n) { if ( n == 0 ) { return 1; } int powerOfHalfN = pow( x, n/2 ); if ( n % 2 == 1 ) { // Odd n return (x * powerOfHalfN * powerOfHalfN); } else { // Even n return ( powerOfHalfN } Runtime T(n) = T(n/2) + c

T(n) = T(n/2) + c T(n/2) = T( (n/2)/2 ) + c T(n/4) = T( (n/4)/2 ) + c … T(0) = 1 T(n) = (T( (n/2)/2 ) + c) + c = T(n/4) + c + c = (T( (n/4)/2 ) + c) + c + c = T(n/8)+ c+ c + c ... = T(0) + c*lg(n) = O(lg(n))

2.4.3 การหาค่า Maximum Subsequence Sum Problem อัลกอริทึม 1: มี running time เป็น Cubic public static int maxSubSum1(int [ ] a) { /* 1*/ int maxSum = 0; /* 2*/ for(int i = 0; i < a.length; i++) /* 3*/ for( int j = i; j < a.length; j++ ) /* 4*/ int thisSum = 0; /* 5*/ for( int k = i; k <= j; k++ ) /* 6*/ thisSum += a[ k ]; /* 7*/ if( thisSum > maxSum ) /* 8*/ maxSum = thisSum; } /* 9*/ return maxSum; loop นี้มีขนาด n loop นี้มีขนาด n - i, มีค่า n ได้ loop นี้มีขนาด j - i + 1, ซึ่งอาจมีค่าสูงสุดถึง n ได้ รวมเวลาทั้งสิ้น คือ O(1 * n * n * n) = O(n3)

2.4.3 การหาค่า Maximum Subsequence Sum Problem การวิเคราะห์ที่ละเอียดถูกต้องกว่าหาได้จากการหาผลบวก 𝑖=0 𝑛−1 𝑗=𝑖 𝑛−1 𝑘=𝑖 𝑗 1 ซึ่งหาค่าได้โดยขั้นแรก จะได้ 𝑘=𝑖 𝑗 1 =𝑗−𝑖+1 จากนั้น หาค่า 𝑗=𝑖 𝑛−1 (𝑗−𝑖+1 )= (𝑛−𝑖+1)(𝑛−𝑖) 2 ซึ่งก็คือการหาผลบวกของ n - i ตัวแรกนั่นเอง

2.4.3 การหาค่า Maximum Subsequence Sum Problem จากนั้นจัดเทอมต่าง ๆ ใหม่ 𝑖=0 𝑛−1 (𝑛−𝑖+1)(𝑛−𝑖) 2 = 𝑖=1 𝑛 (𝑛−𝑖+1)(𝑛−𝑖+2) 2 = 1 2 𝑖=1 𝑛 𝑖 2 −(𝑛+ 3 2 ) 𝑖=1 𝑛 𝑖 + 1 2 ( 𝑛 2 +3𝑛+2) 𝑖=1 𝑛 1 = 1 2 𝑛(𝑛+1)(2𝑛+1) 6 − 𝑛+ 3 2 𝑛 𝑛+1 2 + 𝑛 2 +3𝑛+2 2 𝑛 = 𝑛 3 +3 𝑛 2 +2𝑛 6

2.4.3 การหาค่า Maximum Subsequence Sum Problem อัลกอริทึม 2: อัลกอริทึมที่ดีขึ้น, O(n2) public static int maxSubSum2( int [ ] a ) { /* 1*/ int maxSum = 0; /* 2*/ for( int i = 0; i < a.length; i++ ) /* 3*/ int thisSum = 0; /* 4*/ for( int j = i; j < a.length; j++ ) /* 5*/ thisSum += a[ j ]; /* 6*/ if( thisSum > maxSum ) /* 7*/ maxSum = thisSum; } /* 8*/ return maxSum;

i j i j i j i j /* 3*/ int thisSum = 0; for( int j = i; j < a.length; j++ ){ /* 4*/ int thisSum = 0; /* 5*/ for( int k = i; k <= j; k++ ) /* 6*/ thisSum += a[ k ]; i j i j /* 3*/ int thisSum = 0; /* 4*/ for( int j = i; j < a.length; j++ ){ /* 5*/ thisSum += a[ j ];

2.4.3 การหาค่า Maximum Subsequence Sum Problem อัลกอริทึม 3: ซับซ้อนขึ้นและใช้ recursive: O(n log n) แบ่งปัญหาออกเป็นสองปัญหาย่อยโดยแต่ละปัญหามีขนาดเป็นครึ่งหนึ่งของปัญหาเดิม จากนั้นจึงแก้ปัญหาย่อยนั้นด้วยวิธี recursive ค่า maximum subsequence sum อาจเกิดขึ้นได้จากสามพื้นที่ด้วยกันคือ เกิดจากค่าที่อยู่ด้านซ้ายทั้งหมด หรือ เกิดจากค่าที่อยู่ด้านขวาทั้งหมด หรือ เกิดจากค่าที่อยู่คร่อมทั้งสองข้าง

2.4.3 การหาค่า Maximum Subsequence Sum Problem พิจารณาอินพุตต่อไปนี้: First Half Second Half 4 -3 5 -2 -1 2 6 -2 Maximum subsequence sum ของครึ่งแรกคือ 6 (จาก a1 ถึง a3), และของครึ่งหลังคือ 8 (จาก a6 ถึง a7) Maximum sum ของครึ่งแรกที่รวมตัวสุดท้ายของครึ่งแรกไว้ด้วยคือ 4 (จาก a1 ถึง a4), และ maximum sum ในครึ่งหลังที่รวมตัวแรกของครึ่งหลังไว้ด้วยคือ 7 (จาก a5 ถึง a7) ดังนั้น maximum sum ที่คร่อมทั้งสองส่วนโดยรวมตัวกลางไว้ด้วย คือ 4 + 7 = 11 (จาก a1 ถึง a7)

2.4.3 การหาค่า Maximum Subsequence Sum Problem เรียกใช้ครั้งแรกด้วยค่า left = 0 และ right = n -1 private static int maxSumRec(int [ ] a, int left, int right) { /* 1*/ if( left == right ) // Base case /* 2*/ if( a[ left ] > 0 ) /* 3*/ return a[ left ]; else /* 4*/ return 0; /* 5*/ int center = ( left + right ) / 2; /* 6*/ int maxLeftSum = maxSumRec( a, left, center ); /* 7*/ int maxRightSum = maxSumRec( a, center + 1, right ); Base case ใช้ 1 unit time Two recursive called

/* 8*/ int maxLeftBorderSum = 0, leftBorderSum = 0; /* 9*/ for( int i = center; i >= left; i-- ) { /*10*/ leftBorderSum += a[ i ]; /*11*/ if( leftBorderSum > maxLeftBorderSum ) /*12*/ maxLeftBorderSum = leftBorderSum; } /*13*/ int maxRightBorderSum = 0, rightBorderSum = 0; /*14*/ for( int i = center + 1; i <= right; i++ ) /*15*/ rightBorderSum += a[ i ]; /*16*/ if( rightBorderSum > maxRightBorderSum ) /*17*/ maxRightBorderSum = rightBorderSum; /*18*/ return max3( maxLeftSum, maxRightSum, /*19*/ maxLeftBorderSum + maxRightBorderSum );

2.4.3 การหาค่า Maximum Subsequence Sum Problem /*1 /** Driver for divide-and-conquer maximum contiguous subsequence sum algorithm. */ public static int maxSubSum3( int [ ] a ) { return maxSumRec( a, 0, a.length - 1 ); } /** Return maximum of three integers. */ private static int max3( int a, int b, int c ) return a > b ? a > c ? a : c : b > c ? b : c;

2.4.3 การหาค่า Maximum Subsequence Sum Problem เวลาทั้งหมดของอัลกอริทึม คือ T(n) = 2T(n/2) + O(n) ดังนั้น จะได้สมการ: T(1) = 1 เพื่อให้ง่ายแก่การคำนวณ เราสามารถแทนที่เทอม O(n) ในสมการได้ด้วย n; เนื่องจาก T(n) จะได้รับการให้ความหมายด้วย Big-Oh ซึ่งการแทนที่เทอม O(n) ด้วย n จึงไม่มีผลกับคำตอบ

2.4.3 การหาค่า Maximum Subsequence Sum Problem ดังนั้น ถ้า T(n) = 2T(n/2) + n, และ T(1) = 1, แล้วจะได้ว่า T(2) = 4 = 2 * 2, T(4) = 12 = 4 * 3, T(8) = 32 = 8 * 4, T(16) = 80 = 16 * 5 จากนี้จะเห็นได้ว่า ถ้าให้ n = 2k แล้ว T(n) = n * (k + 1) = n log n + n = O(n log n) การวิเคราะห์นี้กำหนดให้ n เป็นเลขคู่ มิฉะนั้นแล้วจะไม่สามารถหาค่า n/2 ได้

2.4.3 การหาค่า Maximum Subsequence Sum Problem อัลกอริทึม 4: ง่ายกว่าและมีประสิทธิภาพกว่าการใช้ recursive /** Linear-time maximum contiguous subsequence sum algorithm. */ public static int maxSubSum4( int [ ] a ) { /* 1*/ int maxSum = 0, thisSum = 0; /* 2*/ for( int j = 0; j < a.length; j++ ) /* 3*/ thisSum += a[ j ]; /* 4*/ if( thisSum > maxSum ) /* 5*/ maxSum = thisSum; /* 6*/ else if( thisSum < 0 ) /* 7*/ thisSum = 0; } /* 8*/ return maxSum;

2.4.3 การหาค่า Maximum Subsequence Sum Problem อัลกอริทึม 4.1: /** Linear-time maximum contiguous subsequence sum algorithm. */ public static int maxSubSum5( int [ ] a ) { /* 1*/ int maxSum = a[0], thisSum = a[0]; /* 2*/ for( int j = 1; j < a.length; j++ ) /* 3*/ thisSum += a[ j ]; /* 4*/ thisSum = max(thisSum,a[j]); /* 5*/ maxSum = max(maxSum,thisSum); } /* 7*/ return maxSum;

Kadane's algorithm Kadane's algorithm begins with a simple inductive question: if we know the maximum subarray sum ending at position i, what is the maximum subarray sum ending at position i+1? The answer turns out to be relatively straightforward: either the maximum subarray sum ending at position i+1 includes the maximum subarray sum ending at position i as a prefix, or it doesn't. 𝑀 𝑡 =max⁡(0, 𝑀 𝑡−1 +𝐴 𝑡 ) Thus, we can compute the maximum subarray sum ending at position i for all positions i by iterating once over the array. As we go, we simply keep track of the maximum sum we've ever seen.

2.4.4 Running Time ที่มีค่าเป็น Logarithms กฎทั่วไป: อัลกอริทึมจะมี running time เป็น O(log n) ถ้ามันใช้เวลาคงที่ (O(1)) เพื่อที่จะลดขนาดของปัญหาลงเป็นสัดส่วนที่แน่นอนหนึ่ง (ซึ่งปกติจะเป็น 1/2) ในอีกด้านหนึ่ง ถ้าอัลกอริทึมต้องใช้เวลาที่คงที่ในการลดขนาดของปัญหาลงเป็นจำนวนที่คงที่หนึ่ง (เช่นลดขนาดของปัญหาลงได้ทีละ 1), อัลกอริทึมนั้นก็จะเป็น O(n)

2.4.4 Running Time ที่มีค่าเป็น Logarithms Binary Search Euclid's Algorithm Exponentiation กำหนดให้ x เป็นเลขจำนวนเต็มและชุดเลขจำนวนเต็ม a1, a2, . . . , an, ที่มีการจัดเรียงแล้วอยู่ในหน่วยความจำ, ให้หาค่า i ที่ ai = x, หรือให้ i = -1 ถ้า x ไม่เท่ากับค่า a ใด ๆ

2.4.4 Running Time ที่มีค่าเป็น Logarithms /* Performs the standard binary search. @return index where item is found, or -1 if not found */ public static int binarySearch( Comparable[ ] a, Comparable x ) { /* 1*/ int low = 0, high = a.length - 1; /* 2*/ while( low <= high ) /* 3*/ int mid = ( low + high ) / 2; /* 4*/ if( a[ mid ].compareTo( x ) < 0 ) /* 5*/ low = mid + 1; /* 6*/ else if( a[ mid ].compareTo( x ) > 0 ) /* 7*/ high = mid - 1; else /* 8*/ return mid; // Found } /* 9*/ return NOT_FOUND; // NOT_FOUND is defined as -1 loop เริ่มต้นด้วย high - low = n - 1 และจบด้วย high - low > -1 แต่ละครั้งใน loop ค่า high - low มีค่าอย่างน้อยครึ่งหนึ่งของค่าเดิมก่อนหน้านั้น; ดังนั้น, จำนวนครั้งในการวนรอบจึงมีอย่างมากที่สุด log(n - 1) + 2 ครั้ง

2.4.4 Running Time ที่มีค่าเป็น Logarithms Euclid's Algorithm: เพื่อคำนวณหา ห.ร.ม. ค่า m > n เสมอ public static long gcd( long m, long n ) { /* 1*/ while( n != 0 ) /* 2*/ long rem = m % n; /* 3*/ m = n; /* 4*/ n = rem; } /* 5*/ return m; ความจริงเศษที่เหลือไม่ได้ลดลงในอัตราส่วนที่คงที่ในการทำงานแต่ละรอบ อย่างไรก็ตามหลังจากการทำงานสองรอบแล้วเศษที่เหลือมีค่าสูงสุดได้เพียงครึ่งหนึ่งของค่าเดิมของมัน ดังนั้นจำนวนรอบการทำงานมากที่สุดคือ 2 log n = O(log n)

2.4.4 Running Time ที่มีค่าเป็น Logarithms THEOREM 2.1 ถ้า m > n, แล้ว m mod n < m/2 PROOF: แบ่งเป็นสองกรณี คือ ถ้า n < m/2, แล้วเห็นได้เลยว่าทฤษฎีเป็นจริง เนื่องจากเศษที่ได้จะน้อยกว่าค่า n กรณีที่ n > m/2 แล้ว n จะหาร m ครั้งหนึ่งโดยมีเศษที่ได้คือ m - n ซึ่งจะน้อยกว่า m/2, ดังนั้นทฤษฎีเป็นจริง

2.4.5 การตรวจสอบอัลกอริทึม หลังการวิเคราะห์อัลกอริทึมแล้วก็จะเป็นการตรวจสอบดูว่าการวิเคราะห์ของเราถูกต้องมากน้อยแค่ไหน วิธีการหนึ่งคือการเขียนโปรแกรมแล้วทดลองรันโปรแกรมเพื่อดูว่า running time ใกล้เคียงกับที่ได้วิเคราะห์หรือไม่ ถ้า N เพิ่มขึ้นสองเท่าแล้ว running time เพิ่มขึ้นสองเท่าด้วยนั่นหมายความว่า running time เป็น linear time ถ้า N เพิ่มขึ้นสองเท่าแล้ว running time เพิ่มขึ้นสี่เท่า นั่นหมายความว่า running time เป็น quadratic

2.4.5 การตรวจสอบอัลกอริทึม ถ้า N เพิ่มขึ้นสองเท่าแล้ว running time เพิ่มขึ้นแปดเท่า นั่นหมายความว่า running time เป็น cubic โปรแกรมที่มี running time เป็น logarithmic จะใช้เวลาเพิ่มขึ้นเป็นค่าคงที่เมื่อ N เพิ่มขึ้นสองเท่า และโปรแกรมที่มี running time เป็น O(N log N) ใช้เวลาเพิ่มขึ้นกว่าสองเท่าเล็กน้อยเมื่อ N เพิ่มขึ้นสองเท่า การเพิ่มขึ้นดังกล่าวมานั้นจะสังเกตเห็นได้ยาก ถ้าหากว่าสัมประสิทธิของเทอมที่มีกำลังต่ำ ๆ มีค่าสูงมาก ๆ และ N มีค่าไม่สูงมากพอ นอกจากนี้ยังเป็นเรื่องยากที่จะเห็นความแตกต่างระหว่าง linear จาก O(N log N)

2.4.5 การตรวจสอบอัลกอริทึม อีกวิธีที่ใช้ตรวจสอบว่าโปรแกรมเป็น O(f(n)) คือ คำนวณหาค่าของ T(N) / f(N) สำหรับช่วงของค่า N (ซึ่งปกติคือให้มีระยะห่างสองเท่า) เมื่อ T(N) เป็น running time ที่เราวิเคราะห์ได้ ถ้า f(N) เป็นคำตอบของ running time ที่ใกล้เคียงมาก (หรือถูกต้อง) แล้วค่าที่จากการคำนวณจะ converge เข้าหาค่าคงที่บวก ถ้า f(N) เป็นการ over estimate แล้วค่าที่จากการคำนวณจะ converge เข้าหาค่าศูนย์ ถ้า f(N) เป็นการ under estimate (ซึ่งผิด) แล้วค่าที่จากการคำนวณจะ diverge