Thiết kế thuật toán 6 1-

Một phần của tài liệu Thiết kế và đánh giá thuật toán - Trần Tuấn Minh potx (Trang 56 - 62)

VI. Bài toán liệt kê các tổ hợp 6 1-

2. Thiết kế thuật toán 6 1-

Cách giải quyết rõ ràng là xét xem có thể thực hiện một nước đi kế nữa hay

If ( xi chấp nhận được khả năng k) { h xi theo khả năng k; i nhận trạng thái mới; i < n2 ) Try(i+1); Ghi nhận nghiệm; Tr û lại tr h ch t án; }

ể m û ch át th toa , ta ải q nh h m û d iệu ác o , đo

Bi diễ øn c

Các khả năng chọ lựa cho xi

- Cách thức xác định xi theo j.

- Ghi nhận nghiệm.

* Ta sẽ biểu diễn bàn cờ bằng 1 ma trận vuông cấp n : int h[n][n];

dấu ô đã đươ yển của con

Ô <x,y> ngựa chưa đi qua;

 <x > ngựa đã đi qua ở bước thứ i (1 ≤ i ≤ n2 ).

où chính là các nước đi của ngựa mà xi có thể

ộ bắt đầu <x,y> như trong hình vẽ, có tất cả 8 ô <u,v> mà đến 7 như hình sau : không. Sơ đồ đầu tiên có thể phát thảo như sau :

Try(i) ≡ for ( j = 1 → k) Xác địn Gh if( else a ạng t ái cũ o bài o

Đ ô ta i tie uật ùn ph ui đị các ô ta ữ l và c tha tác ù là :

- ểu n ba ờ .

- ?

- Cách thức gi nhận trạng thái mới, trả về trạng thái cũ.

. . .

Sở dĩ thể hiện mỗi ô cờ bằng 1 số nguyên thay cho giá trị boole (để đánh ïc đi qua chưa) là vì ta muốn lần dò theo quá trình di chu

ngựa.

Ta qui ước như sau : h[x][y] = 0 ≡

h[x][y] = i ≡ O ,y

* Các khả năng chonï lựa cho xi ? Đ chấp nhận được.

Với cặp tọa đ

1 2 3 4 5 Tọa Tọa độ độ (a,b) (a,b) (-2,-1) 4 3 1 (-2,1) (-1,-2) 5 2 2 (-1,2) 3 hàng x → (1,-2) 6 1 4 (1,2) (2,-1) 7 0 5 (2,1) co ↑ y ät

( 8 bước đi có thể có của co n ïa

Một phương pháp đơn giản để có được u, v từ x, y là ta dùng 2 mảng a và b u trử cá về tọa oä . ếu a d øng một chỉ số k để đánh số “bước đi kế ” ì chi tie đó đươ thể hiệ bơ : u x a[k ; v y b[ ];

n gư )

lư c sai biệt đ N t u

th át ïc n ûi = + ] = + k k =0,7 .

ươ bi d ãn ư kết hợp của các điều

nghĩa l

* Để ghi nhận nước đi hợp lệ ở bước i, ta gán h[u][v] = i; và để hủy một nước đi thì a gán

áu có <x,y> sao cho h<x,y> = 0 thì đó

n cơ

x, y;//Toạ độ xuất phát ở bước i Output h;

Mô tả : Try(i, x, y) ≡

h[u][v]

xuat_h(); // In ma trận h Điều kiện “chấp nhận được” có thể

kiện :

đ ïc ểu ie nh

Ô mới phải thuộc bàn cờ (1 ≤ u ≤ n và 1 ≤ v ≤ n) và chưa đi qua ô đó, à h[u,v] = 0;

t

* Ma trận h ghi nhận kết quả nghiệm. Ne h[u][v] = 0.

không phải là lời giải của bài toán , còn ngược là h chứa đường đi của ngựa. Vậy thuật toán có thể mô tả như sau :

Input n, //Kích thước bà ø for(k = 0; k <= 7; k++) { u = x + a[k]; v = y + b[k]; if (1 <= u ,v <= n &&h[u][v] == 0) { = i; if (i < n*n) Try(i+1,u,v); else }

h[u][v] = 0;

tục đệ qui được khởi động bằng một lệnh gọi các tọa độ đầu x0, y0 là tham số. Ô xuất phát có trị 1, còn các ô khác được đánh dấu còn trống.

H[x0 ][y0 ] = 1; Try(2,x , y );

Các mảng a và b có thể khởi đầu như sau : ,-2,-2,-1,1,2};

