Cặp ghép với số đỉnh rất lớn

6 530 5
Cặp ghép với số đỉnh rất lớn

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

Thông tin tài liệu

Cặp ghép với số đỉnh rất lớn

Cặp ghép với số đỉnh rất lớnVõ Xuân SơnTrong số 26 (11/2001), tác giả Lê Văn Chương đã giới thiệu cho chúng ta thuật toán Kuhn − Munkres giải bài toán tìm cặp ghép có tổng trọng số lớn nhất, nhỏ nhất nhưng với số đỉnh rất bé. Sau đây, dựa theo thuật toán Kuhn − Munkres tôi trình bày bài toán cặp ghép với số đỉnh rất lớn (nhỏ hơn 5000 đỉnh).Ví dụ minh hoạ.Bài toán xếp hình:1 trò chơi xếp hình trên máy tính từ những ô hình vuông kích thước giống nhau. Mỗi ô hình vuông này được chia thành 4 tam giác, mỗi tam giác có thể nhận 1 trong 4màu đỏ, xanh, vàng, trắng. (quy ước: 0 − đỏ; 1 − xanh; 2 − vàng; 3− trắng) như hình vẽ: Người chơi cần dùng chuột kéo những ô vuông đã cho vào một lưới ô vuông M hàng, N cột đến khi đầy lưới sau đó có thể nhấn chuột để quay ô. Mỗi lần nhấn chuột ô quay 1 góc 900 theo chiều kim đồng hồ. Giả thiết mỗi lần kéo một ô vuông vào một vị trí của lưới mất 1s và mỗi lần nhấn chuột mất 1s. Bằng những thao tác như vậy, người chơi cần tạo ra một hình giống như hình mẫu cho trước với thời gian nhanh nhất.Các ô vuông đã cho được đánh số từ 1. Trạng thái của ô vuông được mã hoá bằng 1 byte (8 bit) như sau: hai bit trái nhất mô tả giá trị mầu của tam giác phía Bắc, lần lượt các nhóm 2 bit tiếp theo mô tả giá trị mầu của các tam giác phía Đông, Nam, Tây của ô vuông.Dữ liệu vào: Xephinh.inp (m, n ≤ 50)Dữ liệu ra: Xephinh.outNếu không có cách xếp thì ghi -1Ví dụ: Tư tưởng thuật toán:Đầu tiên chúng ta tìm các trạng thái có thể có được khi xoay các ô vuông theo chiều kim đồng hồ. Sau đó tiến hành ghép cặp các trạng thái đặt vào các ô của hình mẫu sao cho cách ghép đó là ghép được và thoả mãn với hình mẫu, Từ đó tiến hành lần lượt các bước như trong thuật toán Kuhn − Munkres với tổng thời gian (trọng số) nhỏ nhất.Các bạn có thể tham khảo thuật toán này qua chương trình sau:Program xephinh;const inp = ′xephinh.inp′;out = ′xephinh.out′;Ln = 2500;Var c: array [1 ln, 0 3] of byte;mau, tt: array [1 ln] of byte;px, py: array [1 ln] of integer;F, q, qu: array [1 ln*2] of integer;m, n, mn, x, y, i, u, z: integer;start: longint; g: text;procedure input;beginassign (g,inp) ; reset (g);readln (g,m,n); mn:= m*n;for x:=1 to mn do read (g,tt[x]);readln (g);for x:=1 to mn do readln(g, mau[x]);close (g);start:= meml [0: $46c];End;procedure state;var b1, b2: byte; beginfor x:=1 to mn dofor y:=0 to 3 dobeginc[x, y]:=tt[x];b1:= tt[x] shr 2;b2:= byte (Tt[x] shl 6);Tt[x]:= b1 or b2;end;end;procedure khoitao;var ok: boolean;beginfillchar (f, sizeof (f), 0);fillchar (px, sizeof (px), 0);fillchar (py, sizeof (py), 0);for x:=1 to mn dobeginok:= false;for i:= 0 to 3 dobeginfor y:= 1 to mn doIf (py[y]=0) and (c[x,i] = mau [y]) thenbeginpx [x]:= y;py[y]:= x;ok:=true;break;end;if ok thenbeginF[x]:=i;break;end;end;end;end;Function liberty: boolean;beginfor x:=1 to mn do;if px[x]= 0 thenbeginliberty:= true;u:=x; exit;end;liberty:= false; end;Function Findpath: boolean;Var dau, cuoi, v,w,n: integer;beginfillchar (q, sizeof (q),0);dau:=1; cuoi:= 1; qu[1]:=u; q[u]:=u;while dau <= cuoi dobeginv:= qu[dau]; inc(dau);if v<= mn then;for x:=0 to 3 dofor u:= mn + 1 to mn * 2 doif c[v, x] =mau [u-mn] thenif (F[v] + F[u]= x) and (q[w] = 0) thenbegin q[u]:= v;inc (cuoi);qu [cuoi]:= w;end;if v > mn thenif py[v - mn] = 0 thenbeginfindpath:=true;z:= v ;exit;endelse beginu:=py[v-mn];inc (cuoi);qu [cuoi]:= w;q[u]:= v;end;end;findpath:= false;end;procedure tangcg;var thuocy: boolean;beginy:= y ; thuocy:= true;while y<> u dobegin x:= q[y];if thuocy thenbeginpx [x]:= y - mn;py [y-mn]:= x;end;y:= x; thuocy:= not thuocy;end;end;procedure suanhan;var d, h: integer;begind:= maxint;for x:= 1 to mn doif q[x] > 0 thenfor y:= mn + 1 to mn * 2 doif q[y] = 0 thenfor i:= 0 to 3 doif c[x,i] =mau [y-mn] thenbeginh:= i - f[x] - f[y];if d>h then d:= h;break;end;for x:=1 to mn doif q[x] > 0 then f[x]:= f[x] + d;for y:= mn+1 to mn * 2 doif q[y] > 0 then f[y]:= f[y] - d;end;procedure Virus;beginassign (g,out) ; rewrite (g);write (g, -1); close (g); halt;end;procedure process;beginwhile liberty dobeginwhile not findpath dobeginif (meml [0: $46c] - start) / 18.22 > 1 then virus;suanhan;end;tangcg;end;end;procedure output;beginassign (g,out); rewrite (g);for x:=1 to mn dobeginwrite (g,py[x],′ ′); if x mod n = 0 then writeln (g);end;for x:=1 to mn dobeginfor y:= 0 to 3 doif c[py[x], y] = mau[x] thenbeginwrite (g, y+1, ′ ′);break;end;if x mod n =0 then writeln(g);end;close (g);end;begininput;state;khoitao;process;output;end. . tìm cặp ghép có tổng trọng số lớn nhất, nhỏ nhất nhưng với số đỉnh rất bé. Sau đây, dựa theo thuật toán Kuhn − Munkres tôi trình bày bài toán cặp ghép với. Cặp ghép với số đỉnh rất lớnVõ Xuân SơnTrong số 26 (11/2001), tác giả Lê Văn Chương đã giới thiệu

Ngày đăng: 07/09/2012, 11:39

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan