Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "1 מבוא למדעי המחשב backtracking. 2 מוטיבציה בעיית n המלכות: נתון: לוח שחמט בגודל. המטרה: לסדר על הלוח n מלכות כך שאף אחת לא תאיים על השנייה. דוגמא: עבור."— Presentation transcript:

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; }


Download ppt "1 מבוא למדעי המחשב backtracking. 2 מוטיבציה בעיית n המלכות: נתון: לוח שחמט בגודל. המטרה: לסדר על הלוח n מלכות כך שאף אחת לא תאיים על השנייה. דוגמא: עבור."

Similar presentations


Ads by Google