1. Trang chủ
  2. » Tất cả

LOANG TRONG LƯỚI Ô VUÔNG

30 4 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 30
Dung lượng 247 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Để hiểu rõ bản chất của thuật toán này, ta hãy xem xét mộtcách đưa ra thứ tự duyệt các đỉnh của một đồ thị vô hướng G = V,E, N đỉnh và M cạnh số hiệu của các đỉnh là 1,2,…,N như sau: Thứ

Trang 1

LOANG TRONG LƯỚI Ô VUÔNG Trần Xuân Bình, Chuyên viên Tin học, Sở Giáo dục và Đào tạo Hà Tĩnh

I) THUẬT TOÁN LOANG:

Thuật toán Loang thực chất là thuật toán tìm kiếm theo chiều rộng trên đồ thị

(Breadth First Search) Để hiểu rõ bản chất của thuật toán này, ta hãy xem xét mộtcách đưa ra thứ tự duyệt các đỉnh của một đồ thị vô hướng G = (V,E), N đỉnh và

M cạnh (số hiệu của các đỉnh là 1,2,…,N) như sau: Thứ tự duyệt có thể bắt đầu từmột đỉnh v nào đó Tư tưởng của thuật toán là sử dụng cấu trúc dữ liệu kiểu hàngđợi (QUEUE - vào trước ra trước) Phần tử được nạp vào đầu tiên của QUEUE làđỉnh v Sau đó cứ mỗi đỉnh p lấy ra khỏi QUEUE là ta thăm đỉnh đó đồng thời nạpvào QUEUE những đỉnh chung cạnh với p (chỉ nạp vào những đỉnh chưa xét đến).Quá trình trên được lặp đi lặp lại cho đến khi nào QUEUE rỗng thì dừng

QUEUE = ; {Khởi tạo QUEUE ban đầu là rỗng}

QUEUE <= v; {Nạp đỉnh v vào QUEUE}

Chuaxet[v]:=False;{Đỉnh v nạp vào QUEUE là đã xét rồi => cờ của v làFalse}

While QUEUE ≠ do

Begin

P <= QUEUE; {Lấy p từ QUEUE}

Thăm đỉnh p;

For u € Ke(p) do {Những đỉnh u chung cạnh với đỉnh p}

If Chuaxet(u) then {Nếu đỉnh u chưa xét đến}

Begin

QUEUE <= u; {Nạp u vào QUEUE}

Trang 2

Chuaxet[u]:=False; {Đỉnh u đã xét rồi =>cờ của u là False } End;

Với bài toán trên ta sử dụng mảng 1 chiều Q: Array[1 N] of Byte để biểu diễnQUEUE Khi đó thao tác nạp vào và lấy ra được thực hiện như sau:

FillChar(Q,SizeOf(Q),0); {Khởi tạo tất cả các phần tử của Q có giá trị 0}

Dau:=1;

Cuoi:=1;

Q[cuoi]:=v; {Ban đầu nạp đỉnh v vào Q}

Để nạp thêm đỉnh u nào đó vào Q ta thực hiện:

Cuoi:=Cuoi+1; {Hoặc dùng lệnh Inc(Cuoi)}

Q[Cuoi]:=u;

Để lấy một đỉnh p nào đó ra khỏi Q ta thực hiện:

P:=Q[Dau];

Inc(Dau);

Lưu ý: Ta nói lấy đỉnh p ra khỏi hàng đợi Q là lấy ra theo cơ chế điều khiển (vì

biến Dau đã tăng lên một đơn vị qua lệnh Inc(Dau)); về mặt vật lý thì p vẫn đang nằm trong mảng Q Như vậy ta phải hiểu rằng các phần tử trong cấu trúc hàng đợi Q là các phần tử Q[Dau], ,Q[Cuoi]

Trang 3

A:Array[1 Nmax,1 Nmax] of 0 1;{Nếu có cạnh giữa đỉnh i và đỉnh j thì

A[i,j]=1, ngược lại A[i,j]=0 }

Chuaxet:Array[1 Nmax] of Boolean;{Cờ của các đỉnh, có trạng thái True nếu

chưa xét, ngược lại False}