á kết quả cho từ thuật toán trên :

n 5 x 1 y n=6 x=2 y=3

}

Thủ tục này xuất tất cả các lời giải, nếu có. Thủ

int a[8]= {2,1,-1

int b[8]= {1,2,2,1,-1,-2,-2,-1};

* Các lời giải sau là một so

= = =1 1 6 15 10 21 36 17 6 29 8 11 14 9 20 5 16 19 30 1 10 5 28 19 2 7 22 11 16 35 18 7 12 9 8 13 24 17 4 23 20 31 2 27 4 25 18 3 12 23 34 15 22 25 32 13 21 24 33 14 3 26

* Với n = 5, các tọa độ xuất phát sau không có lời giải : (2,3), (3,2)...

III. Bài toán 8 hậu

1. Phát biểu bài toán

TÁM QUÂN HẬU ĐƯỢC ĐẶT LÊN BAØN CỜ VUA sao cho chúng không ăn được nhau .

toán này là một ví dụ nổi tiếng về việc dùng các phương pháp thử và sai và phương pháp quay lui. Bài

2. Thiết kế thuật toán

Mấu chốt của thuật toán rõ ràng là xét xem có th như thế nào. Theo luật cờ vua, một quân hậu có thể ăn cá

ể đặt quân hậu tiếp theo c quân khác nếu nằm trên cùng 1 đường, đường này có thể là :

a tọa độ vị trí của hậu).

cột j. :

Chỉ quân hậu thứ i : nằm ở hàng i. - Hàng,

- Cột,

- Các đường chéo (đi qu

Suy ra rằng mỗi hàng chỉ có thể chứa 1 và chỉ 1 quân hậu. Nên việc chọn vị trí cho quân hậu thứ i có thể giới hạn được ở hàng thứ i. Như thế tham số i trở thành chỉ hàng, và quá trình chọn vị trí cho quân hậu tiến hành trên toàn giá trị có thể có của các

Ta quy ước

x[i] = j // quân hậu thứ i đặt ở cột j;

ể qua ân hàng i) chấp nhận cột j thì cột j và 2 đường chéo qua ô i,j> ph ûi còn trống ( tức là không có quân hậu khác chiếm lĩnh)

ưu ý r ng tro chéo :

Đườn ngược (vuông góc với đường chéo chính) : tất cả các ô đều có

ường chéo thuận (song song với đường chéo chính) : gồm tất cả các ô ,j) mà có hiệu các tọa độ (i-j) là hằng số.

Cột j Đường chéo (i + j) Đ ân hậu i (tre

< a L ằ ng 2 đường - g chéo tổng 2 tọa độ i và j là hằng; - Đ (i Đường chéo (i – j) Hàng i

Do đó ta sẽ chọn các mảng Boole 1 chiều ể biểu diễn ùc trạng đ ca thái này : a[j] = 1 : Có nghĩa là không có quân hậu nào ở cột.

có quân hậu nào ở đường chéo ngược (i+j) . có quân hậu nào ở đường chéo thuận (i- j) .

Vì :

1 ≤ 16 Và -7 ≤ i - j ≤ 7. Nên

c[15];

øn trống nữa héo tương ứng cũng không còn c[ i - j ] = 0;//trống nữa .

là :

c đường chéo tương ứng trở thành trống j ] = 1;

1; b[i+j] = 1 : Có nghĩa là không c[i -j] = 1 : Có nghĩa là không

≤ i,j ≤ 8 ⇒ 2 ≤ i+j ta có thể khai báo :

int x[8], a[8], b[15],

Với các dữ liệu đã cho, thì lệnhđặt quân hậu sẽ thể hiện bởi : x[ i ] = j;// đặt quân hậu thứ i trên cột j.

a[ j ] = 0;//Khi đặt hậu tại cột j , thì cột j không co b[ i+ j ] = 0;//Các đường c

Còn lệnhDời quân hậu //Làm cho hàng i và cá

a[

b[ i+ j ] = 1; c[ i - j ] =

Còn điều kiện an toàn là ô có tọa độ ( i, j ) nằm ở hàng và các đường chéo g trị True). Do đó, có thể được thể hiện bởi biểu

y(i) ≡ for (j = 1; j <= 8; j++) i-j]) ;

