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

Cặp ghép trong lập trình pascal

9 1K 17
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

Tiêu đề Cặp ghép
Tác giả Lê Văn Chương
Trường học Trường Đại Học
Thể loại Bài viết
Định dạng
Số trang 9
Dung lượng 52,5 KB

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

Nội dung

Tìm hiểu về cặp ghép

Trang 1

Cặp Ghép

Lê Văn Chương Định nghĩa cặp ghép

Xét hai tập hữu hạn X, Y gồm n phần tử:

X= {x1, x2, ,xn}

Y= {y1, y2, ,yn}

Cặp phần tử (x,y) với x thuộc X, y thuộc Y được gọi là một cặpghép Hai cặp ghép (x,y) và (x', ý) được gọi là rời nhau nếu x # x' và y # ý.Tập M gồm các cặp ghép rời nhau được gọi

là một tập cặp ghép

{ Thông thường bài toánxây dựng các cặp ghép được tiếp cận theo 2 hướng hoặc thỏa mãn một điều kiệnghép cặp nào đấy, khi đó người ta quan tâm đến khả năng ghép cặp tối đa, hoặclượng hoá việc ghép cặp, khi đó người ta quan tâm đến phương án ghép cặp tối

ưutheo các giá trị đã lượng hoá }

Vì số tập cặp ghép là hữu hạn, nên một phương pháp xây dựngđơn giản là thử tất cả các khả năng Tuy nhiên, số khả năng như vậy là rất lớn.Vì thế, phải tìm kiếm những thuật giải thật hữu hiệu, dễ cài đặt chương trìnhvà có tính khả thi cao

Bài toán tìm cặp ghép đầy đủtối ưu

a Giới thiệu bài toán:Bài toán tìm cặp ghép đầy đủ tối ưu có nhiều mô hình ứng dụng thực

tế.Một trong những mô hình này là người ta quan tâm đến việc ghép cặp sao cho cóhiệu quả nhất

Để lượng hoá việc ghép mỗi phần tử x thuộc X với một phần tử y thuộc Y,người ta đưa vào ma trận số Cij (i,j = 1, 2, , n) với ý nghĩa Cijmô tả hiệu quả của việc ghép xi với yj Bài toán được đặtra là: Xây dựng một tập cặp ghép đầy đủ có tổng hiệu quả lớn nhất

Bài toán vừa nêu thường được phát biểu dưới dạng một mô hìnhthực tế là bài toán phân công:

Bài toán phân công: Cón người và n công việc Biết C ij là số tiền làm ra nếu giao

côngviệc j cho người i thực hiện Hãy tìm cách phân công mỗi người mỗi việc để tổngsố tiền làm ra là lớn nhất.

b Định lý về cặp ghép: Việcxây dựng tập cặp ghép đầy đủ tối ưu dựa vào dấu hiệu nhận

biết một tập cặp ghépđầy đủ khi nào là tối ưu Dĩ nhiên việc thử dấu hiệu này không phải

Trang 2

là việc sosánh với tất cả các cặp ghép, mà phải được xây dựng mang tính khả thi Để làmđiều này, người ta xây dựng hàm số F, xác định trên tập các phần tử xi thuộc X, yj thuộc Y, màta sẽ gọi là nhãn của các phần tử Nhãn F được gọi là chấp nhận được nếu thoảmãn bất đẳng thức F(xi)+F(yj)>=Cij với mọixi thuộc X,yj thuộc Y.Tập cặp ghép M và nhãn F được gọi là tương thích với nhau nếu thoả mãn đẳngthức F(xi)+F(yj)=Cij với mọi xi thuộc X, yj thuộc Y.Nói riêng, tập cặp ghép rỗng được xem như tương thích với mọi nhãn

Định lý:Tập cặp ghép đầy đủ M là tối ưu khi tồntại nhãn F chấp nhận được là tương thích

với nó.

c Thuật toán Kuhn-Munkres: Nội dung chủ yếu của phương pháp là xuất phát từ một tập

cặp ghépnào đó chưa đầy đủ (có thể là rỗng), ta tăng dần số cặp ghép sao cho khi trởthành đầy đủ, các cặp ghép thu được cũng đồng thời thoả mãn tính tối ưu Cónhiều hình thức trình bày phương pháp này Dưới đây là cách trình bày trên ngônngữ đồ thị kèm với việc dùng thuật toán tìm đường đi

Giả sử F là một nhãn chấp nhận được và M là tập cặp ghép tươngthích với F Xem các phần tử của X và Y như những đỉnh của một đồ thị có hướnghai phía Các cạnh của đồ thị này được xác định tuỳ thuộc nội dung của nhãn Fvà tập cặp ghép M như sau:

- Mỗi cặp phầntử xi thuộc X,yj thuộc Ythoả mãn đẳng thức F(xi)+F(yj) = Cij sẽ xácđịnh một cạnh của đồ thị

- Cạnh này cóhướng từ X sang Y nếu cặp (xi,yj) không thuộc M và ngượclại

Đồ thịxây dựng theo quy tắc vừa nêu được gọi là đồ thị cân bằng tương ứng với F, M vàđược ký hiệu là G(F, M)

Bước 1 Khởi tạo:

Xây dựng nhãn F chấp nhận đượcnhư sau:

F(xi):=Max{Cij, yj thuộc Y} xithuộc X

F(yj):=0 yj thuộc Y

M là tập cặp ghép rỗng

Bước 2 Tìm đỉnh tự do thuộc X:

Tìm đỉnh u thuộc Xchưa được ghép cặp Nếu không còn đỉnh nào của X chưa ghép cặp thì kết thúc:tập cặp ghép M hiện hành là tập cặp ghép đầy đủ tối ưu Trái lại sang bước kếtiếp

Bước 3 Tìm đường tăng cặp ghép:

Trang 3

Xuất phát từ u, thực hiện việctìm kiếm trên đồ thị G(F, M) Kết quả tìm kiếm có hai trường hợp:

- Nếu đến đượcmột đỉnh z thuộcY chưa ghép cặp thì ghi nhận đường đi từ u đến z và chuyển sang bước tăng cặpghép trên đường đi này

- Nếu không tồntại một đường đi như vậy thì chuyển sang bước sửa nhãn F

Bước4 Tăng cặp ghép: điều chỉnh M như sau:

- Giữ nguyênnhững cặp ghép của M nằm ngoài đường tăng cặp ghép

- Trên đườngtăng cặp ghép, bỏ đi những cặp ghép của M là cạnh ngược và thêm vào M những cặpghép là cạnh thuận

Sau bước này,số cặp ghép thuộc M được tăng thêm 1 và đỉnh u được bảo toàn Sau đó quay vềbước 2 để lặp lại vởi đỉnh tự do khác

Bước5 Sửa nhãn:

Gọi S là tậpcác đỉnh thuộc X và T là tập các đỉnh thuộc Y đã được đi đến trong quá

trìnhtìm kiếm ở bước 3

Việc sửa nhãn Fđược tiến hành như sau:

- Tìm lượng sửanhãn:

d:= min{F(xi) + F(yj)- Cij, xi thuộcS, yj thuộcT}

- Gán lại nhãn:

F(xi):=F(xi) -d với xi thuộcS

F(yj):=f(yj) +d với yj thuộcT

Sau đó, quay vềbước 3 để lặp lại việc tìm đường tăng cặp ghép

Chú ý rằng, sau khi thayđổi, nhãn F vẫn giữ nguyên tính chấp nhận được và tính tương thích với M Ngoàira có thêm ít nhất một cặp (xi, yj) thoả mãn F(xi)+F(yj) = C ij, vì thế, sau một số lần sửa nhãn chắc chắnsẽ tăng được cặp ghép

Dưới đây là sơ đồ khối mô tả các bướcthực hiện trên:

Trang 4

Các bạn có thể tham khảo thuật toán này quachương trình.

Chươngtrình:

Program Capghep;

Const Fi='capghep.Inp';

MaxN=100;

Var f:Text;

Total,n,i,j,u,Path:Integer;

A,B,Cg:Array[1 MaxN]Of 0 MaxInt;

Tr,Q:Array[1 2*MaxN]Of 0 2*MaxN;

S,T: Array[1 MaxN] Of 0 1;

Yetx,Yety:Array[1 MaxN]Of Boolean;

C:Array[1 MaxN,1 MaxN]Of 0 MaxInt;

Procedure ReadF;

Begin

Trang 5

Reset(f);

Readln(f,n);

For i:=1 to n do

For j:=1 to n do Read(f,C[i,j]);

Close(f);

End;

ProcedureFindPath(u:Integer);

Var dq,cq,v:Integer;

Begin

Path:=0;

dq:=1;cq:=1;Q[1]:=u;S[u]:=1;

Tr[1]:=0;

While cq>=dq Do

Begin

v:=Q[dq];Inc(dq);

If v<=n Then

For i:=1 to n do

If (A[v]+B[i]=C[v,i])And(T[i]=0) Then Begin

T[i]:=1;

Inc(cq);Q[cq]:=i+n;

Tr[i+n]:=v;

Trang 6

If Yety[i] Then Begin Path:=i+n;Exit;End; End;

If v>n Then

Begin

v:=v-n;

For i:=1 to n do

If (B[v]+A[i]=C[i,v])And(S[i]=0) Then Begin

S[i]:=1;

Inc(Cq);Q[Cq]:=i;

Tr[i]:=v+n;

End;

End;

End;

End;

Procedure IncCg;

Var Way,m,i,j:Integer;

Begin

m:=Path;Way:=0;

Repeat

If m>n Then j:=m-n Else i:=m;

If Way=0 Then Way:=1

Else If Way=1 Then

Trang 7

Way:=-1;Cg[i]:=j;

Yety[Cg[i]]:=True;

Yetx[i]:=False;Yety[j]:=False;

End Else

Begin

Way:=1;Yety[j]:=True;

End;

m:=Tr[m];

Until m=0;

End;

Procedure Change;

Var d,i,j:Integer;

Begin

d:=MaxInt;

For i:=1 to n do

If S[i]=1 Then

For j:=1 to n do

If T[j]=0 Then

If (d>A[i]+B[j]-C[i,j]) Then d:=A[i]+B[j]-C[i,j]; For i:=1 to n do

If S[i]=1 Then Dec(A[i],d);

For i:=1 to n do

Trang 8

If T[i]=1 Then Inc(B[i],d);

End;

Procedure Main;

Begin

ReadF;

{Enter }

For i:=1 to n do

Begin

A[i]:=0;B[i]:=0;

For j:=1 to n do

If C[i,j]>A[i] Then A[i]:=C[i,j]; End;

FillChar(Yetx,SizeOf(Yetx),True); FillChar(Yety,SizeOf(Yety),True); FillChar(Cg,SizeOf(Cg),0);

Repeat

u:=0;

For i:=1 to n do

If Yetx[i] Then Begin u:=i;Break;End;

If u=0 Then Break;

FillChar(S,SizeOf(S),0);

FillChar(T,SizeOf(T),0);

FillChar(Tr,SizeOf(Tr),0);

Trang 9

If Path=0 Then Change Else IncCg; Until False;

Writeln('Cap ghep :');

Total:=0;

For i:=1 to n do

Begin

Writeln('(',i,',',Cg[i],')');

Inc(Total,C[i,Cg[i]]);

End;

End;

BEGIN

Main;

END

Ngày đăng: 07/09/2012, 10:30

TỪ KHÓA LIÊN QUAN

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

TÀI LIỆU LIÊN QUAN

w