1. Trang chủ
  2. » Công Nghệ Thông Tin

Thuật toán Loang và gắn nhãn

5 1,7K 71
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 39 KB

Nội dung

Thuật toán Loang và gắn nhãn

Trang 1

Kỹ thuật loang đổ mảng và gán nhãn các đỉnh

Nguyễn Thành Trung

Trong các số báo của ISM trước đây đã đề cập rất nhiều đến thuật toán tìm kiếm theo chiều rộng (BFS) và có thể nói đó là một thuật toán tìm kiếm "mù", tức là quá trình tìm kiếm sẽ lập đi lập lại cho đến khi tìm được phương án Như vậy, đòi hỏi một lượng lớn không gian lưu trữ và thời gian thực hiện nhất là đối với những bài toán mà cây tìm kiếm gần như vô tận Để khắc phục điều đó, chúng ta sẽ dùng kỹ thuật loang đổ mảng và gán nhãn các đỉnh Kỹ thuật đó giúp tránh được các trạng thái lặp cũng như các trạng thái

mà chắc chắn không dẫn đến lời giải, từ đó giảm bớt không gian lưu trữ, tìm kiếm và làm cho quá trình tìm kiếm "có tính dừng"

Loang đổ mảng: trong quá trình loang, thường các bạn hay dùng một hàng đợi để lưu lại toàn bộ các trạng thái đã thăm và chuẩn bị thăm Nhưng ta chú ý loang là tìm kiếm theo mức, từ một mức khởi đầu sẽ sinh ra mức tiếp theo và từ mức tiếp theo sẽ sinh ra mức tiếp theo nữa… Khi đó, mức đã được dùng để sinh không còn cần thiết nữa nghĩa là ta hoàn toàn có thể loại bỏ chúng ra khỏi hàng đợi để lấy "chỗ" cho các trạng thái sau Từ ý tưởng trên, ta sẽ dùng 2 mảng khác thay thế cho 1 hàng đợi để lưu lại 2 mức liên tiếp nhau

Sau đây, chúng ta điểm qua 1 số bài toán tìm kiếm đầy thú vị:

Bài 1: Chuyển bi

Cậu bé vẽ N (N<=100) vòng tròn, đánh số từ 1 tới N và tô màu các vòng tròn đó (có thể

có các vòng tròn có màu giống nhau) Sau đó nối từng cặp lại bằng các cung định hướng, mỗi cung có một màu nhất định Các màu (của cung và của vòng tròn) được đánh số từ 1 đến 100

Cậu bé chọn 3 số nguyên khác nhau L, K và Q nằm tong phạm vi từ 1 tới N, đặt vào trong các vòng tròn số L và K mỗi vòng một hòn bi, sau đó bắt đầu di chuyển bi theo qui tắc sau:

- Bi chỉ được chuyển theo cung có màu trùng với màu của vòng tròn chứa viên bi thứ 2

- Bi chỉ được chuyển theo chiều cung

- Hai viên bi không được đồng thời ở cùng một vòng tròn

- Quá trình di chuyển kết thúc, khi một trong hai viên bi tới vòng tròn Q

Hãy lập trình xác định cách di chuyển để chấm dứt quá trình sau một số ít nhất các bước chuyển

Dữ liệu: vào từ file BI.INP:

- Dòng đầu: 4 số nguyên N L K Q

- Dòng thứ 2: N số nguyên C1, C2, …, CN (Ci: là màu của vòng tròn i)

- Dòng thứ 3: số nguyên M (0<=M<=10000)

- M dòng sau: mỗi dòng 3 số nguyên Ai Bi Di xác định cung màuDi đi từ vòng tròn Ai tới vòng tròn Bi

Các số trên một dòng cách nhau 1 dấu cách

Kết quả: đưa ra file BI.OUT:

- Dòng đầu: YES hoặc NO cho biết quá trình có kết thúc được hay không

- Nếu dòng đầu là YES thì dòng 2 chứa số nguyên xác định số bước chuyển tối thiểu

