1 מבוא למדעי המחשב תרגול מספר 14 ואחרון.... 2 הנושאים להיום...

Post on 21-Dec-2015

259 Views

Category:

Documents

14 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

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

14תרגול מספר

...ואחרון

2

הנושאים להיום

פתרון שאלות ממבחניםרקורסיהסיבוכיותBacktrackingמבנים

3

1שאלה

...נתחיל בהגדרות:מטריצה ממויינת עמודות

כל האיברים באותה העמודה מסודרים בסדר לא יורד:מטריצה ממויינת שורות

כל האיברים באותה השורה מסודרים בסדר לא יורד

4 2 -4 6 -2 3

4 5 1 7 0 5

6 7 9 8 4 7

7 9 10 9 6 10

4 5 9 10 11 21

-2 1 4 7 8 15

-6 -4 -3 5 6 7

0 0 1 3 3 4

4

- המשך1שאלה

:נגדיר מבנה נקודה, וניצור מטריצה של נקודות

מטרת השאלה היא לכתוב פונקציה בשפתC xאשר ממיינת את המערך כך שקואורדינטות

yשל איבריו יהיו ממוינות בשורות וקואורדינטות של איבריו יהיו ממוינות בעמודות.

a[0][0]=(1,1) a[0][1]=(2,5) a[0][2]=(9,1)

a[1][0]=(1,2) a[1][1]=(4,6) a[1][2]=(4,2)

a[2][0]=(1,7) a[2][1]=(3,9) a[2][2]=(8,7)

5

1שאלה

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

xיורד לפי הערך של קוארדינאטת ה

void Merge_By_x(Point a[], int n,

Point b[], int m,

Point c[]);

6

- המשך1שאלה

ממש את הפונקציה הבאה, הממיינת מערךנקודות בצורה רקורסיבית:

void internal_sort_x(Point a[], int n, Point tmp[]);

:וכעת, גם את פונקציה המעטפתvoid merge_sort_by_x(Point a[], int n, Point tmp[]);

7

- המשך1שאלה

באותה צורה, ניתן לממש את internal_sort_ymerge_sort_by_y

השלם את הפונקציהsort_by_x_and_y אשר ממיינת את של איבריו תהיינה ממוינות xהמערך כך שקואורדינטות

של איבריו תהיינה ממוינות yבשורות וקואורדינטות בעמודות.

void sort_by_x_and_y (Point a[M][N]) סיבוכיות זמןO(MN(log M + log N)) .

8

Back-Tracking לפעמים פתרון של בעיה בנוי מרצף של מהלכים, כשבכל

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

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

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

כך נעשה בכל שלב ובכל אופציה עד שנגיע לפתרון - אם ישפתרון.

9

בעיית צעדי הפרש הקדמה למי שלא יודע

שח-מט: הפרש הוא כלי שניתן להזיזו רק

לפי הכלל הבא:

צעדים בכיוון מסוים, ולאחר מכן 2צעד בודד בכיוון מאונך לכיוון

הראשוני.

10

- בעיית צעדי הפרש2שאלה

נתונה מטריצהMN ועלינו לומר אם ניתן באמצעות צעדי פרש לעבור דרך כל משבצות

המטריצה ומבלי לעבור דרך אותה משבצת פעמיים. 5למשל עבור מטריצהX6:ישנו הפתרון הבא

1 2 3 4 5 6

1 1 24 19 8 15 30

2 18 9 16 5 20 7

3 25 2 23 12 29 14

4 10 17 4 27 6 21

5 3 26 11 22 13 28

11

בעיית צעדי הפרש

:נפתח במספר הגדרות

#define N 5

#define M 6

#define FALSE 0

#define TRUE 1

typedef int Matrix[N][M];

typedef int boolean;

12

בעיית צעדי הפרש

נניח שאנו נמצאים בכניסה כלשהיmat[i][j], עקרונית אופציות להמשיך והן:8יש לנו

m[i+2][j-1] , m[i+2][j+1] m[i-2][j-1] , m[i-2][j+1] m[i+1][j+2] , m[i+1][j-2] m[i-1][j+2] , m[i-1][j-2]

.אולם חלק מהאופציות עלולות להיות לא חוקיותמדוע?

