เอกสารประกอบการอบรม Greedy Algorithms ค่ายคอมพิวเตอร์โอลิมปิก สอวน. ค่าย 2 2/2565 ศูนย์โรงเรียนสามเสนวิทยาลัย - มหาวิทยาลัยธรรมศาสตร์ ระหว่างวันที่ 20 มีนาคม – 4 เมษายน 2566 โดย สาขาวิชาวิทยาการคอมพิวเตอร์ คณะวิทยาศาสตร์และเทคโนโลยี มหาวิทยาลัยธรรมศาสตร์ 1 DAY_8_28032023 อัลกอริทึม 4-1 (Day 8): - Greedy Algorithms ผศ.ดร.ฐาปนา บุญชู 28 มีนาคม 2566 Greedy Algorithms 3 Rod cutting 4 Rod Cutting • A company buys long steel rods and cuts them into shorter rods, which it then sells. • We assume that we know, for 𝑖 = 1,2, …, the price 𝑝𝑖 in dollars that the company charges for a rod of length i inches. Rod-cutting problem: Given a rod of length 𝑛 inches and a table of prices 𝑝𝑖 for 𝑖 = 1,2, …, determine the maximum revenue 𝑟𝑛 obtainable by cutting up the rod and selling the pieces. 5 Rod Cutting Example • Consider the case when 𝑛 = 4, 6 Rod Cutting Example 7 Greedy Algorithms • Algorithms สาหรับปั ญหา Optimization โดยปรกติจะเป็ นการเดินแต่ละ Step ใน Sequence หนึ่ง โดยการเดินแต่ละ Step จะต้องเลือกว่าจะเดินไป ทางไหนดี • สาหรับบางปั ญหาทีเ่ ป็ น Optimization การใช้ Dynamic Programming เพือ่ หา Optimal solution จะเหมือนขีช่ า้ งจับตักแตน ๊ (Overkill) • Greedy algorithm (ขัน้ ตอนวิธลี ะโมบ) นัน้ จะเลือกทางทีด่ ที ส่ี ดุ “At the moment” (Locally) หมายถึงเลือกทางเลือกที่ Optimal ทีส่ ดุ ใน Step ล่าสุด เพือ่ หวังว่าการนี้จะพาไปสู่ Globally optimal solution • แต่การเลือกในลักษณะนี้ สุดท้ายแล้วอาจจะไม่ได้ Optimal solution ก็ได้ แต่ สาหรับหลาย ๆ ปั ญหามันสามารถหาได้ ! 8 An activity-selection problem 9 An activity-selection problem • ปั ญหาคือการจัดการกิจกรรม (Activities) ทีม่ กี ารใช้ ทรัพยากรร่วมกัน โดยทีต่ อ้ งการหาเซตของกิจกรรมที่ ได้จานวนกิจกรรมเยอะทีส่ ดุ โดยทีก่ จิ กรรมทีเ่ หล่านัน้ ต้องเป็ น Compatible activities (Mutually) • ให้ 𝑆 = {𝑎1 , 𝑎2 , … . 𝑎𝑛 } เป็ นเซตของ n กิจกรรมทีม่ กี ารใช้ทรัพยากรร่วมกัน • แต่ละกิจกรรม 𝑎𝑖 จะมีเวลาเริม่ ต้น 𝑠𝑖 และเวลาสิน้ สุด 𝑓𝑖 โดยที่ 0 ≤ 𝑠𝑖 ≤ 𝑓𝑖 ≤ ∞ • กิจกรรม 𝑎𝑖 และ 𝑎𝑗 จะ Compatible เมือ่ ช่วงเวลาใช้ ทรัพยากร [𝑠𝑖 , 𝑓𝑖 ) และ [𝑠𝑗 , 𝑓𝑗 ) ไม่ซอ้ นทับกัน 10 An activity-selection problem • สาหรับ Activity-selection problem เราต้องการหา Maximum-size subset of mutually compatible activities • พิจารณา Sub-problems *เรียงตามเวลาสิ้นสุดของกิจกรรม • สมมติวา่ 𝑆𝑖𝑗 คือเซตของกิจกรรมทีเ่ ริม่ หลังจากทีก่ จิ กรรม 𝑎𝑖 สิน้ สุดและเสร็จสิน้ ก่อน 𝑎𝑗 เริม่ • และเราต้องการหา Maximum set of mutually compatible activities 𝐴𝑖𝑗 ใน 𝑆𝑖𝑗 นี้ทร่ี วมบางกิจกรรม 𝑎𝑘 เข้าไปด้วย • การรวม 𝑎𝑘 เข้าไปใน Optimal solution 𝐴𝑖𝑗 นัน้ ทาให้เกิด 2 Sub-problems คือ 𝑆𝑖𝑘 and 𝑆𝑘𝑗 • โดยให้ 𝐴𝑖𝑘 = 𝐴𝑖𝑗 ∩ 𝑆𝑖𝑘 และ 𝐴𝑘𝑗 = 𝐴𝑖𝑗 ∩ 𝑆𝑘𝑗 • จะได้วา่ 𝐴𝑖𝑗 = 𝐴𝑖𝑘 ∪ 𝑎𝑘 ∪ 𝐴𝑘𝑗 • ทาให้ 𝐴𝑖𝑗 ของ 𝑆𝑖𝑗 ประกอบไปด้วยจานวนกิจกรรมทัง้ หทด 𝐴𝑖𝑗 = 𝐴𝑖𝑘 + 𝐴𝑘𝑗 + 1 activities. 11 An activity-selection problem • กาหนดให้ขนาดของ Optimal solution ใน 𝑆𝑖𝑗 ด้วย 𝑐 𝑖, 𝑗 และจากการวิเคราะห์ก่อน หน้าเราสามารถเขียนความสัมพันธ์ได้วา่ 𝑐 𝑖, 𝑗 = 𝑐 𝑖, 𝑘 + 𝑐 𝑘, 𝑗 + 1 • ในกรณีทเ่ี ราไม่รวู้ า่ Optimal solution ใน 𝑆𝑖𝑗 นัน้ มี 𝑎𝑘 อยูต่ รงไหน เราต้องหาทุก ๆ กรณีทเ่ี ป็ นไปได้ กล่าวคือ 12 An activity-selection problem • Making a greedy choice • หากในแต่ละ Step การเลือก Activity มาใส่ใน Optimal solution โดยไม่จาเป็ นต้องพิจารณา หรือไม่ตอ้ งรู้ Optimal solution ของ Subproblems ก่อน • หากเป็ นไปได้เราจะไม่จาเป็ นต้องพิจารณาทุก ๆ Subproblems ก่อนหน้าและช่วยเรา ประหยัดเวลาในการประมวลผลได้ • ใน Activity selection problem นี้เราพิจารณาเพียง Choice เดียวก็เพียงพอคือ “Greedy choice” • ด้วย Common sense เราน่าจะเลือก Activity ที่ทาให้เราเหลือเวลาสาหรับทากิจกรรมอื่นให้ เยอะมากที่สดุ • ด้วยแนวคิดนี้ให้เราเลือกกิจกรรมในเซต 𝑆 ทีเ่ วลา Finish time เกิดขึน้ เร็วทีส่ ดุ เพือ่ จะให้เหลือเวลาทา กิจกรรมอื่นให้เยอะมากทีส่ ดุ 13 An activity-selection problem •Making a greedy choice (ต่อ) • เนื่องจากกิจกรรมนัน้ ถูกเรียงลาดับตามเวลาสิน้ สุดมาอยูแ่ ล้วกิจกรรมแรกทีเ่ รา จะเลือกคือ 𝑎1 • และหากเราพิจารณาเลือก Greedy choice นี้เราจะเหลือเพียง 1 Subproblem ทีต่ อ้ ง Solve นันคื ่ อ หากิจกรรมหลัง 𝒂𝟏 สิน้ สุด • Let 𝑆𝑘 = {𝑎𝑖 ∈ 𝑆: 𝑠𝑖 ≥ 𝑓𝑘 } เป็ นเซตทีม่ กี จิ กรรมทีเ่ กิดขึน้ หลังเวลาสิ้นสุด ของ 𝒂𝒌 • ** หมายความว่า เมือ่ เรา Make greedy choice สาหรับ Activity 𝑎1 แล้ว 𝑆1 จะ กลายเป็ นเพียง 1 Subproblem เท่านัน้ ทีต่ อ้ งแก้ต่อไป 14 An activity-selection problem • คาถามคือ Greedy choice ทีเ่ ราเลือกมันถูกต้องแล้วหรือไม่ เพียงแค่เลือกกิจกรรมอันที่ สิน้ สุดก่อนใน Subproblem นี้ และจะแน่ใจได้อย่างไรว่า 𝒂𝒌 ทีเ่ ลือกนัน้ เป็ นส่วนหนึ่งของ Optimal solution Consider any nonempty subproblem 𝑆𝑘 , and let 𝑎𝑚 be an activity in 𝑆𝑘 with the earliest finish time. Then 𝑎𝑚 is included in some maximum-size subset of mutually compatible activities of 𝑆𝑘 . 15 An activity-selection problem • Greedy algorithm ทีใ่ ช้ในการแก้ปัญหา Activity selection problem นัน้ มีการใช้ Top-down approach กล่าวคือ มันเลือก Activity แล้วใส่เข้าไปในเซตคาตอบที่ เป็ น Optimal solution แล้วก็ทาการเลือก Activity อื่น ๆ ที่ Compatible กับ Activity ทีเ่ คยเลือกไปแล้วต่อ • ซึง่ Greedy algorithms ส่วนใหญ่จะมีการทางานในลักษณะนี้คอื Make choice แล้ว Solve subproblem 16 A recursive greedy algorithm • RECURSIVEACTIVITY-SELECTOR รับพารามิเตอร์ • • • • s: start times f: finish times k: ใช้ในการกาหนด sub problem 𝑆𝑘 n: size ของ Original problem • RECURSIVEACTIVITY-SELECTOR คืนค่า maximum-size set of mutually compatible activities in 𝑆𝑘 • Assumption: สมมติวา่ ทุก ๆ Activities ถูกเรียงลาดับด้วย Finish times มาเรียบร้อยแล้ว Time complexity: 𝜣 𝒏 ; Assuming that the activities were already sorted initially by their finish times. 17 18 An iterative greedy algorithm f[k] จะเป็ นเวลาที่ ak สิ ้นสุดเสมอ Time complexity: 𝜣 𝒏 ; Assuming that the activities were already sorted initially by their finish times. 19 6 Steps • 1. ระบุ Optimal substructure ของปั ญหา • 2. พัฒนา Recursive solution • 3. พิจารณาว่าหากเรา Make the greedy choice จะมีเพียง 1 Subproblem เหลืออยู่ • 4. พิสจู น์ความถูกต้องในการ Make the greedy choice • 5. พัฒนา Recursive algorithm • 6. แปลง Recursive algorithm ไปเป็ น Iterative algorithm 20 Exercise • ให้นกั เรี ยนเขียนโปรแกรมเพื่อแก้ปัญหาการเลือกทากิจกรรม (Activity Selection Problem) โดยใช้ Greedy method. • ให้ลองทดสอบกับ Inputs ต่อไปนี้ 𝑖 1 2 3 4 5 6 7 8 9 10 11 𝑠𝑖 1 3 0 5 3 5 6 8 8 2 12 𝑓𝑖 4 5 6 7 9 9 10 11 12 14 16 𝑖 1 2 3 4 5 6 𝑠𝑖 5 1 3 0 5 8 𝑓𝑖 9 2 4 6 7 9 21 Exercise • ให้นกั เรี ยนเขียนโปรแกรมเพื่อแก้ปัญหาตารวจจับโจร • กาหนดให้ Array มาให้เพื่อแสดงตาแหน่งโจร (T) และตาแหน่งของตารวจ (P) เช่น • Positions [] = {'P', 'T', 'P', 'T', 'T', 'P’} และกาหนดค่าความสามารถของการจับโจรของ ตารวจ (K) โดยค่า K คือระยะห่างที่ตารวจจะจับโจรได้ • โจทย์ ให้นกั เรี ยนเขียนโปรแกรมเพือ่ ช่วยหาว่าจะมีตารวจกี่คนที่สามารถจับโจรได้ • ตัวอย่าง [1]Input: {'P', 'T', 'P', 'T', 'T', ‘P’}, K = 3 Output: 3 [2] Input: {'P', 'T', 'T', 'P', ‘T’}, K=1 Output: 1 • Greedy Choice: ให้พิจารณาตาแหน่งของตารวจและโจรแบบ Relative เรื่ อยๆ หาก index ใครน้อยกว่า ให้เพิม่ index ของคนนั้น ในกรณี ที่ตารวจจับโจรได้ให้ขยับ index ของทั้งคู่ 22 0-1 knapsack problem 23 0-1 knapsack problem • A thief robbing a store finds 𝑛 items. • The 𝑖th item is worth 𝑣𝑖 dollars and weighs 𝑤𝑖 pounds, where 𝑣𝑖 and 𝑤𝑖 are integers. • The thief wants to take as valuable a load as possible, but he can carry at most 𝑊 pounds in his knapsack, for some integer 𝑊. Which items should he take? In the fractional knapsack problem, the setup is the same, but the thief can take fractions of items, rather than having to make a binary (0-1) choice for each item. 24 An example showing that the greedy strategy does not work for the 0-1 knapsack problem. (a) The thief must select a subset of the three items shown whose weight must not exceed 50 pounds. (b) The optimal subset includes items 2 and 3. Any solution with item 1 is suboptimal, even though item 1 has the greatest value per pound. (c) For the fractional knapsack problem, taking the items in order of greatest value per pound yields an optimal solution. 25 Coin Change 26 Coin Change • กาหนดจานวนเงิน 𝑉 บาท และ List ของมูลค่าเหรียญทีส่ ามารถแลกเป็ นเงินทอนได้ (𝑛 ชนิด) กล่าวคือ 𝑐𝑜𝑖𝑛𝑉𝑎𝑙𝑢𝑒[𝑖] บาท สาหรับเหรียญประเภท 𝑖 ∈ [0, … , 𝑛 − 1] • โจทย์: หาจานวนเหรียญทีน่ ้อยทีส่ ดุ ทีจ่ ะใช้ในการทอน *สมมติวา่ เรามีเหรียญทุกชนิดไม่จากัดจานวน • ตัวอย่าง 𝑛 = 4, 𝑐𝑜𝑖𝑛𝑉𝑎𝑙𝑢𝑒 = {25, 10, 5, 1} และเราต้องการ 𝑉 = 42 บาท • Greedy algorithm (Greedy choice): เลือกเหรียญทีม่ ขี นาดใหญ่สดุ มาทอนก่อนเสมอ • 42-25 = 17 → 17-10 = 7 → 7-5 = 2 → 2-1 = 1 → 1-1 = 0, a total of 5 coins. 27 Coin Change (ต่อ) • วิเคราะห์ปัญหา Coin changer: • Optimal substructure: • เราพบว่า 42 บาทนัน้ เราใช้ 25 + 10 + 5 + 1 + 1 • **ซึง่ เป็ น Optimal 5-coin solution สาหรับ Original problem • **Optimal solution สาหรับ Subproblem ก็เป็ นส่วนหนึ่งของคาตอบใน Optimal 5-coin solution • เช่น ถ้าเราต้องการทอน 17 บาท เราจะใช้เหรียญ 10 + 5 + 1 + 1 (เป็ นส่วนหนึ่งของคาตอบ 42 บาท) • หรือ 7 เราจะใช้เหรียญ 5 + 1 +1 (เป็ นส่วนหนึ่งของคาตอบ 42 บาท เช่นกัน) • Greedy property: • สาหรับทุก ๆ Amount V เราสามารถ เราสามารถเลือกเหรียญทีม่ มี ลู ค่ามากทีส่ ดุ แล้วหักลบกับ V ได้ • แต่! Greedy algorithm อาจจะไม่สามารถหา Optimal solution ให้กบั ทุก ๆ เซตของเหรียญ • เช่น {4, 3, 1} สาหรับ 6 บาท หากเราใช้ Greedy approach เราจะได้เงินเทอน 3 เหรียญคือ 4, 1, 1 แต่ Optimal solution คือ 3, 3 • General version => Brute force, Dynamic programing 28 Station Balance (Load Balancing) 29 Station Balance (Load Balancing) • UVa 410: Station Balance • กาหนดโถ 1 ≤ 𝐶 ≤ 5 ทีส่ ามารถบรรจุ 0, 1 หรือ 2 specimens กล่าวคือ 1 ≤ 𝑆 ≤ 2𝐶 และ List ของมวลของ specimens M • โจทย์: ให้หาว่าโถใบไหนควรจะบรรจุ specimens บ้างเพือ่ ลด “Imbalance” ให้ได้มากทีส่ ดุ • โดย Imbalance = σ𝐶𝑖=1 |𝑋𝑖 − 𝐴| โดยที่ 𝑋𝑖 คือ มวลรวมของ specimens ในโถ 𝑖 และ A คือค่าเฉลีย่ ของของมวล specimens ต่อโถ • ปั ญหานี้สามารถแก้ได้ดว้ ย Greedy algorithm! แต่!! 30 Station Balance (Load Balancing) (ต่อ) • แต่เราต้องสังเกตอะไรบางอย่าง • Ob.1: ถ้าพบโถว่าง แล้ว อย่างน้อยเราต้องย้าย Specimens จากโถ ทีม่ อี ย่างน้อย 2 Specimens มาไว้โถทีว่ า่ ง • Ob.2: ถ้า S > C ดังนัน้ S – C Specimens จะต้องไปจับคูก่ บั Specimen เดีย่ ว ๆ ทีอ่ ยูใ่ นโถหนึ่ง (หลักการช่องนกพิราบ) • ถ้า S < 2C ให้ใส่ Dummy 2C – S Specimens ด้วยมวล 0 เช่น C = 3, S = 4, M = {5,1,2,7} ===> C=3, S=6, M={5,1,2,7,0,0} • หลังจากนัน้ ให้เรียง Specimens ด้วย Masses กล่าวคือ 𝑀1 ≤ 𝑀2 • • • • ≤ . . . ≤ 𝑀2𝐶 − 1 ≤ 𝑀2𝐶 ในตัวอย่างดังกล่าว M={0,0,1,2,5,7} Greedy choice appears !! เราสามารถจับคู่ 𝑀1 &𝑀2𝐶 และใส่ไปใน Chamber 1 และ 𝑀2 &𝑀2𝐶−1 และใส่ไปใน Chamber 2 31 Load Balancing (Another variant) https://www.otfried.org/courses/cs500/slides-approx.pdf 32 แบบฝึกหัด • ลอง Implement: Station Balance ตามทีไ่ ด้เรียนไป • 20 นาที • More … left as your self-Exercise ☺ • UVa 11389 - The Bus Driver • UVa 10656 - Maximum Sum (II) • UVa 11157 - Dynamic Frog 33 Internal covering problem 34 Internal covering problem • กาหนด Array A ทีป่ ระกอบด้วย N Intervals (N ช่วง) และ Target interval X • โจทย์ ให้หาจานวนของ Intervals ทีน่ ้อยทีส่ ดุ ทีจ่ าก A ทีส่ ามารถครอบคลุมทัง้ ช่วง X ได้ • เช่น [1] Input: A[] = {{1, 3}, {2, 4}, {2, 10}, {2, 3}, {1, 1}}, X = {1, 10} Output: 2 [2] Input: A[] = {{2, 6}, {7, 9}, {3, 5}, {6, 10}} , X = {1, 4} Output: -1 • Greedy approach: หากพิจารณาจะพบว่า Greedy choice คือ {u, v} ทีเ่ ป็ นไปได้คอื u <= p และ v นัน้ มากทีส่ ดุ เท่าทีเ่ ป็ นไปได้ 35 Internal covering problem • Algorithm: (กาหนดให้ชว่ ง X={M, N}) • Sort A จากน้อยไปมากด้วยจุดเริม่ • กาหนดให้ตวั แปร Start = M และ End = Start-1 • สร้างตัวแปร cnt แทยการนาจานวนของช่วงทีเ่ ลือก • วนลูปใน A; A[0]…A[i]…A[n-1] • ถ้า Start >= A[i].Start ให้อปั เดตค่า End ด้วย max(End, A[i].End) • ถ้า Start < A[i].Start ให้อปั เดตค่า End ด้วย A[i].End และ Start = A[i].Start พร้อมกับเพิม่ ค่า cnt ด้วยจานวน 1 • ออกจากลูปเมือ่ A[i].Start > End หรือ A[i].End > End • คืนค่า -1 เมือ่ วนลูปครอบแล้ว End < A[i].End มิเช่นนัน้ คือ cnt 36 Watering Grass (UVa 10382) • กาหนดให้มี n Sprinklers ติดตัง้ ตรงกลางสนามหญ้าทีม่ คี วามยาว L เมตร กว้าง W เมตร • โดย Sprinklers แต่ละตัวจะถูกระบุตาแหน่งจากระยะห่างจากซ้ายสุดของสนามหญ้า และ กาหนด ระยะเหวีย่ งน้าของ Sprinkler แต่ละตัว • โจทย์: จานวน Sprinklers ทีน่ ้อยทีส่ ดุ ทีใ่ ช้เพือ่ จะรดน้าให้ครอบคลุมทัง้ สนามหญ้าเป็ นคือกีต่ วั • ตัวอย่าง จากรูปด้านล่างมี Sprinklers ทัง้ หมด 6 ตัวคือ {A,B,C,D,E,F} มี 2 Sprinkler ทีไ่ ม่ได้ใช้งาน คือ {C, G} • Brute force คือ ทดลองทุก ๆ Subset ทีเ่ ป็ นไปได้ของการใช้ Sprinklers (=> Time limit exceeded??) เราสามารถใช้ความสัมพันธ์นี้แปลงเป็นช่วงได้ … [x-dx, x+dx] 37 แบบฝึกหัด • 10020 - Minimal Coverage • 10340 - All in All • 10440 - Ferry Loading (II) • Sorting a Three-Valued Sequence (IOI’96) • https://ioinformatics.org/files/ioi1996problem4.pdf 38 Huffman codes 39 Huffman codes • Huffman codes compress data very effectively: savings of 20% to 90% are typical, depending on the characteristics of the data being compressed. • We consider the data to be a sequence of characters. • Huffman’s greedy algorithm uses a table giving how often each character occurs (i.e., its frequency) to build up an optimal way of representing each character as a binary string. • Suppose we have a 100,000-character data file that we wish to store compactly. 40 Huffman codes • Here, we consider the problem of designing a binary character code (or code for short) in which each character is represented by a unique binary string, which we call a codeword. • If we use a fixed-length code, we need 3 bits to represent 6 characters (A data file of 100,000 characters): • a = 000, b = 001, …, f=101. • This method requires 300,000 bits to code the entire file. Can we do better? • A variable-length code can do considerably better than a fixed-length code, by giving frequent characters short codewords and infrequent characters long codewords. • It takes 224, 000 bits to represent the file, a savings of approximately 25%. 41 Prefix codes • prefix codes: codes in which no codeword is also a prefix of some other codeword. • We code the 3-character file “abc” as 0•101•100, • denotes concatenation. • Since no codeword is a prefix of any other, the codeword that begins an encoded file is unambiguous. • We can simply identify the initial codeword, translate it back to the original character, and repeat the decoding process on the remainder of the encoded file. • According to the table, the string 001011101 parses uniquely as 0•0•101•1101, which decodes to aabe. • The decoding process needs a convenient representation for the prefix code so that we can easily pick off the initial codeword. • A binary tree whose leaves are the given characters provides one such representation. 42 Prefix codes • We interpret the binary codeword for a character as the simple path from the root to that character, where 0 means “go to the left child” and 1 means “go to the right child.” • An optimal code for a file is always represented by a full binary tree, in which every nonleaf node has two children. Variable-length codes Fixed-length codes 43 Prefix codes • We can say that if 𝐶 is the alphabet from which the characters are drawn and all character frequencies are positive, then the tree for an optimal prefix code has exactly |𝑪| leaves. • One for each letter of the alphabet, and exactly 𝑪 − 𝟏 internal nodes. • Given a tree 𝑇 corresponding to a prefix code, we can easily compute the number of bits required to encode a file. • For each character 𝑐 in the alphabet 𝐶, let the attribute 𝑐. 𝑓𝑟𝑒𝑞 denote the frequency of c in the file and let 𝑑 𝑇 (𝑐) denote the depth of 𝑐’s leaf in the tree. Note that 𝑑 𝑇 (𝑐) is also the length of the codeword for character 𝑐. • The number of bits required to encode a file is thus 𝐵 𝑇 = 𝑐. 𝑓𝑟𝑒𝑞 ⋅ 𝑑 𝑇 (𝑐) 𝑐∈𝐶 which we define as the cost of the tree T. 44 Constructing a Huffman code • Huffman invented a greedy algorithm that constructs an optimal prefix code called a Huffman code. • 𝐶 is a set of 𝑛 characters. 45 Constructing a Huffman code 46 Complexity Analysis • 𝑄 is implemented as a binary min-heap. For a set of 𝐶 of 𝑛 characters. • Initializing 𝑄 takes 𝑂(𝑛) • In the loop starting at Line 3, it executes n-1 times, and each time requires 𝑂 lg 𝑛 , so the loop contributes 𝑂(𝑛 lg 𝑛) to the running time. • Thus, the total running time of HUFFMAN on a set of 𝑛 characters is 𝑂(𝑛 lg 𝑛). 47 แบบฝึกหัด • ให้นกั เรี ยนเขียนโปรแกรมเพื่อนสร้าง Huffman code ของ Characters ต่อไปนี้ 48 References • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. 2009. Introduction to Algorithms, Third Edition (3rd. ed.). The MIT Press. • https://www.otfried.org/courses/cs500/slides-approx.pdf • Competitive Programming 3 49