190 likes | 305 Views
קורס מחשב לרפואנים 274121. הרצאה 10: חיפושים ומיונים יעילים. נכתב על-ידי ראובן בר-יהודה. משאבי זמן וזיכרון של תוכניות מחשב: תזכורת. אלו מתתי התוכניות הבאות צורכת יותר זמן? הנחה: כל פעולה "בסיסית" עולה 1 יחידות זמן. עבור n=0 5 פעולות כל איטרציה מוסיפה 7 פעולות Time(n) = 5 + 7*n
E N D
קורס מחשב לרפואנים274121 הרצאה 10: חיפושים ומיונים יעילים נכתב על-ידי ראובן בר-יהודה.
משאבי זמן וזיכרון של תוכניות מחשב: תזכורת • אלו מתתי התוכניות הבאות צורכת יותר זמן? הנחה: כל פעולה "בסיסית" עולה 1 יחידות זמן. עבור n=0 5 פעולות כל איטרציה מוסיפה 7 פעולות Time(n) = 5 + 7*n עבור n=0 4 פעולות כל איטרציה מוסיפה 5 פעולות סך מספר האיטרציות הוא n2 Time(n) = 4 + 5*n2 • y =0; • i= 0 + 0 + 0; • while i< n • i=i+ 1; • y = y +i*i*i; • end • i=n*n; • y= 0; • while i>0 • i = i- 1; • y = y +i; • end
משאבי זמן וזיכרון של תוכניות מחשב: תזכורת אמנם עבור n-ים קטנים הפרבולה מתחת לישר אבל עבור n-ים גדולים הפרבולה גבוהה יותר. מה שמעניין אותנו הם סדרי הגודל: התוכנית הראשונה צורכת זמן בסדר גודל לינארי התוכנית השנייה צורכת זמן בסדר גודל ריבועי ריבועי לינארי
משאבי זמן וזיכרון של תוכניות מחשב (סיבוכיות): תזכורת דוגמאות לסדרי גודל קבוע: (מסומן ב-(O(1): 1, 10, 123.235, 10001000 לינארי (מסומן ב-(O(n):5 + 5*n, 5n+1999, 0.001n+100000, n+n0.7 ריבועי (מסומן ב-(O(n2):5 + 5*n2, 5n+1999+n2, 0.001n2+100000, 1+2+…+n פולינומי: (מסומן ב poly(n) או (nO(1): 5 + 5*n11, 5n+1999+n12, 0.001n22+100000, לוגריתמי (מסומן ב-((O(log(n):5 + 5*log(n), log(1+2+3+…+n) , log22(n) ובלתי נסבל: אקספוננציאלי: , 1.13n+2 ,2n
סיבוכיות: הבהרות מטרות: • להיות מודעים למגבלות משאבי המחשב, ולמשל, להמנע מתוכניות שצורכות זמן בלתי נסבל (כמו שנראה מיד, אקספוננציאלי) • לעזור בפיתוח תוכניות יעילות כמו שנעשה בהמשך, למשל, בעיות של חיפוש בזמן O(log(n)), מיזוג בזמן לינארי ומיון בזמן O(nlog(n)) שנלמד בשיעור זה (ובעיות נוספות שנלמד בעתיד). מבחן סופי: • לא יהיו שאלות בהם אתם נדרשים לנתח או להוכיח סיבוכיות • אבל כן נבקש משימות תחת מגבלות סיבוכיות.
פתרונות רקורסיביים בזבזניים • פתרון רקורסיבי עלול להיות מאד לא יעיל מבחינת סיבוכיות זמן (או מקום). • נדגים זאת על ידי פונקציה רקורסיבית פשוטה לחישוב האבר ה n-י בסדרת פיבונאצ'י. • נעיר שהתכנית הכי יעילה לחישוב האבר ה n-י היא על ידי שימוש בנוסחה הסגורה
rfib: תכנית רקורסיבית לסדרת פיבונאצ'י • להלן פונקציה רקורסיבית לחישוב האבר ה n-י בסדרת פיבונאצ'י על פי ההגדרה. • פונקציה זו מאד לא יעילה: (אקספוננציאלית) function f=rfib(n) if n<=2 f=1; else f=rfib(n-1)+rfib(n-2); end
function f=F(n) if n<=2 f=1; else f=F(n-1)+F(n-2); end F(6) n=6 f = + F(5) F(4) n=5 f = + 3 F(4) F(3) n=4 f = + 2 1 F(3) F(2) n=3 f = + n=2 f = 1 2 F(2) F(1) 1 1 n=1 f = 1 n=2 f = 1
הוכחת אקספוננציאליות של rfib באינדוקציה יהי Timenמספר הפעולות הנדרשות לביצועrfib(n) . נוכיח φn<Timen באינדוקציה. בסיס:Time1 = 3 > φ1, Time2 = 3 > φ2 . צעד: הזמן לחשב עבור n כרוך בין היתר בקריאה לפונקציה עבור n-2 ועבור n-1 ולכן: function f=rfib(n) if n <= 2 f=1; else f=rfib(n-1)+rfib(n-2); end • Timen> Timen-1 + Timen-2 • > φn-1 + φn-2 % מהנחת האינדוקציה • > φn-2 (φ+ 1) • = φn-2 φ2 %x2 – x – 1 = 0 שורש של φ • =φn
דרך נוספת: Timen> מספר העלים = rfib(n) f(7) function f=rfib(n) if n<=2 f=1; else f=rfib(n-1)+rfib(n-2); end f(6) f(5) f(4) f(4) f(3) f(3) f(2) f(3) f(2) f(2) f(1) f(2) f(1) f(2) f(1)
מימוש אינדוקטיבי (תכנון דינאמי) של מספרי פיבונאצ'י מספר הפעולות הוא לינארי. חישוב זה שומר את כל n האברים הראשונים בסדרת פיבונאצ'יבוקטורf. functionfib = myfib(n) % Fibonacci number computation f = zeros(1,n); %memory allocation f(1)=1;f(2)=1; for k=3:n f(k)=f(k-1)+f(k-2); end fib=f(n);
חיפוש בינארי • function m = bin_search (x, a) • % a is a non decreasing sorted array • % find x in a and return in m its index. • % if x is not there, m = -1 • b = 1; t = length(a); • while b <= t • m = floor((b+t)/2); • if a(m) == x • return • elseif a(m) > x • t = m-1; • else • b = m+1; • end • end • m = -1;
b t חיפוש בינארי: נכונות שמורות בכל איטרציה x לא נמצא ב a(1 : b-1) x לא נמצא ב a(t+1: end) הוכחה: באינדוקציה על מספר האיטרציות: בסיס: 0 איטרציות- נכונות באופן ריק. צעד: אם a(m) > x אז כל האיברים ב a(m:end) גדולים ממש מ-x ולכן הוא לא שם, אם a(m) < x אז כל האיברים ב a(1:m) קטנים ממש מ-x ולכן הוא לא שם. בסיום: אם x לא נמצא (שורה 5) אז נגיע לשורה 13 בה מתקיים b>t ומכאן נובע שהאיחוד של a(t+1: end) ו a(1 : b-1) מכיל את כל איברי a ולכן, לפי השמורות,x לא נמצא ב-a • function m = bin_search (x, a) • b = 1; t = length(a); • while b <= t • m = floor((b+t)/2); • if a(m) == x • return • elseif a(m) > x • t = m-1; • else • b = m+1; • end • end • m = -1;
חיפוש בינארי: סיבוכיות זמן O(log(n)) • function m = bin_search (x, a) • b = 1; t = length(a); • while b <= t • m = floor((b+t)/2); • if a(m) == x • return • elseif a(m) > x • t = m-1; • else • b = m+1; • end • end • m = -1; בכל איטרציה האינטרוואל b:t נחצה ב-2. אם אורכו בהתחלה היה n אז לאחר איטרציה אחת הוא יהיה בערך n/2 לאחר עוד איטרציה הוא יהיה בערך n/4 לאחר עוד איטרציה הוא יהיה בערך n/8 ולכן לאחר k איטרציות הוא יקטן ל n/2k ש: עבור איזה k הביטוי הנ"ל יהיה קטן מדי? ת: נפתור את אי השוויון: 1 > n/2k או: 2k > n וזה יקרה כאשר k = log2(n) מכאן מספר האיטרציות (ולכן סיבוכיות הזמן) הוא (O(log(n)
חיפוש בינארי: מימוש רקורסיבי • functioni = r_bin_search (x, a, b, t) • % a is a non decreasing sorted array • % find x in a(b:t) and return in i its index. • % if x is not there, i = -1 • m = floor((b+t)/2); • if b > t • i = -1; • elseif a(m) == x • i = m; • elseif a(m) > x • i = r_bin_search(x, a, b, m-1); • else • i = r_bin_search(x, a, m+1, t); • end
Meet Merge Sort (SilvioMichli MIT) MERGE-SORTa(1:n) • If n== 1, done (nothing to sort). divide and conquer Otherwise, recursively sort a(1 : n/2)and a(n/2 + 1 : n) “Merge” the two sorted sub-arrays. Key function:MERGE
מיון מיזוג – נכונות+סיבוכיות+מימוש מיזוגבשבוע הבא... • function b = msort(a) • if length(a)<2 • b = a; • return • end • m = ceil(length(a)/2); • b = merge(msort(a(1:m)), msort(a(m+1:end)));