13

בעיית צעדי הפרש

:backtrackשלבי אלגוריתם ה- שעונה על השאלה: האם ניתן למלא fill_boardנרצה לכתוב פונקציה

?(mat[i][j])את כל משבצות המטריצה מהמשבצת הנוכחית

1.(אסור לעבור בה שוב בהמשך) סמן את המשבצת הנוכחית . 2 אם סומנו .M*N ! משבצות – סיימנו )return true(;. 3 מהמשבצת הנוכחית: 8>= (החוקיים. לכל אחד מהצעדים (

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

4 -3. אם היתה הצלחה באחת הקריאות הרקורסיביות ב ,return true;

.;return false, 1 אחרת בטל את הסימון מסעיף

14

בעיית צעדי הפרש

:פונקצית עזר שבודקת אם צעד הוא חוקי

boolean legal(Matrix mat, int i, int j)

{

return !( (i>=N||i<0) || (j>=M||j<0) || mat[i][j] );

}

15

בעיית צעדי הפרש

מעבר על כל הצעדים החוקיים מהמשבצתהנוכחית:

static int d_row[ ] = {+2,+2,-2,-2,+1,+1,-1,-1};

static int d_col[ ] = {+1,-1,+1,-1,+2,-2,+2,-2};

for(t = 0 ;t < 8 ; ++t)

if(legal(mat , i+d_row[t] , j+d_col[t]))

fill_board(mat , i+d_row[t] , j+d_col[t]);

16

בעיית צעדי הפרש - הקוד המלאboolean fill_board(Matrix mat, int i, int j) {

int t;

static int cnt = 0 ;

static int d_row[ ] = {2,2,-2,-2,1,1,-1,-1} ;

static int d_col[ ] = {1,-1,1,-1,2,-2,2,-2} ;

mat[i][j] = ++cnt ;

if(cnt==M*N) { /* Halt condition */

cnt = 0 ;

return TRUE;

}

for(t = 0 ;t < 8 ; ++t) /* All possible moves */

if(legal(mat , i+d_row[t] , j+d_col[t]))

if(fill_board(mat , i+d_row[t] , j+d_col[t]))

return TRUE;

/*Can't fill the remaining entries from this entry*/

mat[i][j] = 0 ;

cnt--;

return FALSE;

}

17

בעיית צעדי הפרש

int main()

{

Matrix mat={0};

fill_board(mat,0,0);

print_mat(mat);

return 0;

}

:וכך נקרא לפונקציה שלנו

18

- בעיית האנוי3שאלה

רוצים להעבירn חישוקים ממגדל A למגדל B תוך שימוש במגדל C

19

פתרון מגדלי האנוי

void Hanoi(int n, int from, int via, int to) {

if (n == 0) return;

Hanoi(n-1, from, to, via);

printf("Move Disk from %d to %d",from, to);

Hanoi(n-1, via, from, to);

}

20

ואריאציה על האנוי

יש לפתור את בעיית האנוי תחת האילוץ שהעברתהחישוקים חייבת להיות בין שני עמודים סמוכים

)C ל A(לא ניתן להעביר חישוק מ

? כיצד נקטין את הבעיה) אם ההעברה היא לא דרך המוט האמצעיB אז (

אפשר להקטין את הבעיה בצורה רגילה

21

פיתרון לואריאציה של האנוי

22

1סיבוכיות

23

2סיבוכיות

24

חשב סיבוכיות זמן ומקום#include “stdio.h”

int k = 2001;

void detective( int a[], int n) {

int i;

if (k == 2001) {

i='s';

printf("%c ", 'i'+1);

{

for (i = 0; i < n; i++ ) {

a[i] += k;

printf( "%d ", *(a+i));

}

k *= 2;

}

void shamus( int *a, int n) { int delta; detective(a, n(; delta = n/2; if (delta > 0) shamus(a,delta);}

25

פתרון

n

n

n

nnnnnT

nn

nTnT

nnT

nT

nn

TnT

2

2

log210

log32

2

2

2

1...

2

1

2

1

2

1)

2...

222(1)

...2

(2)()

2(

2)(

2)

(2)()

2

21

1

1

2

1

2

1

0

log

0

2

i

iin

i

top related