Trang 2

Thật không khó để các bạn có thể giải quyết bài toán trên bằng thuật toán loang thông thường với điều kiện nghiệm phải ở một mức tìm kiếm cho phép, còn khi nghiệm ở một mức khá lớn hoặc vô nghiệm, chắc chắn chúng ta không thể biết được liệu phải cần một không gian lưu trữ lớn như thế nào và liệu quá trình tìm kiếm có dừng hay không? Như vậy, nó làm mất đi tính tổng quát của một bài toán tin học

Để ý rằng, một trạng thái được ghi nhận là số thứ tự của 2 vòng tròn chứa 2 viên bi và ta coi nó là một nút của cây tìm kiếm, ký hiệu (i,j)

Gọi nhãn của một nút là f(i,j): f(i,j)=0 hoặc f(i,j)=1 cho biết nút đó chưa thăm hay đã thăm Như vậy một nút sẽ được thăm nếu nó thỏa mãn mọi điều kiện của bài toán và nhãn của nó có giá trị 0 Từ đó, ta suy ra rằng một mức sẽ có không quá n2 nút Do vậy, ta sẽ dùng 2 mảng q1, q2 kích thước n*n để lưu lại các nút của 2 mức liên tiếp

Sau đây là toàn văn chương trình:

const inp=’bi.inp’;

out=’bi.out’;

var a,q1,q2,f:array[1 100,1 100] of byte;

c:array[1 100] of byte;

n,v1,v2,v3:byte;

m,dem:integer;

stop:boolean;

fi:text;

procedure docf;

var i,j,mau:byte;

k:integer;

begin

assign(fi,inp);

reset(fi);

readln(fi,n,v1,v2,v3);

for k:=1 to n do read(fi,c[k]);

readln(fi);

readln(fi,m);

fillchar(a,sizeof(a),0);

for k:=1 to m do

begin

readln(fi,i,j,mau);

a[i,j]:=mau;

end;

close(fi);

end;

procedure initBFS;

begin

fillchar(f,sizeof(f),0) {khởi tạo tất cả các nút đều chưa thăm}

fillchar(q1,sizeof(q1),0) {mức khởi đầu chưa có nút nào}

fillchar(q2,sizeof(q2),0) { mức tiếp theo cũng chưa có nút nào}

q1[v1,v2]:=1;q1[v2,v1]:=1;

f[v1,v2]:=1;f[v2,v1]:=1;

end;

Trang 3

procedure inkq;

begin

writeln(fi,’YES’);

writeln(fi,dem);

close(fi);

halt;

end;

procedure play;

var i,j,k:byte;

begin

for i:=1 to n do

for j:=1 to n do

if q1[i,j]=1 then

for k:=1 to n do

if (k<>j) and (a[i,k]=c[j]) and (f[k,j]=0) then

begin

q2[k,j]:=1;q2[j,k]:=1;

f[k,j]:=1;f[j,k]:=1;

stop:=false;

if k=v3 then inkq;

end;

end;

procedure BFS;

begin

dem:=0; {bắt đầu ở mức 0}

repeat

inc(dem);

stop:=true;

play;

if stop=false then

begin

q1:=q2; {ghi đè mức mới lên mức cũ}

fillchar(q2,sizeof(q2),0); {khởi tạo mức mới chưa có nút nào} end;

until stop;

procedure xuly;

begin

assign(fi,out);

rewrite(fi);

initBFS;

BFS;

writeln(fi,’NO’);

close(fi);

end;

begin

docf;

Trang 4

xuly;

end

Qua chương trình trên, ta có thể thấy ngay rằng, quá trình tìm kiếm sẽ dừng khi

tất cả các nhãn đều có giá trị 1

Đến đây, chắc các bạn đã thấy "sự lợi hại" của kỹ thuật loang đổ mảng và gán nhãn các đỉnh

Bài 2: Lâu đài

