שאלת מבחן במבני נתונים - אוניברסיטת בר-אילן 2011 - תכנות דינמי
יהי מערך של המוניים (לא מיוחדים). הגדר זמן ריצה של בלא קאי, עיבודים הפונקציה הוקרא לאחסון הנתונים ומחזיר שתיית שונות שלמים בעיניים כך שסכום המערך מתא עד מקסימום אפשרי בכל קנקנים של המערך. בקץ הבעיה רחבה דיגום סדרה משנה ברציפות עם סימן בדיקה (המספיק בה בחוקי הבחינה בעמידת תנאים תיטת המערך הנתונה).
העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
אוניברסיטת בר-אילןמועד א2011סמסטר ב
★★★★★
תכנות דינמיסיבוכיות זמןסיבוכיות מקוםנוסחת נסיגההוכחת נכונות
עבור על המערך במעבר יחיד. בכל צעד, חשב את הסכום המקסימלי של תת-מערך המסתיים באינדקס הנוכחי, והשתמש בתוצאה זו כדי לעדכן את הסכום המקסימלי הכולל שנמצא עד כה.
הבעיה המתוארת, על אף הניסוח המשובש, היא בעיה קלאסית במדעי המחשב הידועה כבעיית תת-המערך הרציף בעל הסכום המקסימלי (Maximum Subarray Problem). המטרה היא למצוא תת-מערך רציף במערך נתון כך שהסכום הוא הגדול ביותר האפשרי. ניתן לפתור בעיה זו ביעילות באמצעות תכנות דינמי, באלגוריתם הידוע כאלגוריתם של קדן (Kadane's Algorithm).\n\nהרעיון המרכזי:\nהאלגוריתם סורק את המערך משמאל לימין במעבר יחיד. בכל שלב , אנו מחשבים את הסכום המקסימלי של תת-מערך רציף *המסתיים באינדקס *. נסמן סכום זה ב-.\nכדי לחשב את עבור האינדקס , יש שתי אפשרויות:\n1. תת-המערך המקסימלי שמסתיים ב- מורכב מהאיבר בלבד.\n2. תת-המערך המקסימלי שמסתיים ב- הוא הרחבה של תת-המערך המקסימלי שהסתיים ב-, על ידי הוספת .\n\nלכן, מתקיימת נוסחת הנסיגה הבאה:\n\n\nבמקביל, אנו שומרים משתנה נוסף, , אשר מחזיק את הסכום המקסימלי שנמצא עד כה, בכל אינדקס שהוא. לאחר כל חישוב של , אנו מעדכנים את :\n\n\nכדי להחזיר את האינדקסים , עלינו לעקוב אחר נקודות ההתחלה והסוף של תתי-המערכים המתאימים ל- ול-.\n\nאלגוריתם:\n1. אתחל:\n -
max_so_far = A[1] (הסכום המקסימלי הכולל)\n - current_max = A[1] (הסכום המקסימלי שמסתיים באינדקס הנוכחי)\n - best_L = 1, best_R = 1 (האינדקסים של הפתרון הטוב ביותר עד כה)\n - current_L = 1 (אינדקס ההתחלה של המערך הנוכחי)\n2. עבור i מ-2 עד n:\n א. אם A[i] > current_max + A[i]:\n - current_max = A[i]\n - current_L = i\n ב. אחרת:\n - current_max = current_max + A[i]\n ג. אם current_max > max_so_far:\n - max_so_far = current_max\n - best_L = current_L\n - best_R = i\n3. החזר את (best_L, best_R).\n\nניתוח סיבוכיות:\n- סיבוכיות זמן: האלגוריתם מבצע מעבר יחיד על המערך בגודל . כל פעולה בתוך הלולאה לוקחת זמן קבוע, . לכן, **סיבוכיות הזמן הכוללת היא .\n- סיבוכיות מקום:** האלגוריתם משתמש במספר קבוע של משתנים נוספים (max_so_far, current_max, וכו') ללא תלות בגודל הקלט . לכן, **סיבוכיות המקום (הנוספת) היא .\n\nהוכחת נכונות (באינדוקציה):\nטענה:** לכל , לאחר איטרציה של הלולאה, המשתנה current_max מכיל את הסכום המקסימלי של תת-מערך רציף המסתיים באינדקס , והמשתנה max_so_far מכיל את הסכום המקסימלי של תת-מערך רציף כלשהו בתוך .\n**בסיס האינדוקציה ():** לפני תחילת הלולאה, מאתחלים current_max = A[1] ו-max_so_far = A[1]. זה נכון כי תת-המערך היחיד ב- הוא עצמו.\nצעד האינדוקציה: נניח שהטענה נכונה עבור . באיטרציה ה-, אנו מחשבים את current_max החדש. תת-מערך רציף מקסימלי המסיים ב- חייב לכלול את . הוא או מורכב מ- בלבד, או מהרחבה של תת-מערך רציף מקסימלי המסיים ב-. סכומו הוא לכן , כאשר הוא תת-המערך הרציף המקסימלי המסיים ב-. לפי הנחת האינדוקציה, סכום זה הוא current_max מהאיטרציה הקודמת. לכן, עדכון current_max ל- הוא נכון. לאחר מכן, max_so_far מתעדכן להיות המקסימום בין ערכו הקודם (הסכום המקסימלי ב-) לבין current_max החדש (הסכום המקסימלי המסיים ב-). זה מבטיח ש-max_so_far יכיל את הסכום המקסימלי ב-.