הרצאות 1-2: הקדמה וחסמים
קורס 67109 | מבני נתונים | 20 במרץ 2022
סיכום מאת דני פרוידנברגר
1. אלגוריתמים
למרות שקורס זה עוסק במבני נתונים, ישנו קשר הדוק ביניהם ובין אלגוריתמים.
הגדרה: אלגוריתם
אלגוריתם הוא מתכון (רשימת פעולות נדרשות בסדר מסוים) כדי לייצר פלט מבוקש בהתאם לקלט שמתקבל.
אלגוריתמים נפוצים במדעי המחשב:
- מיון מערכי מספרים - קלט: מערך | פלט: מערך ממוין
- מציאת מספרי טלפון של אדם מסוים - קלט: רשימת שמות עם מספרי טלפון | פלט: מספר טלפון ספציפי
- מציאת מסלול שיעבור בכל הערים - קלט: מפה של ערים | פלט: מסלול
1.1 אלגוריתמים מול תוכנות
אלגוריתם הוא הרעיון האבסטרקטי שמתאר ב-high level אילו פעולות יש לעשות כדי להגיע מהקלט אל הפלט. המחשב לא יצליח להריץ את האלגוריתם ישירות, כי הוא לא ממומש.
תוכנה היא המימוש של האלגוריתם. ההוראות כתובות ב-low level כך שהקומפיילר של המחשב יכול להריץ אותן.
maxIndex = 0
max := a[0]
for i := 1 to 3 do:
if (a[i] > max) then maxIndex := i
temp := a[3]
a[3] := a[maxIndex]
a[maxIndex] := temp
1.2 מבני נתונים
הדרך שבה אנחנו מאחסנים את המידע היא קריטית בשביל האלגוריתם. מבני הנתונים שנבחר ישפיעו על יעילות האלגוריתם.
כשמדברים על יעילות, מדברים על שני קריטריונים:
- מהירות - כמה מהר האלגוריתם מסתיים, כתלות בקלט
- מקום - כמה זיכרון נדרש להרצת האלגוריתם
דוגמה 1: חיפוש איבר מקסימלי במערך
- מערך ממוין: פשוט מחזירים את האיבר האחרון - טריוויאלי
- מערך לא ממוין: צריך לעבור על כל האיברים - פחות יעיל
דוגמה 2: פולינומים
רוצים להכפיל שני פולינומים P,Q:
- אחסון כגורמים לינאריים: קל להחזיר מכפלה. למשל (x−1)(x+1)(x+2) כפול (x+3) פשוט נותן (x−1)(x+1)(x+2)(x+3)
- אחסון כסכומים: דורש הרבה חישובים, כי צריך לכפול איבר-איבר
1.3 מבני נתונים מופשטים (ADTs)
הגדרה: Abstract Data Types
בספרות העולמית ADT הוא תיאור אבסטרקטי של מבנה נתונים, המוגדר באמצעות הצורך שהוא צריך לספק. מבנה נתונים מממש ADT.
1.4 מטרות הקורס
- אלגוריתמים - נלמד אלגוריתמים כגון חיפוש, מיון, אינדוקס
- ניתוח אלגוריתמים - ניתוח של יעילות בזמן ובמקום
- השוואת אלגוריתמים - נקבע איזה אלגוריתם יותר טוב
- שאלות נוספות:
- האם יש פתרון לכל בעיה? (בעיית העצירה)
- האם יש פתרון יעיל?
- האם האלגוריתם שלי הוא הטוב ביותר?
- האם קיים פתרון "יעיל ביותר"?
2. סיווג בעיות לפי רמת קושי
דוגמה לבעיה קלה: המסלול הקצר ביותר
מציאת מסלול קצר ביותר בגרף - בעיה יחסית פשוטה.
דוגמה לבעיה קשה: בעיית האריזה
אחסון חלקים בתוך לוח כך שיתפסו כמה שפחות מקום.
לכל צורה 4 אפשרויות, ויש n חלקים, אז יש 4n קומבינציות - פתרון אקספוננציאלי!
2.1 מדידת יעילות
נחלק את הניתוח לפי שלושה מקרים:
- המקרה הטוב ביותר (Best Case)
- המקרה הגרוע ביותר (Worst Case)
- המקרה הממוצע (Average Case)
3. בעיית המיון
בבעיית המיון, יש לנו מערך של n איברים ונרצה למיין אותו מהקטן לגדול.
3.1 מיון בועות (Bubble Sort)
נעבור משמאל לימין על כל זוג מספרים, ואם צריך - נחליף בין A[i−1] לבין A[i]. נעבור על המערך עד n פעמים.
אחרי האיטרציה ה-i: המספר ה-i הגדול ביותר נמצא במקומו.
ניתוח יעילות: בכל איטרציה יש ∼n פעולות, וסה"כ עד n איטרציות:
n⋅n=n2
3.2 מיון מיזוג (Merge Sort)
חלק את המערך ל-2, כל תת-מערך חלק שוב ל-2, עד מערכים בגודל 1. ואז מזג כל זוג בצורה ממוינת חזרה למעלה.
ניתוח יעילות: מחלקים logn פעמים, ובכל מיזוג n פעולות:
T(n)=n⋅logn
4. סיבוכיות
מדידה: נמדוד סיבוכיות ע"י מספר הפעולות (לא זמן בפועל), כפונקציה של גודל הקלט n.
מיון הכנסה (Insertion Sort)
מסתכלים על הרישא (prefix) של המערך. כל פעם שנתקלים במספר חדש, מכניסים אותו למקום הנכון ברישא הממוינת.
for j = 1 to n-1:
key = A[j]
i = j - 1
while i >= 0 and A[i] > key:
A[i+1] = A[i]
i = i - 1
A[i+1] = key
זמן ריצה כולל:
T(n)=c1n+c2(n−1)+c4(n−1)+c5∑j=1n−1tj+c6∑j=1n−1(tj−1)+c7∑j=1n−1(tj−1)+c8(n−1)
- מקרה טוב (מערך ממוין): T(n)=(c1+c2+c4+c5+c8)n−(c2+c4+c5+c8) - לינארי
- מקרה גרוע (מערך ממוין הפוך): T(n)=2c1+c6+c7n2+2c1+c2+c4+c8+c5−c6−c7n−(c2+c4+c5+c8) - ריבועי
5. ניתוח אסימפטוטי
מעניין אותנו מקרים בהם n גדול מאוד. נסתכל על T(n)=f(n) כאשר n→∞.
חסמים אסימפטוטיים
חסם עליון - Big O
f(n)=O(g(n)) אם קיימים N∈N ו-c>0 כך שלכל n≥N: f(n)≤c⋅g(n)
כלומר, g היא חסם עליון של f - החל ממקום מסוים g גדולה מ-f (בהתעלמות מקבועים).
חסם תחתון - Big Omega
f(n)=Ω(g(n)) אם קיימים N∈N ו-c>0 כך שלכל n≥N: f(n)≥c⋅g(n)
חסם הדוק - Big Theta
f(n)=Θ(g(n)) אם f(n)=O(g(n)) וגם f(n)=Ω(g(n))
תכונות של חסמים
- רפלקסיביות: f(n)=O(f(n)), f(n)=Ω(f(n)), f(n)=Θ(f(n))
- סימטריה: f(n)=Θ(g(n)) אם"ם g(n)=Θ(f(n))
- טרנזיטיביות: אם f=O(g) וגם g=O(h) אזי f=O(h) (ודומה ל-Ω ו-Θ)
תכונות נוספות:
- O(O(f(n)))=O(f(n))
- O(f(n)+g(n))=O(f(n))+O(g(n))
- O(f(n)⋅g(n))=O(f(n))⋅O(g(n))
- O(logn)=O(lgn) (כאשר lg=log2)
חסמים בפולינומים: מסתכלים על החזקה הגדולה ביותר. למשל n4+2n2−5n+7=Θ(n4).
הרצאה 2: חסמים ואלגוריתמים רקורסיביים
1. אלגוריתמים רקורסיביים
נחפש T(n)=Θ(f(n)) - הפונקציה ההדוקה ביותר לזמן הריצה.
הנחות יסוד:
- אורך הקלט n מאוד גדול
- T(1)=1 (עבור קלט קטן הפתרון קבוע)
- תנאי שפה נוחים (נניח n=2k)
שיטת "הפרד ומשול": מפרידים את הבעיה לתתי-בעיות ומנתחים כעץ רקורסיבי.
שלוש שאלות מפתח:
- לכמה תתי-בעיות מחלקים?
- מה הגודל של כל תת-בעיה?
- איך מחברים את תתי-הבעיות?
דוגמאות
דוגמה 1: חישוב עצרת
n!=n⋅(n−1)!, כך ש-1!=1
T(n)=T(n−1)+Θ(1)=Θ(n)
עץ ברוחב 1 ועומק n.
דוגמה 2: פיבונצ'י
fib(n)=fib(n−1)+fib(n−2)
T(n)=T(n−1)+T(n−2)+Θ(1)=Θ(2n)
רוחב העץ מוכפל פי 2 בכל רמה - גדילה אקספוננציאלית.
דוגמה 3: מיון הכנסה
T(n)=T(n−1)+Θ(n)=Θ(n2)
סכום של סדרה חשבונית: 1+2+...+n=2n(n+1)
דוגמה 4: חיפוש בינארי
T(n)=T(2n)+Θ(1)=Θ(logn)
דוגמה 5: Merge Sort
T(n)=2T(2n)+Θ(n)=Θ(nlogn)
שיטות לפתרון משוואות רקורסיביות
- ניחוש - מנחשים תשובה ומוכיחים באינדוקציה
- איטרציה - פותחים את הנוסחה וסוכמים
- משפט האב (Master Theorem)
2. שיטת ההצבה
דוגמה: Merge Sort
נוכיח ש-T(n)=Θ(nlogn) כאשר T(n)=2T(2n)+n.
הוכחת חסם עליון: T(n)≤2⋅nlogn
בסיס (n=2): T(2)=2T(1)+2=4≤2⋅2⋅log2=4 ✓
צעד: נניח נכונות עבור 2n:
T(n)=2T(2n)+n≤2⋅[n⋅log2n]+n=2nlogn−n≤2nlogn
3. שיטת האב (Master Theorem)
משפט האב
יהיו a,b,c קבועים כך ש-a,b≥1 ו-c≥0.
תהי T(n)=a⋅T(bn)+nc כך ש-T(1)=1.
- אם logba<c אזי T(n)=Θ(nc)
- אם logba=c אזי T(n)=Θ(nclogbn)
- אם c<logba אזי T(n)=Θ(nlogba)
אינטואיציה:
- a = כמות הפיצולים (רוחב העץ)
- b = גודל כל תת-בעיה (עומק העץ)
- c = כמות העבודה בכל רמה (משקל)
שלושת המקרים:
- עלים דומיננטיים: הפיצולים (a,b) שולטים על העבודה (c)
- שורש דומיננטי: העבודה (c) שולטת על הפיצולים
- שוויון: עלים ועבודה שווים
דוגמאות לשימוש במשפט האב
| בעיה | נוסחה | a,b,c | מקרה | תוצאה |
|---|
| מיון מיזוג | T(n)=2T(2n)+n | a=2,b=2,c=1 | log22=1=c | Θ(nlogn) |
| חיפוש בינארי | T(n)=T(2n)+1 | a=1,b=2,c=0 | log21=0=c | Θ(logn) |
| אלגוריתם תאורטי | T(n)=16T(4n)+n3 | a=16,b=4,c=3 | log416=2<3=c | Θ(n3) |