Q:Array[1 Nmax] of Byte;{Biểu diễn hàng đợi QUEUE}

Trang 4

dau:=dau+1; {Lấy đỉnh p ra khỏi Q }

If (dau-1) mod 14 = 0 then Writeln(p:4) {In ra số hiệu đỉnh p - thao tác

Trang 5

FillChar(Chuaxet,Sizeof(Chuaxet),True); {Khởi tạo cờ của tất cả các đỉnh đều ở

trạng thái True - Trạng thái chưa xét}

Writeln('Thu tu tham cac dinh cua do thi khi tim kiem theo chieu rong la:'); For i:=1 to N do

If Chuaxet[i] then BFS(i);

Writeln;

Readln;

END

Chương trình trên thực hiện với dữ liệu vào là tệp TKR_DT.INP có cấu trúc:

- Dòng đầu tiên, được gọi là dòng 0: ghi các số nguyên dương N, x cáchnhau ít nhất là một ký tự trống (N: Số đỉnh của đồ thị; x: Đỉnh xuất phát);

- Trong các dòng tiếp theo: Dòng thứ i (i = 1 N-1) ghi N-i số 0 và 1 liêntiếp nhau cho biết giữa đỉnh i và đỉnh j có cạnh nối với nhau hay không (j = i +1 N) Nếu số ghi ở vị trí j-i tính từ trái sang phải trên dòng thứ i có giá trị 1 thì cócạnh nối giữa đỉnh i và đỉnh j, nếu là giá trị 0 thì không có cạnh nối

Ví dụ với tệp TKR_DT.INP sau đây:

Trang 6

- giữa đỉnh 1 với đỉnh 2 có cạnh nối với nhau

- giữa đỉnh 1 với đỉnh 3 không có cạnh nối với nhau

- giữa đỉnh 1 với đỉnh 4 có cạnh nối với nhau

- giữa đỉnh 1 với đỉnh 5 không có cạnh nối với nhau

- giữa đỉnh 1 với đỉnh 11 không có cạnh nối với nhau

- giữa đỉnh 1 với đỉnh 12 có cạnh nối với nhau

- giữa đỉnh 1 với đỉnh 13 không có cạnh nối với nhau

+ Ở dòng 2: 01000000000

- giữa đỉnh 2 với đỉnh 3 không có cạnh nối với nhau

- giữa đỉnh 2 với đỉnh 4 có cạnh nối với nhau

+ Ở dòng 11: 10

- giữa đỉnh 11 với đỉnh 12 có cạnh nối với nhau

- giữa đỉnh 11 với đỉnh 13 không có cạnh nối với nhau

+ Ở dòng 12: 0

- giữa đỉnh 12 với đỉnh 13 không có cạnh nối với nhau

Quan hệ giữa các đỉnh được mô tả qua đồ thị sau:

2 3 5

Trang 7

7 8

4

1 6 9

12 13

10 11

Thứ tự các đỉnh được nạp vào hàng đợi Q và lấy ra tuần tự như sau:

Các phần tử

nạp vào Q

Các phần tử

có trạng thái

cờ là False

Các phần tử trong Q

Phần tử lấy

ra khỏi Q

Không nạp phần tử nào khi

lấy 2 ra khỏi Q

Không nạp phần tử nào khi

lấy 10 ra khỏi Q

Không nạp phần tử nào khi

lấy 11 ra khỏi Q

Không nạp phần tử nào khi

lấy 13 ra khỏi Q

Không nạp phần tử nào khi

lấy 3 ra khỏi Q

Không nạp phần tử nào khi

lấy 8 ra khỏi Q

Không nạp phần tử nào khi

lấy 9 ra khỏi Q

Các phần tử tuần tự được lấy ra khỏi hàng đợi Q chính là các đỉnh được duyệt:

1, 2, 4, 12, 6, 7, 10, 11, 5, 13, 3, 8, 9

Trang 8

Qua đó cho thấy từ một đỉnh ta thăm đến các đỉnh khác liên quan đến nó theo chiều rộng Chính vì vậy thuật toán tìm kiếm theo chiều rộng được gọi là thuật toán Loang.

II) LOANG TRONG LƯỚI Ô VUÔNG:

Nhiều mô hình bài toán Loang được đưa ra trong các lưới ô vuông, khi đó việc thểhiện tư tưởng của thuật toán như thế nào?

Để rèn luyện kỹ năng "loang" trong lưới ô vuông, tôi xin giới thiệu cách giải haibài toán sau đây:

Bài toán 1: Đường đi của Robot (Đề thi HSG lớp 12 năm học 2009 - 2010, Tỉnh

Hà Tĩnh)

Một bảng hình chữ nhật có kích thước MxN (M,N nguyên dương và không lớnhơn 100) được chia thành các ô vuông đơn vị bằng các đường thẳng song songvới các cạnh Một số ô vuông nào đó có thể đặt các vật cản Từ một ô vuông,Robot có thể đi đến một ô vuông kề cạnh với nó nếu ô vuông đó không có vậtcản Hỏi rằng nếu Robot bắt đầu xuất phát từ một ô vuông không có vật cản thuộcdòng K, cột L thì có thể đi đến được ô vuông không có vật cản thuộc dòng H, cột

O hay không? Nếu có thì hãy chỉ ra đường đi qua ít ô vuông nhất

Dữ liệu vào là tệp văn bản BAI3.INP có cấu trúc:

- Dòng đầu tiên ghi các chữ số M, N, K, L, H, O Các số ghi cách nhau ít nhấtmột ký tự trống;

- M dòng tiếp theo, mỗi dòng ghi N số 1 hoặc 0 tuỳ thuộc vào ô vuông tươngứng trong bảng hình chữ nhật nêu trên có vật cản hay không (ghi số 1 nếu có vậtcản); các số trên mỗi dòng ghi liên tiếp nhau

Dữ liệu ra là tệp văn bản BAI3.OUT có cấu trúc:

Nếu Robot có thể đi được từ ô vuông thuộc dòng K, cột L đến ô vuông thuộcdòng H, cột O thì:

- Dòng đầu tiên ghi ‘Co duong di ‘;

Trang 9

- Các dòng tiếp theo, mỗi dòng ghi 2 số là chỉ số dòng và chỉ số cột của các ôvuông trong đường đi tìm được từ ô vuông thuộc dòng K, cột L đến ô vuôngthuộc dòng H, cột O mà qua ít ô vuông nhất Hai số trên mỗi dòng ghi cách nhau

Hàng đợi phục vụ “loang” được thể hiện bởi mảng 2 chiềuQ:Array[1 2,Mmax*Max] of Byte; hàng thứ 1 của Q để lưu thông tin chỉ số hàng,hàng thứ 2 lưu thông tin của chỉ số cột của các ô khi nạp vào Q

Mảng A lưu thông tin tình trạng các ô - có vật cản hay không của bảng hình chữnhật chứa các ô vuông

Trang 10

Mảng P dùng để đánh dấu những ô đã “loang” đến; đồng thời để phục vụ cho việctruy xuất đường đi sau này nên khi ô [i,j] được “loang” đến thì P[i,j] được gán giátrị là r (r là giá trị tương ứng với hướng mà ô trước đó “loang” đến, hướng nàotương ứng với giá trị k bao nhiêu tuỳ theo quy định, ví dụ r = 1 - sang phải, 2 - đixuống, 3 - sang trái, 4 - đi lên).

Sau khi thực hiện xong việc “loang”, nếu P[H,O] = 0 thì điều có có nghĩa là ô[H,O] chưa được “loang” đến (không có đường đi), nếu P[H,O] = r (r=1 4 - loangtheo 4 hướng) thì dựa vào hướng “loang” đến mà ta tìm được ô trước đó, rồi ta lạidựa vào giá trị k của ô tìm được ta tìm được ô trước đó nữa quá trình trên kếtthúc khi tìm được ô [K,L]

Sau khi “loang” xong thì giá trị các phần tử trong mảng Q không còn giá trị sửdụng nữa nên ta có thể dùng mảng Q phục vụ cho việc truy xuất kết quả

Toàn văn chương trình:

Trang 11

