
השתמשנו בטכניקת memorisation זה נקרא גם top-down . שיטה זו מאפשרת לנו לבצע caching לערכים וככה למנוע חישובים מיותרים .
בעיה שנוצרת היא הצורך לשמור את ערכים אלו באוסף לאורך כל התוכנית . כדי לטפל בזה נרצה להשתמש בטכניקה שנקראת bottom-up בטכניקה זו אנחנו מבינים מהו הסדר הנכון לביצוע החישוב, משתמשים בבעיות התחלתיות כדי לפתור בעיות מתקדמות, לאחר שחישבנו את הבעיות המתקדמות , נפתר בזכרון מהחישובים הישנים.
למשל בפיבונאצי, בישביל

למשל הנ״ל יעבוד באופן הבא.

שימוש ב bottom-up חוסך זכרון רב. עם כי לעומת memorized הביצועים לא יהיו גבוהים בהרבה מmemo.

בהינתן מערך
אם נבנה dependency graph לפונקצייה, היא אמורה להראות בסגנון הזה

כי התשובה האם ניתן לשתול או לא תלוייה בהאם שתלנו או לא שתלנו באיבר ליד.
התלות הריקורסיבית תהיה בצורה הבאה
כאשר
נרצה לחשב להשתמש ב bottom-up לפי התלות באיברים שבנינו:


הרעיון של הבחירה הוא באופן הבא:

כלומר הפונקצייה הריקורסיבית תיראה באופן הבא
כאשר
התשובה תהיה עבור ערך
כעת, בגלל שהפונקצייה מקבלת כקלט 2 ערכים, נשמוע את המידע בטבלה דו מימדית .

במצב כזה, שבו קשה לנו לחזות מה תהיה תוצאת החישוב הבאה וכי אנחנו לא מכסים את כל השיטות חישוב האפשרויות מומלץ להשתמש בשיטת top down ולא bottom up.

זאת בעיה מורכבת יותר ו ידרשו מספר צעדים נוספים כדי לפתור אותה, הראשון הוא להפוך את הקלט למידע שניתן לבצע עליו dynamic programming . השלב השני זה התכנון הדינמי עצמו. והשלב השלישי זה לקח את המידע שהוצאנו בישביל להחזיר בחזרה לפלט הרצוי.

1 . נוכל להגדיר יחס בין פיקסלים באופן הבא

נקרא לזה energy of a pixel
באופן מתמטי , נגדיר את האנרגייה

(אפשר להגדיר אנרגייה גם באופנים נוספים בהינתן מידע נוסף על התמונה).


נאיבי
ריקורסיבי
נגדיר את הפונקצייה הבאה
הסבר, קלט : המערך כ
סיבוכיות כמו באלגוריתם הנאיבי גם פה במקרה הגרוע אנחנו נבדוק את כל התי קבוצות האפשרויות, ולכן זמן הריצה לא השתנה. הסיבוכיות מעידה על נכונות האלגוריתם כיוון שגם פה אנחנו סורגים את כל הקבוצות האפשרויות עד שנקבל תשובה. מספיק שאחת מהן תחזיר אמת כדי להגיע לתשובה אבל במקרה הגרוע נסרוק את כל
דינאמי נשתמש בטכניקה של memorization כלומר מלמעלה למטה, נחזיק מערך דו מימדי המכיל את כל הזוגות הסדורים האפשריים של אינדקס והסכום שאפשר לקבל כלומר מטריצה בגודל
וכעת כל מה שנשאר לעשות הוא לפני הקריאות הריקורסיביות לבדוק האם יש איבר במקום ה
אם יש נחזיר אותו , אחרת נבדוק בידיוק את אותם התנאים רק נעשה השמה באופן הבא:
סיבוכיות זמן+מקום
static int subsetSum(int a[], int n, int sum)
{
// Storing the value -1 to the matrix
int tab[][] = new int[n + 1][sum + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= sum; j++) {
tab[i][j] = -1;
}
}
if (sum == 0)
return 1;
if (n <= 0)
return 0;
if (tab[n - 1][sum] != -1)
return tab[n - 1][sum];
if (a[n - 1] > sum)
return tab[n - 1][sum]
= subsetSum(a, n - 1, sum);
else {
if (subsetSum(a, n - 1, sum) != 0
|| subsetSum(a, n - 1, sum - a[n - 1])
!= 0) {
return tab[n - 1][sum] = 1;
}
else
return tab[n - 1][sum] = 0;
}
}

נאיבי
אנחנו נרצה את תת הקבוצה הקטנה ביותר שתקיים שסכום הערכים שלה יוצא בידיוק הסכום המבוקש. הפתרון הנאיבי יהיה לרוץ על קבוצת החזקה של סוגי המטבעות כלומר
ריקורסיה
נגדיר את הפונקצייה הבאה
הסבר :
נכונות
כמו שבשאלה הקודמת גם כן בסופו של דבר נבדוק את כל הצירופים הצירופים האפשריים של תתי הקבוצות ולכן סך הכל הריקורסיה עובדת . (אפשר להוכיח באינדוקציה שאכן בכלל ניתן לקחת
דינאמי
את הבעיה הזאת נפתור בשיטת top down גם כן, נגדיר מערך דו מימדי בגודל
סיבוכיות

נאיבי נחשב את כל הקריאות האפשריות , על קבוצת החזקה של הקלט
ריקורסיבי
נגיד את הפונקצייה הבאה
f(S,n,i):
if i>=n
return true
for(j=i ; j<=n l j++) :
return T(S,i,j) and f(S,i,j+1)
כלומר נחזיק מצביע לתחילת המילה ועל כל אינדקס שנבחר נבדק האם התת מילה עצמה היא חוקית וגם כל מה שאחריה.
בדומה לאלגוריתמים הריקורסיבים האחרים גם במקרה הזה היעילות לא משתפרת כיוון שאנחנו סורקים את כל תתי המילים האפשרויות ותיתכן כפילויות.
דינאמי
נשים לב שהפעם אנחנו עובדים עם אינדקס אחד נוכל לשמור את המידע
for i=n to 1 {
boolean temp = false
for j=n to i {
if j >= n:
temp = T(S, i, j) and A[j+1]
if j==n:
temp = T(S, i, j)
if temp == true:
A[i] <- true
break
if temp == false:
A[i] <- false
}
}
return A[1];
נשים לב שtemp שמייצג את הערך העתיד להכנס לאיבר במקום ה
זמן הריצה יהיה
סיבוכיות המקום היא

לכל משבצת שבה הארנב נמצא יש 3 אפשרויות תזוזה, ולכל תזוזה כזו יש מחיר, כמו כן ייתכן שהמסלול שהארנב יבצע יוביל אותו למצב לא תקין שממנו לא ניתן להגיע כלל ליעד. לכן נגדיר את הפונקצייה הבעיה
זמן הריצה הירקורסיבי יהיה כל תתי הקבוצות שמייצגות מסלול כלומר
נרצה לייעל את מספר המסלולים שעוברים באותם הנקודות על ידי שמירה של הערכים במטריצה שכל איבר בה מייצג את
int f((s1,s2),(i,j)) {
for i in [n] :
for j in [n] :
min [C(i-1,j)+P2(i-1,j) ,
C(i,i-1)+ P1(i,j-1) ,
C(i-1,j-1) + P3(i-1 , j-1)]
return C[n,n]
}