ình trạng ban đầu còn trống cho hàng [j],

j, để tìm lời giải khác */ ;

chưa bị chiếm (được thể hiện bằn thức logic :

a[ji ] && b[ i + j ] && c[ i - j ]

Tr {

if (a[j] && b[i+j] && c[ { x[i] = j; a[j] = 0; b[i+j] = 0 c[i-j] = 0; if (i < 8 ) try (i+1); else Xuất(x); /* Sau khi in 1 lời giải xong,trả lại t a

ờng chéo i+j và đường chéo i- đư a[ j ] = 1 b[i+j] = 1; c[i-j] = 1; } } Ghi chú :

Thuật toán này tìm được tất cả 92 lơ

ø vì thuật toán không ghi nhận tính đối xứng.

øi giải. Thực ra là chỉ có 12 lời giải

n

khác nhau thật sự, đó la

IV. Bài toán liệt kê các dãy nhị phân độ dài

1. Phát biểu bài toán

Liệt kê các dãy có chiều dài n dưới dạng x1x2...xn , trong đó xi∈ { 0,1 }.

2. Thiết kế thuật toán

Ta có thể sử dụng sơ đồ tìm tất cả các lời giải của bài toán.Hàm Try(i) xác

định xi 1. Các giá trị này mặc nhiên

được c iện gì. Nên Hàm try(i) có thể

viết như sau : Try ( i) ≡

for (j = 0; j <= 1; j++)

, trong đó xi chỉ có 1 trong 2 giá trị là 0 hay hấp nhận mà không cần phải thoả mãn điều k

= j; n )

Cây kh ái của bài toán có thể mô tả bởi :

0 000 0 10 011 100 101 110 111 V. Ba { x[i] if (i < Try (i+1); else Xuất(x); } ông gian các trạng th 0 1 0 1 1 0 1 0 1 0 1 0 1 01 0

øi toán liệt kê các hoán vị

1. Phát biểu bài toán

Liệt kê các hoán vị của n số nguyên dương đầu tiên.

2. Thiết kế thuật toán

i i j ≠

i

hớ j đã được sử dụng ha chưa khi quay lui. Để làm điều này ta dùng một dãy các biến logic b với quy ước :

Ta biểu diễn các hoán vị dưới dạng a1 ... an ;

j. Với mọi i, a chấp nhận giá trị j nếu j chưa được sử dụng, và vì vậy ta cần ghi a

∈{1,..,n} và a ≠ a nếu i n y j ⎩ ⎨ ⎧ = = ∀ lại. ngược nếu dụng sử chưa j nếu ; 0 ; 1 : , 1n bj j

hớ cho bj ( bj = 0) và phải trả lại trạng thái một hoán vị.

át như sau : ry( i)

a[i] = j;

Sau khi gán j cho ai , ta cần ghi n cũ cho bj ( bj = True) khi thực hiện việc in xong

Ta chú ý rằng dãy các biến bj sẽ được khởi động bằng 1 Thuật toán có thể vie

T ≡

{

for ( j = 1; j <= n; j++)

if ( b[j])

b[j] = 0; // Ghi nhận trạng thái mới

Try(i+1); else

Xuất();

e; // Trả lại trạng thái cũ

I. B i toán liệt kê các tổ hợp

if (i < n) b[j] = Tru } } V à

1. Phát biểu bài toán

Liệt kê các tổ hợp chặp k trong n phần tử.

2. Thiết kế thuật toán

Ta sẽ biểu diễn tổ hợp dưới dạng x1...xk ; Trong đó :

≤ x1 < x2 < . . < xk ≤ n.

ác biến booole để ghi nhớ nữa.

<= n ; j++) <= n - k + i ) { uất(x); ên đồ thị 1 Ta nhận xét rằng với mọi j ∈ {1,..n}: x chấp nhận j i ⇔ j ∈ { c +1, . ., n-k+i}. i-1

Các giá trị j thỏa điều kiện trên mặc nhiên được chấp nhận, nên ta không cần dùng c

Thuật toán có thể viết như sau : Try( i) ≡ for ( j = 1; j if( x[i-1] + 1 <= j x[i] = j; if (i < k) Try(i+1); else X }

Một phần của tài liệu Thiết kế và đánh giá thuật toán - Trần Tuấn Minh potx (Trang 56 - 62)

Tải bản đầy đủ (PDF)

(123 trang)