If (i=h) and (j=o) then Exit;{Đến ô cần đến}

If (i>1) and (P[i-1,j]=0) and (A[i-1,j]=0) then

Trang 14

Tuy nhiên ta nhận thấy rằng trong mảng A thông tin của các ô đã “loang” đến rồithực sự không còn quan trọng nữa nên ta có thể dùng chính mảng A để thay thếchức năng của mảng P Hàng đợi Q có thể thay đổi mỗi phần tử là một record HC: Type

HC = Record

Trang 15

h,c:Byte; {h: lưu chỉ số hàng, c: lưu chỉ số cột}

End;

Từ một ô trong lưới ô vuông (có giá trị các ô là 0/1) “loang” theo 4 hướng, ngoàicách trình bày như chương trình trên ra, người ta sử dụng kỷ thuật “rào” và 2mảng hằng Hi=(-1,0,1,0) Hj=(0,-1,0,1) để cài đặt chương trình một cách gọn hơn,trong sáng hơn:

- Kỷ thuật “rào”: Khai báo mảng A: Array[0 Mmax+1,0 Nmax+1] of Byte; rồisau đó dùng lệnh SetfillChar(A,SizeOf(A),1); (mảng A được “rào” xung quanhbởi số 1), nhờ vậy mà khi “loang” không cần phải kiểm tra điều kiện của chỉ sốhàng, cột các ô

Hj:Array[1 4] of Integer=(0,-1,0,1); {Tương ứng với chỉ số cột, -1:trái, 1:phải}

Thực hiện “loang” theo 4 hướng:

Trang 16

End;

End;

Trong đoạn chương trình trên ta thấy:

- Với r =1 => Hi[r] = Hi[1] = -1 => i + Hi[1] = i – 1, có nghĩa là chỉ số hànggiảm đi một đơn vị (1)

Hj[r] = Hj[1] = 0 => j + Hj[1] = j – 0 , có nghĩa là chỉ số cộtkhông đổi (2)

(1) và (2) <=> thao tác di chuyển đến ô chung cạnh ở phía trên (đi lên)

- Với r =2 => Hi[r] = Hi[2] = 0 => i + Hi[2] = i + 0, có nghĩa là chỉ số hàngkhông đổi (3)

Hj[r] = Hj[2] = -1 => j + Hj[2] = j – 1 , có nghĩa là chỉ số cộtgiảm đi một đơn vị (4)

(3) và (4) <=> thao tác di chuyển đến ô chung cạnh ở phía bên trái (sangtrái)

- Tương tự với các giá trị khác của r

Với những vấn đề nêu ra ở trên, chương trình có thể cải tiến lại như sau:

Trang 17

s:char;

A:Array[0 Mmax+1,0 Nmax+1] of Byte; Q:Array[1 Mmax*Nmax] of HC;

Trang 18

If (i = H) and (j = O) then Exit;

For r:=1 to 4 do {r=1:lên 2:trái 3:xuống 4:phải}

Trang 19

Writeln(f,'Co duong di'); dem:=1;

Inc(dem);

If A[i,j]=1 then

Begin

Q[dem].h:=i+1; Q[dem].c:=j;

If A[i,j]=3 then

Begin

Q[dem].h:=i-1; Q[dem].c:=j;

i:=Q[dem].h;

j:=Q[dem].c;

Trang 20

Bài toán 2: Gặp gỡ của hai Robot.

Trên một lưới ô vuông MxN (M,N<100), người ta đặt Robot A ở góc trái trên,Robot B ở góc phải dưới Mỗi ô của lưới ô có thể đặt một vật cản hoặc không (ôtrái trên và ô phải dưới không có vật cản) Hai Robot bắt đầu di chuyển đồng thờivới tốc độ như nhau và không Robot nào được dừng lại trong khi Robot kia dichuyển (trừ khi nó không thể đi được nữa) Tại mỗi bước, Robot chỉ có thể dichuyển theo 4 hướng - đi lên, đi xuống, sang trái, sang phải - vào các ô kề cạnh.Hai Robot gặp nhau nếu chúng cùng đứng trong một ô vuông Bài toán đặt ra làtìm cách di chuyển ít nhất mà 2 Robot phải thực hiện để có thể gặp nhau

