1 / 15

מבוא למדעי המחשב

מבוא למדעי המחשב. backtracking. מוטיבציה. בעיית n המלכות: נתון: לוח שחמט בגודל . המטרה: לסדר על הלוח n מלכות כך שאף אחת לא תאיים על השנייה. דוגמא: עבור 2 מלכות, לא קיים פתרון. Q. Q. Q. Q. Q. Q. מוטיבציה. בעיית n המלכות: דוגמא: פתרון אפשרי עבור 4 מלכות.

kalb
Download Presentation

מבוא למדעי המחשב

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. מבוא למדעי המחשב backtracking

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

  3. Q Q Q Q מוטיבציה בעיית n המלכות: דוגמא: פתרון אפשרי עבור 4 מלכות.

  4. בעיית n המלכות פתרון אפשרי: • לבדוק את כל האפשרויות: עבור n מלכות מספר האפשרויות הוא: עבור n=4←43,680 אפשרויות. עבור n=8← 178,462,987,637,760אפשרויות.

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

  6. Backtracking הרעיון: • בניית הפתרונות האפשריים בצורה שיטתית. • בכל שלב מנסים ללכת צעד אחד קדימה. • במידה ומתאפשר ממשיכים. במידה ולא – חוזרים לשלב הקודם ומנסים לבחור בצעד אחר. למשל, עבור בעיית n המלכות: • ברור כי עלינו למקם בכל שורה בדיוק מלכה אחת. נעבור על השורות לפי הסדר. • עבור השורה ה- i : ננסה למקם את המלכה כך שלא תאיים על המלכות בשורות 1,…,i-1. • אם נצליח, נמשיך לשורה הבאה. • אם לא, נחזור לשורה הקודמת ונשנה את מיקום המלכה שם. • נחזור על התהליך באופן רקורסיבי עד למציאת כל הפתרונות.

  7. בעיית n המלכות – פתרון בעזרת backtracking /* queens.c */ /* print all solutions of the 8 (N) queens problem */ #include <stdio.h> #define N 5 enum {EMPTY,QUEEN}; enum {FALSE, TRUE}; void solve (char board[N][N], int row); void print_board (char board[N][N]); int threatens (char board[N][N], int row, int column); int main() { char board[N][N]; int i,j; /* initialize board to empty */ for (i=0; i<N; i++) { for (j=0; j<N; j++) { board[i][j]=EMPTY; } } solve(board,0); return 0; }

  8. בעיית n המלכות – פתרון בעזרת backtracking void solve (char board[N][N], int row) { int column=0; if (row == N) { print_board(board); } else { for (column=0; column < N; column++) { if (!threatens(board, row, column)) { board[row][column] = QUEEN; solve(board, row+1); board[row][column] = EMPTY; } } } return; }

  9. בעיית n המלכות – פתרון בעזרת backtracking void print_board(char board[N][N]) { int i,j; static int counter=0; printf("Solution number %d:\n", ++counter); for (i=0; i<N; i++) { for (j=0; j<N; j++) { printf("%s", (board[i][j]==EMPTY)?" . ":" Q "); } printf("\n"); } printf("\n"); }

  10. בעיית n המלכות – פתרון בעזרת backtracking /* threatens: return TRUE if "board" has a queen which threatens position [row,column] */ int threatens(char board[N][N], int row, int column) { int r; /* check if there's a queen on this column */ for (r=0; r<row; r++) { if (board[r][column] == QUEEN) { return TRUE; } } /* check if there's a queen on the diagonals */ /* first, check the upper-left diagonal: [row-r,column-r] */ for (r=1; row-r>=0 && column-r>=0; r++) { if (board[row-r][column-r] == QUEEN) { return TRUE; } } /* then, check the upper-right diagonal: [row-r,column+r] */ for (r=1; row-r>=0 && column+r<N; r++) { if (board[row-r][column+r] == QUEEN) { return TRUE; } } return FALSE; }

  11. Q Q Q Q בעיית n המלכות – פתרון בעזרת backtracking שיפור הפתרון: במקום לייצג את הלוח ע"י טבלה (מערך דו-מימדי) ניתן להיעזר במערך חד-מימדי כאשר בתא ה- i יימצא אינדקס העמודה בה ממוקמת המלכה בשורה ה- i. 0 1 2 3 2 0 0 0 1 1 3 2 2 1 3 3

  12. בעיית n המלכות – פתרון בעזרת backtracking /* queens1.c */ /* print all solutions of the 8 (N) queens problem */ #include <stdio.h> #define N 8 enum {EMPTY,QUEEN}; enum {FALSE,TRUE}; void solve (char board[N], int row); void print_board (char board[N]); int threatens (char board[N], int column); int main() { static char board[N]; solve(board,0); return 0; }

  13. בעיית n המלכות – פתרון בעזרת backtracking void solve (char board[N], int row) { int col; if (row == N) { print_board(board); } else { for (col=0; col < N; col++) { board[row] = col; if (!threatens(board, row)) { solve(board, row+1); } } } return; }

  14. בעיית n המלכות – פתרון בעזרת backtracking void print_board(char board[N]) { int i,j; static int counter=0; printf("Solution number %d:\n", ++counter); for (i=0; i<N; i++) { for (j=0; j<N; j++) { printf("%s", (board[i]==j)?" Q ":" . "); } printf("\n"); } printf("\n"); }

  15. בעיית n המלכות – פתרון בעזרת backtracking /* threatens: return TRUE if "board" has a queen which threatens position [row,column] */ int threatens(char board[N], int row) { int i; for (i=0; i<row; i++) { /* check if there's a queen on this column */ if ( board[i] == board[row] ) { return TRUE; } /* check upper-right diagonal */ if ( board[i] == board[row] + (row-i) ) { return TRUE; } /* check upper-left diagonal */ if ( board[i] == board[row] - (row-i) ) { return TRUE; } } return FALSE; }

More Related