Splendid, vua xứ Byteotia muốn cho cô con gái xinh đẹp của mình − công chúa Ada xuất giá Ông hỏi con gái muốn người chồng của mình phải thế nào Công chúa trả lời là chồng tương lai phải là một người thông minh đồng thời không hoang phí cũng như không keo kiệt bủn xỉn Nhà vua suy nghĩ khá lâu về cách kiểm tra để chọn cho công chúa người tốt nhất Cuối cùng ông thấy hay nhất là sử dụng lâu đài của mình để tổ chức tiếp đãi mọi cư dân của Byteotia Lâu đài có rất nhiều phòng, trong đó trưng bày các báu vật quốc gia Theo các hành lang trong lâu đài, người ta có thể ghé vào phòng này hay phòng khác, ngắm nhìn các hiện vật độc đáo trưng bày, mang lại những kinh ngạc thích thú cho người xem Để ghé vào mỗi phòng, người tham quan phải trả một số Bytealer (đơn vị tiền tệ của Byteotia) Cuộc tham quan bắt đầu từ phòng có cửa vào lâu đài Nhà vua trao cho mỗi người trong điện có thể chọn làm phò mã một túi tiền, với một số lượng Bytealer như nhau Nhà vua yêu cầu mỗi người tự chọn đường đi tham quan, bắt đầu từ phòng vào lâu đài và kết thúc ở phòng công chúa ngồi Mỗi người được yêu cầu chi hết đúng số tiền trong túi được trao Những người hoang phí quá nhiều cho việc ghé xem các phòng trưng bày và hết tiền trước khi đến được phòng công chúa Ngược lại, những người keo kiệt tới phòng công chúa nhưng với túi vẫn còn tiền, kết quả là bị công chúa đuổi ra ngoài sau khi thu hết số tiền dư trong túi

Thật không may là vẫn chưa có chàng trai nào hoàn thành nhiệm vụ nhà vua đã trao và công chúa vẫn phải trông chờ, hy vọng một khi nào đó sẽ có kết cục tốt đẹp Tại sao bạn lại không thử vận may của mình xem sao? Bạn có thể lập trình để trợ giúp cho nàng công chúa tội nghiệp đó

Dữ liệu: vào từ file văn bản Castle.inp

- Dòng đầu tiên có 5 số nguyên n,m,e,p,b (1<=n<=100; 1<=m<=4950; 1<=e,p<=n; 1<=b<=1000) trong đó n: số phòng; m: số hành lang; các phòng được đánh số từ 1 tới n; e:phòng vào lâu đài; p: phòng có công chúa; b: số Bytealer trong túi

- Dòng thứ 2 chứa n số nguyên dương c1,c2,…,cn (1<=ci<=1000) ci: tiền cần trả để vào xem phòng i

- M dòng tiếp theo: mỗi dòng chứa một cặp số nguyên dương x, y (x≠y,1<=x,y<=n) cho biết có hành lang nối 2 phòng x và y

Các số trên một dòng cách nhau ít nhất 1 dấu cách

Kết quả: đưa ra file văn bản Castle.out dãy số nguyên xác định các phòng cần ghé từ

phòng e tới phòng p

Bài toán này cũng tương tự như bài toán trên, nó chỉ khác ở chỗ mỗi đỉnh bây giờ không phải chỉ có 1 nhãn mà là b nhãn

Ta dùng 2 mảng f,c kích thước n*b:

f[i,j]: là nhãn thứ j của đỉnh i

c[i,j]: lưu đỉnh trước của đỉnh i ứng với nhãn j

Tuy nhiên do các nhãn của một đỉnh chỉ có giá trị 0,1 nên ta có dùng bit để tiết kiệm bộ nhớ

Trang 5

Phần cài đặt xin dành cho các bạn

Cần lưu ý rằng, việc loang đổ mảng sẽ không thể thực hiện được khi ta chưa xác định số lượng lớn nhất các trạng thái có trong một mức

Hy vọng với kỹ thuật trên, các bạn có thể giải được một lớp lớn các bài toán có tính chất tìm kiếm

Ngày đăng: 11/09/2012, 15:00

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w