Dữ liệu vào cho bởi tệp robot.inp:

- Dòng đầu ghi 2 số M, N cách nhau ít nhất một ký tự trống;

- M dòng tiếp theo, mỗi dòng ghi N số 0 hoặc 1 liên tiếp nhau mô tả trạngthái của các ô vuông: 1 - có vật cản, 0 - không có vật cản

Dữ liệu ra ghi vào tệp robot.out:

- Nếu 2 Robot không thể gặp nhau thì ghi ký tự ‘#’

- Ngược lại, ghi hai dòng, mỗi dòng là một dãy các ký tự viết liền nhau mô

tả các bước đi của Robot: U - đi lên, D - đi xuống, L - sang trái, R - sang phải.Dòng đầu là các bước đi của Robot A, dòng sau là các bước đi của Robot B

Trang 21

3 4 0000 0000 0000

#

Phân tích:

Với dạng bài toán như vậy thì ta nghĩ ngay đến thuật toán Loang để tìm đường đicho 2 Robot Như vậy là phải “loang” từ 2 phía (loang của Robot A và loang củaRobot B) Nhưng vì 2 Robot di chuyển đồng thời trong khi không cho phép ta càiđặt việc “loang” song song từ 2 phía nên ta phải thiết kế “loang” thế nào cho hợp

Xin đề xuất một ý tưởng “loang” như sau: Cứ Robot A loang 1 lớp thì dừng lại đểRobot B loang 1 lớp, quá trình đó được lặp đi lặp lại cho đến khi 2 Robot gặpnhau tại một ô hoặc 1 trong 2 Robot dừng “loang” Một lớp “loang” ở đây là

“loang” từ các phần tử hiện có trong hàng đợi (từ phần tử Queue[dau] đến phần tửQueue[cuoi]) Sau mỗi lớp “loang”, biến dau và biến cuoi lại được điều chỉnh đểtrở thành vị trí đầu và vị trí cuối của các phần tử mới trong Queue Ta có thể mô

tả cụ thể các lớp “loang” của 2 Robot với dữ liệu vào là tệp robot.inp thứ 2 ởtrên:

Trang 22

Q1,Q2 là 2 mảng dùng để biểu diễn cấu trúc hàng đợi để phục vụ việc “loang”của 2 Robot Trong quá trình “loang” ta phải lưu giữ thông tin hàng, cột của ô khi

“loang” đến, bởi vậy các phần tử của Q1, Q2 là các record có kiểu HC

Khi đó việc “loang” theo lớp của Robot A được thực hiện như sau:

Procedure LoangA;

Var

k:Byte;

Trang 23

cuoi1:=j; {Điều chỉnh lại biến dau1, cuoi1 cho các phần tử mới trong Q1}

If dau1 > cuoi1 then ST:=True; {ST=True là Q1 rỗng, kết thúc “loang”}

End;

Việc “loang” theo lớp của Robot B cũng tương tự như Robot A nhưng chỉ khác ởchổ khi “loang” đến một ô [h,c] nào đó thì phải xét dấu hiệu B[h,c] xem thử đãgặp Robot A chưa:

Trang 24

hm:=h; {Lưu lại chỉ số hàng của ô mà 2 Robot gặp nhau để lấy kết

Quá trình “loang” theo từng lớp của 2 Robot được thực hiện như sau:

Trang 25

Việc lấy kết quả dựa vào giá trị của biến TT: TT=True - Hai Robot gặp nhau,TT=False - Hai Robot không gặp nhau.

Trong trường hợp gặp nhau thì dựa vào việc đã lưu thông tin ô gặp nhau vào 2biến hm ,cm (hm - chỉ số hàng, cm - chỉ số cột) ta sẽ truy xuất đường đi của 2Robot

Toàn văn chương trình:

Trang 29

Until (i=1) and (j=1);

{Đường đi của Robot B}

i:=hm;

j:=cm;

Trang 30

Until (i=M) and (j=N);

For i:=Length(s1) downto 1 do Write(f,s1[i]);

Ngày đăng: 17/05/2018, 12:30

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w