Download presentation
Presentation is loading. Please wait.
1
1 מבוא למדעי המחשב backtracking
2
2 מוטיבציה בעיית n המלכות: נתון: לוח שחמט בגודל. המטרה: לסדר על הלוח n מלכות כך שאף אחת לא תאיים על השנייה. דוגמא: עבור 2 מלכות, לא קיים פתרון. Q Q
3
3 מוטיבציה בעיית n המלכות: דוגמא: פתרון אפשרי עבור 4 מלכות. Q Q Q Q
4
4 בעיית n המלכות פתרון אפשרי: לבדוק את כל האפשרויות: עבור n מלכות מספר האפשרויות הוא: עבור n=4 ← 43,680 אפשרויות. עבור n=8 ← 178,462,987,637,760אפשרויות.
5
5 בעיית n המלכות פתרון אפשרי: לבדוק את כל האפשרויות. החיסרון: מעבר שיטתי על קבוצת כל המיקומים האפשריים מתייחס לכל פתרון בנפרד ולא מבחין בפתרונות בעלי מכנה משותף שיכלו להיבדק (ולהיפסל !) כמקשה אחת בשלב מוקדם. דוגמא: Q Q
6
6 Backtracking הרעיון: בניית הפתרונות האפשריים בצורה שיטתית. בכל שלב מנסים ללכת צעד אחד קדימה. במידה ומתאפשר ממשיכים. במידה ולא – חוזרים לשלב הקודם ומנסים לבחור בצעד אחר. למשל, עבור בעיית n המלכות: ברור כי עלינו למקם בכל שורה בדיוק מלכה אחת. נעבור על השורות לפי הסדר. עבור השורה ה- i : ננסה למקם את המלכה כך שלא תאיים על המלכות בשורות 1,…,i-1. אם נצליח, נמשיך לשורה הבאה. אם לא, נחזור לשורה הקודמת ונשנה את מיקום המלכה שם. נחזור על התהליך באופן רקורסיבי עד למציאת כל הפתרונות.
7
7 בעיית n המלכות – פתרון בעזרת backtracking /* queens.c */ /* print all solutions of the 8 (N) queens problem */ #include #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
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
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
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
11 בעיית n המלכות – פתרון בעזרת backtracking שיפור הפתרון : במקום לייצג את הלוח ע " י טבלה ( מערך דו - מימדי ) ניתן להיעזר במערך חד - מימדי כאשר בתא ה - i יימצא אינדקס העמודה בה ממוקמת המלכה בשורה ה - i. Q Q Q Q 0 1 2 3 0123 0 1 2 3 1 3 0 2
12
12 בעיית n המלכות – פתרון בעזרת backtracking /* queens1.c */ /* print all solutions of the 8 (N) queens problem */ #include #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
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
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
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; }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.