נושאים פעיליםנושאים פעילים  הצגת רשימה של חברי הפורוםרשימת משתמשים  חיפוש בפורוםחיפוש  עזרהעזרה
  הרשמההרשמה  התחברותהתחברות RSS עדכונים
תיכנות
RSS UnderWarrior Forums : RSS תיכנות
נושא

נושא: עזרה בבקשה בפתירת תרגיל ברקורסיה - שפת C.

שליחת תגובהשליחת נושא חדש
כותב
הודעה << נושא קודם | נושא הבא >>
אורח
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 03 February 2009 בשעה 19:55 | IP רשוּם
ציטוט אורח

השאלה כי כזו:
כתבו פונקציה רקורסיבית:
כתבו פונקציה רקורסיבית:
bool subsetSum(int numbers[], int size, int sum);
הפונקציה מקבלת מערך של מספרים, את גודלו, ומספר נוסף SUM.
הפונקציה תחזיר אמת אם"ם קיימת איזושהי תת-קבוצה של מספרים מתוך המערך (לאו דווקא רצופה)
שסכומה הוא SUM.
כלומר למערך כזה:
numbers = [1,5,3,9,10
הפונקציה תחזיר אמת כי 5+9=14

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

האם אפשר כיוון לפתרון? (לא פתרון מלא).

תודה מראש.

חזרה לתחילת העמוד הצג את כרטיס החבר של אורח חפש הודעות אחרות של אורח בקר בדף הבית של אורח
 
גרשון
משתמש מתחיל
משתמש מתחיל
סמל אישי

הצטרף / הצטרפה: 19 February 2009
מדינה: Israel
משתמש: מנותק/ת
הודעות: 6
נשלח בתאריך: 19 February 2009 בשעה 23:39 | IP רשוּם
ציטוט גרשון

בצורה איטרטיבית, ממיין את המערך בסדר עולה,  רץ עליו ועבור כל ערך ממנו מחזיר

מהמשתנה SUM עד שערכו שווה לאפס (מצאתי) או קטן (לא קיים הסכום).

בקשר לרקורסיה, אם אתה מכיר את המושג מחסנית ?

הפיתרון לכל רקורסיה הוא לדמיין כיצד עובדת המחסנית !

ברקורסיה משתמשים כאשר יש לבצע סריקה של צירופים לא ידועים מראש, לדוגמא

בסריקת עץ התיקיות של המחשב שלך, האם תיקייה תכיל בנוסף לקבצים עוד תת תיקיות וכו, כיצד ניתן היה לסרוק זאת ?

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

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

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

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

 

חזרה לתחילת העמוד הצג את כרטיס החבר של גרשון חפש הודעות אחרות של גרשון
 
גרשון
משתמש מתחיל
משתמש מתחיל
סמל אישי

הצטרף / הצטרפה: 19 February 2009
מדינה: Israel
משתמש: מנותק/ת
הודעות: 6
נשלח בתאריך: 19 February 2009 בשעה 23:44 | IP רשוּם
ציטוט גרשון

בקשר לשורה הראשונה : "רץ עליו ועבור כל ערך ממנו מחזיר"

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

חזרה לתחילת העמוד הצג את כרטיס החבר של גרשון חפש הודעות אחרות של גרשון
 
באתי לעזרת חבר
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 27 February 2009 בשעה 22:47 | IP רשוּם
ציטוט באתי לעזרת חבר

שני דברים, האחד - הפתרון הרקורסיבי לבעיה הוא די אינטואטיבי ופשוט, להלן האלג' -

תנאי עצירה -
אם גודל המערך == 0 וגם הסכום הרצוי != 0 החזר שקר.
אחרת אם הסכום הרצוי == 0 החזר אמת.

קשר רקורסיבי -
שליחת מערך בגודל n-1 לרקורסיה (ללא האיבר הראשון), פעם אחת כאשר מחסירים מהסכום את ערך האיבר הראשון ופעם אחת בלי להחסיר את ערך האיבר הראשון.
כעת מה שנותר לבצע הוא OR בין התוצאות שחזרו והחזרת ערך אמת או שקר בהתאם.
לדוגמא ב- C:

 || ([return subset(numbers + 1, size - 1, sum - numbers[0
;(subset(numbers + 1, size - 1, sum

הדבר השני אותו רציתי לציין היא שהבעיה עצמה ידועה כבעיית NP קשה, כלומר לא ידוע שום פתרון בזמן יעיל הפותר אותה, כאשר הכוונה לזמן יעיל היא לזמן לכל היותר מעריכי, כגון -(T(n^3. אז אתה יכול להרגיש בסדר עם זה שלא מצאת שום פתרון איטרטיבי לבעיה כי הוא לכשלעצמו מסובך ומסורבל לכתיבה.

אגב, הפתרון האיטרטיבי שגרשון הציע אינו נכון לדוגמא במערך הממוין -
1,2,3,4,5,6 עם הסכום 11 זה לא יעבוד כיוון שהסכום יגיע למס' שלילי לאחר הספרה 5, למרות שתת הקבוצה {5,6} מקיימת את הסכום.

חזרה לתחילת העמוד הצג את כרטיס החבר של באתי לעזרת חבר חפש הודעות אחרות של באתי לעזרת חבר בקר בדף הבית של באתי לעזרת חבר
 
גרשון
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 18 March 2009 בשעה 10:58 | IP רשוּם
ציטוט גרשון

לא הסברתי נכון את הפיתרון האיטרטיבי, ולכן להלן הפתרון:

void combi()
{
 int numbers[10] = {1,3,5,17};
 int a,b,c,d;
 for (a=0; a<4; a++)
 {
  cout<<numbers[a]<<endl;   // show the combi
  for (b=a+1; b<4; b++)
  {
   cout<<numbers[a]+numbers[b]<<endl;
   for (c=b+1; c<4; c++)
   {
    cout<<numbers[a]+numbers[b]+numbers[c]<<endl;
    for (d=c+1; d<4; d++)
    {
     cout<<numbers[a]+numbers[b]+numbers[c]+numbers[d]<<endl;
    }
   }
  }
 }
}

הפרוצדורה מציגה את כל צירופי הסכומים האפשריים של תאי המערך,

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

זמן הריצה של הפרוצדורה (או כל בעיה כזאת של צירופים) הוא !n (במקרה זה : !4 )

כל הכבוד לתגובה לעיל, אני אישית לא הצלחתי לפתור ברקורסיה (לא חשבתי על הטריק של ה OR ).

חזרה לתחילת העמוד הצג את כרטיס החבר של גרשון חפש הודעות אחרות של גרשון בקר בדף הבית של גרשון
 
ahron
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 28 March 2009 בשעה 04:37 | IP רשוּם
ציטוט ahron

גרשון שכח מזה, הפתרון שלך הוא לא נכון הוא עובד רק במקרה הזה עם המערך הזה. בגלל שיש לך יחס של 1:1 בין מס' הלולאות למס' הפרמטרים במערך.
אם אתה לא מאמין לי תוסיף פרמטר- לדוגמא: 4 בסוף המערך ותראה שלא תקבל את הסכום 7 לדוגמא (3+4) או 12 (3+4+5).
בקיצור חבל על המאמץ שלך, זאת אחת הבעיות הידועות במדעי המחשב, שהבעיה הכוללת שלה ידועה כאחת הבעיות המתמטיות של המילניום, כאלה ששברו עליה את הראש מתמטיקאים דגולים.

חזרה לתחילת העמוד הצג את כרטיס החבר של ahron חפש הודעות אחרות של ahron בקר בדף הבית של ahron
 
גד
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 31 March 2009 בשעה 23:52 | IP רשוּם
ציטוט גד

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 08 April 2009 בשעה 01:24 | IP רשוּם
ציטוט אהרון

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

לבעיה עצמה שנחשבת בעיית החלטה (NP complete) כמובן שיש פתרון, הן רקורסיבי והן איטרטיבי שניהם לא יעילים.
חזרה לתחילת העמוד הצג את כרטיס החבר של אהרון חפש הודעות אחרות של אהרון בקר בדף הבית של אהרון
 
wavenator
משתמש מתחיל
משתמש מתחיל


הצטרף / הצטרפה: 07 October 2008
משתמש: מנותק/ת
הודעות: 2
נשלח בתאריך: 12 April 2009 בשעה 11:25 | IP רשוּם
ציטוט wavenator

ahron כתב:

גרשון שכח מזה, הפתרון שלך הוא לא נכון הוא עובד רק במקרה הזה עם המערך הזה. בגלל שיש לך יחס של 1:1 בין מס' הלולאות למס' הפרמטרים במערך.
אם אתה לא מאמין לי תוסיף פרמטר- לדוגמא: 4 בסוף המערך ותראה שלא תקבל את הסכום 7 לדוגמא (3+4) או 12 (3+4+5).
בקיצור חבל על המאמץ שלך, זאת אחת הבעיות הידועות במדעי המחשב, שהבעיה הכוללת שלה ידועה כאחת הבעיות המתמטיות של המילניום, כאלה ששברו עליה את הראש מתמטיקאים דגולים.


בגלל זה יש פונקציה רקורסיבית
חזרה לתחילת העמוד הצג את כרטיס החבר של wavenator חפש הודעות אחרות של wavenator
 
kotz
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 13 April 2009 בשעה 04:00 | IP רשוּם
ציטוט kotz

פתרתי גם רקורסיבית וגם איטרטיבית.

kotzkotz@gmail.com

 

חזרה לתחילת העמוד הצג את כרטיס החבר של kotz חפש הודעות אחרות של kotz בקר בדף הבית של kotz
 

אם ברצונך להגיב לנושא זה עליך קודם להתחבר
אם אינך רשום/ה כבר עליך להרשם

  שליחת תגובהשליחת נושא חדש
גרסת הדפסה גרסת הדפסה

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