מבני נתונים ואלגוריתמים - מחברת קורס/מבחן סופי מועד א' סמסטר קיץ 2007 - שאלות

מתוך ויקיספר, אוסף הספרים והמדריכים החופשי

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



הנחיות

  1. משך המבחן - שלוש שעות.
  2. החומר המותר בשימוש במבחן זה הוא כל דף (מודפס) שמקורו באתר הקורס, כולל דפים שעליהם הערות בכתב יד. כל חומר אחר אסור בשימוש במבחן. השימוש בכל מכשיר אלקטרוני (כולל מחשבון) אסור בשימוש במבחן.
  3. בכל שאלה, אם תציין במפורש שאינך עונה עליה - תקבל 15% מערכה.
  4. בתשובה שבה אתה משתמש בתכנון דינמי, 70% מהניקוד יוענק לפתרון נכון, מוכח, ויעיל, המוצא את מחיר הפתרון הטוב ביותר. 100% מהניקוד יוענק לפתרון העונה על הדרישות הנ"ל, אך מדפיס במפורט גם את פרטי הפתרון.


שאלה 1[עריכה]

(~12 נקודות)

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

נתון מערך רצון התעסוקה W, שבו זוגות. אם הזוג (i, j) מופיע בW, אז המשמעות היא שסטודנט מוכן לעבוד בחברה , וחברה מוכנה להעסיק את סטודנט . כמו כן, נתון מערך פוטנציאל ההעסקה P, שבו מספרים שלמים. P[j] מתאר את מספר המשרות הפנויות בחברה .

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

  1. אם הזוג (i, j) מופיע בW', אז הוא גם מופיע בW.
  2. אם הזוג (i, j) מופיע בW', אז אין זוג אחר בW' שאברו הראשון .
  3. מספר הזוגות מהצורה (i, j) בW' בעלי אותו , הוא לכל היותר .

שאלה 2[עריכה]

(~33 נקודות)

מעל הירקון עומד גשר שאורכו מטרים ( מספר שלם חיובי גדול מ1 כלשהו). הגשר נמצא לא תקין אפילו בסטנדרטים של מדינת ישראל(!). יש לפרק את הגשר לחלקים ולפנותו בצורה הזולה ביותר. ראשית צריך לשבור את הגשר. ניתן לשבור את הגשר למספר חלקים. שבירת הגשר חייבת להתבצע בנקודות בלבד. שבירת כל נקודה עולה שקלים ( מספר שלם חיובי כלשהו).



דוגמה:

נניח ו (ראה A בתרשים הבא). אפשר לשבור את הגשר ב4 אפנים:

  1. שוברים בנקודות 1 ו2. מתקבלים 3 חלקים בעלי אורך 1 כל אחד (ראה B בתרשים הבא). עלות השבירה היא .
  2. שוברים בנקודה 1. מתקבלים 2 חלקים: הראשון בעל אורך 1, והשני בעל אורך 2 (ראה C בתרשים הבא). עלות השבירה היא .
  3. שוברים בנקודה 2. מתקבלים 2 חלקים: הראשון בעל אורך 2, והשני בעל אורך 1 (ראה D בתרשים הבא). עלות השבירה היא .
  4. לא שוברים באף נקודה. מתקבל חלק יחיד בעל אורך 3. עלות השבירה היא .
דוגמה לגשר הזבלה.
דוגמה לגשר הזבלה.


כעת יש להוביל את חלקי הגשר. הנח שקיימת פונקציה ידועה כך ש מתארת את עלות הובלתו של חלק בעל אורך i. הנח ש הוא מספר שלם חיובי לכל .


שימו לב:

וודא שאינך מניח במובלע דברים שלא נאמרו לגבי . בפרט, אל תניח שהפונקציה מונוטונית עולה (עלות ההובלה נקבעת לפי שיקולים שאיננו יודעים.)




דוגמה:

בהמשך לדוגמה הקודמת שראינו, נניח ,‏ ,‏ ו. ארבע האפשרויות שראינו מקודם יעלו כך:

  1. עלות ההובלה היא .
  2. עלות ההובלה היא .
  3. עלות ההובלה היא .
  4. עלות ההובלה היא .


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

שאלה 3[עריכה]

(~33 נקודות)


נתונה רשת כבישי אגרה. לכל כביש יש מספר המתאר את עלות הנסיעה בכביש.



דוגמה:

בתרשים הבא, עלות הנסיעה בכביש מ1 ל2 היא .

כבישי אגרה, עם כביש אחד שלילי.
כבישי אגרה, עם כביש אחד שלילי.


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



דוגמה:

בתרשים הקודם, עלות הנסיעה בכביש מ7 ל3 היא .



שימו לב:

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

אנא מצא אלגוריתם יעיל המקבל את הגרף, טבלת עלויות לקשתות, וצומת מוצא , ומחזיר, עבור כל צומת , את עלות המסלול הזול ביותר מ ל.



דוגמה:

בתרשים הקודם, נניח שצומת המוצא הוא :

  1. המסלול הזול ביותר מ ל6 הוא ,‏ ועלותו 2.
  2. המסלול הזול ביותר מ ל4 הוא ,‏ ועלותו 3.


שאלה 4[עריכה]

(~28 נקודות)

הסטודנט העיראקי איפ חמיס תברא מתבונן בקטע הקוד הבא:

# Makes a binary heap from an array (Values).
Build-Heap(Values)
1	bh = Make-Priority-Queue()
	
2	bh.size = Length(Values)	
	
3	for i in [1, ..., Length(Values)]
4		bh.Values[i] = Values[i]
		
5	Arrange(bh)
	
6	return bh

קטע קוד זה מקבל מערך, ומחזיר ערימה בינרית . איפ חוכך בדעתו כיצד מומשה הפונקציה Arrange. (אנו למעשה כבר ראינו את המימוש הבא:

Arrange(bh)
1	for i in [Length(bh.Values), ..., 1]
2		Bubble-Down(bh, i)

אך הוא אינו יודע זאת).

מספר אפשרויות עולות על דעתו:

Arrange(bh)
1	for i in [Length(bh.Values) / 2, ..., 1]
2		Bubble-Down(bh, i)
Arrange(bh)
1	Merge-Sort(bh.Values)
Arrange(bh)
1	for i in [1, ..., Length(bh.Values)]
2		Bubble-Down(bh, i)
Arrange(bh)
1	for i in [1, ..., Length(bh.Values)]
2		Bubble-Up(bh, i)
Arrange(bh)
1	for i in [Length(bh.Values), ..., 1]
2		Bubble-Up(bh, i)

עבור כל אחת מהאפשרויות, אנא הוכח או הפרך את הטענה שבהכרח תתקבל ערימה תקנית, ונתח את הסיבוכיות במקרה הגרוע (בלי קשר לשאלה האם תתקבל ערימה תקנית).