1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Xu ly mang trong pascal

17 7 0

Đ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 17
Dung lượng 139,5 KB

Nội dung

Khi trén vµ ph©n phèi, ta trén c¸c Run ngîc chiÒu nhau cña vïng trén vµ ph©n phèi lu©n phiªn vµo 2 ®Çu cña vïng ph©n phèi bíc kÕ tiÕp dÔ trén h¬n.. Qu¸ tr×nh s¾p xÕp sÏ kÕt thóc nÕu vïng[r]

(1)

CÁC THUẬT TOÁN CƠ BẢN VỀ XỮ LÝ MÃNG TRONG PASCAL.

Sơ lợc chủ đề

Sau sơ lợc chủ đề đợc đề cập phần chơng trình:

+ Phần sở: công cụ phơng pháp đợc dùng xuyên suốt cho tất chơng sau phần Nó gồm phần bàn luận ngắn Pascal, theo sau giới thiệu cấu trúc liệu gồm mảng, xâu liên kết, ngăn xếp, hàng đợi Chúng ta bàn luận công dụng thực tiễn đệ quy bắt đầu hớng tới việc phân tích tiếp cận thực tốn

+ Sắp xếp: Các phơng pháp xếp đợc phát triển, đợc mô tả, đợc so sánh với Các thuật tốn cho nhiều vấn đề có liên quan đợc xem xét gồm có hàng đợi u tiên, phép chọn phép trộn Một vài tảng số đợc dùng nh tảng cho thuật toán khác tiếp sau phần

+ Xử lý chuỗi: gồm loạt phơng pháp để phân tích câu Các ky thuật nén tập mật mã đợc khảo sát Cũng vậy, giới thiệu chủ đề nâng cao đợc cung cấp qua việc xem xét vài toán quan trọng phạm vi chúng

+ Hình học: tập hợp có chọn lọc phơng pháp để giải toán liên quan đến điểm đờng ( đối tợng hình học đơn giản khác ) Chúng ta xem xét thuật tốn để tìm bao lồi tập điểm, phần giao đối tợng, để giải tốn điểm gần nhất, tìm kiếm nhiều chiều

+ Đồ thị: Một chiến lợc tổng quát để tìm kiếm đồ thị đợc phát triển đợc áp dụng cho toán liên thơng bản, gồm có đờng ngắn nhất, liên thông tối thiểu, mạng so khớp Một xem xét thống thuật toán chứng tỏ tất dựa vào thủ tục thủ tục phụ thuộc vào cấu trúc liệu phát triển trớc

+ Các thuật tốn tốn học: gồm phơng pháp từ số học số nguyên, đa thức, ma trận nh thuật toán để giải cac vấn đề toán học mà phát sinh nhiều ngữ cảnh : việc tạo số ngẫu nhiên, lỡi giải chơng trình đồng thời, xấp xỉ liệu, lấy tích phân Sự nhấn mạnh thiên khía cạnh thuật tốn phơng pháp, tảng toán học

+ Các chủ đề cao cấp: đợc thảo luận nhằm mục đích liên hệ chủ đề tập sách với nhiều lĩnh vực nghiên cứu cao cấp khác Phần cứng chuyên dụng, quy hoạch động, quy hoạch tuyến tính, tìm kiếm- vét cạn

I Sắp xếp:

1 Kh¸i niƯm:

a) Sắp xếp trình tổ chức lại dãy liệu theo trật tự định

b) Mục đích việc xếp nhằm giúp cho việc tìm kiếm liệu cách dễ dàng nhanh chóng Sắp xếp việc làm đợc dùng rộng rãi kĩ thuật lập trình nhằm sử lý liệu

c) Các giải thuật xếp đợc phân chia thành hai nhóm là: - Sắp xếp (hay xếp mảng)

Toàn sở liệu cần xếp phải đợc đa vào nhớ máy tính Do thờng đ-ợc sử dụng khối lợng liệu không vợt q dung lợng nhớ

Nhóm xếp bao gồm phơng pháp : * Phơng pháp đếm

* Phơng pháp chèn * Phơng pháp chọn * Phơng pháp đổi chổ * Phơng pháp trộn

(2)

Vận dụng trờng hợp ta phải xếp tập tin chứa nhiều mẫu tin mẫu tin có chiều dài tơng đối lớn ta khơng thể nạp tồn vào nhớ để xếp thứ tự Vì ta phải có phơng pháp thích hợp cho việc xếp tập tin

2 Sắp xếp trong: a) Khái niệm:

Cấu trúc liệu thích hợp cho phần tử cần xếp thứ tự Record Mỗi phần tử có hai vùng đặc trơng là: Vùng Key để chứa khoá phần tử đợc sử dụng giải thuật tìm kiếm, vùng info dùng để chứa đữ liệu phần tử

Ta khai b¸o : Type

Item = Record key : Integer; Info : Integer; End;

Var

A : Array[1 n] of Item;

Khoá phần tử chữ số

Yờu cu gii thớch dùng vùng nhớ thời gian thực nhanh b) Phơng pháp đếm (Counting sort)

* Gi¶i thÝch:

Nội dung phơng pháp đếm phần tử có khố nhỏ hay khố phần tử A[i] Nếu có j phần tử có khố nhỏ khố phần tử A[i] phần tử A[i] có vị trí theo thứ tự (j+1) dãy có thứ tự

Trong giải thuật, ta dùng mảng Count[i] ( i = 1, 2, n ) với Count[i] cho biết số phần tử có khố nhỏ khố phần tử A[i] Nh Count[i+1] vị trí phần tử A[i] dãy có thứ tự

* VÝ dơ:

S¾p xÕp d·y i: Count:

Nh phần tử có khoá vị trí Count[9]=7 * Thể Pascal:

Procedure Count_Sort; Var

Count : Array[1 n] of Integer; A : Array[1 n] of Item; i,j : Integer;

Begin

For i := to n Count[i] := 0; For i := n downto

For j := i-1 downto If A[i].Key < A[j].Key Then Count[j] := Count[j] + Else Count[i] := Count[i] + 1;

For i := to n S[Count[i] + 1] := A[i]; For i := to n A[i] := S[i];

End;

(3)

Nội dung phơng pháp giả sử ta có dãy A[1] A[i-1] có thứ tự, có phải xác định vị trí thích hợp phần tử A[i] dãy A[1] A[i 1] phơng pháp tìm kiếm từ A[i -1] trở A[-1] để tìm vị trí thích hợp A[i] Ta chèn A[i] vào vị trí kết đãy A[1] A[i] có thứ tự Ta áp dụng cách làm với i = 2, 3, , n

* Ví dụ:

Ta phải xếp dÃy sè:

39 50 37 89 13 62 i=2 39 50 37 89 13 62 i=3 39 50 37 89 13 62 i=4 39 50 37 89 13 62 i=5 37 39 50 89 13 62 i=6 37 39 50 89 13 62 i=7 13 37 39 50 89 62 i=8 13 37 39 50 89 62 13 37 39 50 89 62 * ThĨ hiƯn b»ng Pascal:

Procedure Insertion_Sort; Var

x : Item; i,j : Integer; Begin

For i := to n Begin

x := A[i]; A[0] := x; j := j - 1;

While x.Key < A[j].Key Begin

A[j+1] := A[j]; j := j - 1;

End;

A[j+1] := x; End;

End;

d) Phơng pháp chän (Selection Sort) * Gi¶i thÝch:

Nội dung phơng pháp bớc thứ i (i = 1, 2, 3, , n-1 ) ta lựa chọn phần tử nhỏ dãy A[i] A[n] đổi chổ phần tử với phần tử A[i] Cuối ta có dãy A[1] A[n] có thứ tự

* Ví dụ:

Ta phải xếp d·y sè :

(4)

Procedure Selection_Sort; Var

x : Item; i,j ,k : Integer; : Integer; Begin

For i := to n-1 Begin

:= A[i].Key; k := i;

For i := to n-1 For j := i+1 to n If A[j].Key < Then Begin

:= A[j].Key; k := j;

End; x := A[k]; A[k] := A[i]; A[i] := x; End; End;

e) Phơng pháp đổi chỗ:

Có nhiều phơng pháp xếp dựa việc đổi chỗ phần tử dãy Sau xét phơng pháp:

- Bubble Sort - Shake Sort - Sell Sort - Quick Sort * Bubble Sort: * Gi¶i thÝch:

Nội dung phơng pháp duyệt dãy A[1], , A[n] Nếu A[i].Key > A[i+1].Key (i = 1, 2, 3, , n-1)#0 ta đổi chỗ A[i].Key với phần tử A[i+1].Key Lập lại trình duyệt dãy khơng cịn việc đổi chổ hai phần tử

Chú ý lúc phần tử nhỏ gặp trớc tiên Nó nh bột khí nhẹ lên đun nớc Sau thứ hai phần tử nhỏ thứ đợc đặ vào vị trí Vì xếp bột thao tác nh kiểu xếp chọn, khơng làm nhiều việc để đa phần tử vào vị trí

* VÝ dơ:

Ta phải xếp dÃy số:

(5)

* ThĨ hiƯn b»ng Pascal: Procedure Bubble_Sort; Var

x : Item; i,j : Integer; Begin

For i := to n

For j := n downto i

If A[j-1].Key > A[j].Key Then Begin

x := A[j-1]; A[j-1] := A[j]; A[j-1] := x; End;

End; * C¶i tiÕn:

Ta nhận thấy lần duyệt dãy mà khơng co s xẩy đổi chổ hai phần tử dãy dang có thứ tự giải thuật kết thúc

Ta cài đặt cờ để ghi nhận điều có chơng trình sau: Procedure Bubble_Sort2;

Var

x : Item; i : Integer; flag : Boolean; Begin

flag := true; While flag Begin

flag := False; For i := to n-1

If A[i].Key > A[i+1].Key Then Begin

x := A[i]; A[i] := A[i+1]; A[i+1] := x; End;

End; End;

f* Shake Sort: * Gi¶i thÝch:

Phơng pháp cải tiến phơng pháp Bubble Sort theo hớng "Không phần tử nhẹ lên mà phần tử nặng xuống dới" giống nh ta rung"rung" nồi thuật toán xếp phải đợc điều khiển hai trình "nổi lên" "chìm xuống" cách tự giác Muốn ta phải ghi nhớ lần đổi chổ cuối duyệt dãy từ lên duyệt từ xung để định chu trình duyệt từ đâu đến đâu

* VÝ dơ:

S¾p xÕp d·y sè:

(6)

c = 8 7 39 1 1 50 39 39 7 50 39 13 37 37 13 37 89 37 50 37 39 13 89 13 50 50 13 62 62 62 62 62 89 89 89 * ThĨ hiƯn b»ng Pascal: Procedure Shake_Sort; Var

x : Item; i,k,d,c : Integer; Begin

d := 2; c := n; k := n; Repeat

For i := c downto d

If A[i-1].Key > A[i].Key Then Begin

x := A[i-1]; A[i-1] := A[i]; A[i-1] := x; k := i; End; d := d + 1;

For i := d to c

If A[i-1].Key > A[i].Key Then Begin

x := A[i-1]; A[i-1] := A[i]; A[i-1] := x; k := i; End; c := k-1; Until d>c; End;

g * Shell Sort: * Gi¶i thÝch:

(7)

* Ví dụ:

Ta phải xếp dÃy số:

39 50 39 89 13 62 Bíc 1: 4-Sort

39 50 39 89 13 62 39 13 37 89 50 62 Bíc 2: 2-Sort

39 13 37 89 50 62 13 37 39 50 89 62 Bíc 3: 1-Sort

13 37 39 50 89 62 13 37 39 50 89 62 * ThĨ hiƯn b»ng Pascal:

Chó ý:

- Ta dùng dãy phụ chứa dộ tăng h[i], , h[t] để điều khiển trình xếp thứ tự với h[t]=1 Việc chộn độ tăng thích hợp làm giảm thời gian thứ tự

- Dặt h1 = h[1] ta phải khai báo dÃy a nh sau: A : Array[1 n] of Item;

phần tử A[i] (i<=0) lính canh Sau ta chọn: h[1] = 9, h[2] = 5, h[3] = 3, h[4] =

Procedure Shell_Sort; Const

t = 4; Var

x : Item; i,j,k,s,m: Integer;

h : Array[1 t] of Integer; Begin

h[1] = 9; h[2] = 5; h[3] = 3; h[4] = 1;

For m := to t Begin

k := h[m]; s := -k;

For i := k+1 to n Begin

x := A[i]; j := i - k;

If s = Then s:=-k; s := s + 1;

A[s] := x;

While x.Key<A[j].Key Begin

A[j+k] :=A[j]; j := j - k; End;

(8)

End; End; h Quick Sort: * Gi¶i thÝch:

Nội dung phơng pháp chọn phần tử x dãy làm chuẩn để so sánh Ta phân hoạch dãy thành dãy liên tiếp nhau:

- D·y thø nhÊt gồm phần tử có khoá nhỏ x.key - DÃy thứ hai gồm phần tử có khoá b»ng x.key - D·y thø ba gåm c¸c phần tử có khoá lớn x.key

Sau áp dụng giải thuật phân hoạch cho dãy thứ nhất dãy thứ ba, dãy có nhiều phần tử (Đệ qui)

Cụ thể xét doạn dãy từ thành phần L đến thành phần thứ R - Lấy giá trị thành phần thứ (L+R) Div gán vào biến X

- Cho i ban đầu L - Cho j ban đầu R - Lập lại

* Chừng A[i] < X tăng i * Chừng A[j] > X giảm j * i<=j

+ Hoán vị A[i] A[j] + Tăng i

+ Giảm j Cho đến i>j

+ Sắp xếp đoạn từ A[L] đến A[j] + Sắp xếp đoạn từ A[i] đến A[R] * Ví dụ:

S¾p xÕp d·y sè:

39 50 37 89 13 62 X = 37

Sau lần đổi chổ ta đợc dãy: 13 37 89 50 39 62 Xử lý dãy con:

13 Ta đợc: 13 Sử lý dãy con: 89 50 39 62 Ta đợc:

39 50 89 62 39 50 62 89 Vậy dãy xếp là: 13 39 50 62 89 * Thể Pascal:

Để đơn giản ta viết thủ tục mảng số nguyên đợc truyền tham biến Procedure Quick_Sort(Var A : Array[1 n] of Integer);

Procedure Sort(L,R : Integer); Var

i,j,Tg,X : Integer; Begin

(9)

i := L; j := R; Repeat

While (A[i] < X) Inc(i); While (A[j] > X) Dec(j); If i <= j Then

Begin

Tg := A[i]; A[i] := A[j]; A[j] := Tg; Inc(i); Dec(j); End; Until i>j;

If L < j Then Sort(L,j); If i < R Then Sort(i,R); End;

Begin Sort(1,n); End;

i Phơng pháp trọn (Merging Sort) * Giải thích:

Nội dung phơng pháp chia dãy số cần thành dãy có thứ tự(goi Run) có số phần tử luỹ thừa sau tìm cách trộn dần chúng với thành Run có thứ tự chiều dài tăng dần cịn Run q trình xếp kết thúc

Ta có giải thuật sau để trộn Run x y thứ tự có chiều dài lần lợt m n thành run z có chiều dài m + n

Procedure Merge; Var

i,j,k : Integer; Begin

i := 1; j := 1; k := 1;

While (i <= m) and (j <= n) Begin

If X[i] < Y[j] Then Begin

Z[k] := X[j]; i := i + 1; End

Else Begin

Z[k] := Y[j] j := j + 1; End;

k := k + 1; End;

While i<=m Begin

(10)

k := k + 1; i := i + 1; End;

While j<=n Begin

Z[k] := X[j]; k := k + 1; j := j + 1; End;

End;

Cụ thể ta phải xếp dÃy: A[1], A[2], ,A[n]

Ta phải sử dụng 2*n phần tử đợc chia thành vùng Vùng gồm phần tử A[1] A[n], vùng gồm phần tử A[n+1] A[2*n] Ta trộn Run từ vùng phân phối vào vùng Khi trộn phân phối, ta trộn Run ngợc chiều vùng trộn phân phối luân phiên vào đầu vùng phân phối bớc dễ trộn Quá trình xếp kết thúc vùng phân phối Run Khi kết thúc, vùng phân phối gồm phần tử A[n+1] A[2*n] ta chép dãy A[n+1] A[2*n] vào dãy A[1] A[n]

ThÓ hiÖn b»ng Pascal

Procedure mergesort ( l , r : integer ); Var i , j , k , m: integer;

Begin

If r-l>0 then Begin

m := (r+l) div 2;

mergesort (l,m); mergesort (m+1,r); for i:=m downto l b [i] := a [i]; for j:=m+1 to r b [r+m+1-j] := a [j]; for k := l to r

if b[i] < b [j] then

begin a [k] := b[i]; i:=i+1; end else begin a [k] := b[j]; j:=j-1; end; end;

End; End;

II Hình học:

- Điểm đối tợng sở hình học Mỗi điểm mà xét sau đợc biểu diễn cặp số nguyên- toạ độ điểm hệ trục Descart thờng dùng

- Một đoạn thẳng cặp điểm đợc nối với phần đờng thẳng

- Một đa giác danh sách điểm, với hai điểm cạnh đợc nối đờng thẳng điểm đầu nối với điểm cuối tạo thành hình đóng

Thơng thờng dùng mảng để biểu diễn đa giác, số trờng hợp ta dùng danh sách liên kết hay kiểu khác Hầu hết chơng trình dùng kiểu sau đây:

Type point = record x , y : integer; end; line = record p1 , p2 : pointer; end; Var polygon : array [0 nmax] of point;

Chú ý điểm đợc biểu diễn toạ độ nguyên, dùng số thực nhng dùng tọa độ nguyên thuật tốn đơn giản nhiều phép tính thực nhanh đáng kể

(11)

Trong học sơ cấp đầu tiên, xét xem đoạn thẳng có giao hay không Một phơng pháp dễ hiểu để giải tốn tìm giao điểm đ ờng thẳng xác định đoạn thẳng kiểm tra xem có nằm hai điểm đầu hai đoạn thẳng hay khơng Một cách dễ dàng khác xem thử xem đờng từ điểm thứ sang điểm thứ sang điểm thứ theo chiều kim đồng hồ hay ngợc chiều kim đồng hồ:

Function ccw ( p0 , p1 , p2 : pointer ) : integer; Var dx1 , dx2 , dy1 , dy2 : integer;

Begin

dx1:=p1.x; dy1:=p1.y-p0.y; dx2:=p2.x; dy2:=p2.y-p0.y; If dx1*dy2>dy1*dx2 then ccw:=1; If dx1*dy2<dy1*dx2 then ccw:=1; If dx1*dy2=dy1*dx2 then

Begin

If (dx1*dx2<0) or (dy1*dy2<0) then ccw:=-1 else If (dx1*dx1+dy1*dy1) >= (dx2*dx2+dy2*dy2) then ccw := else ccw := 1;

End; End;

Để hiểu đợc chơng trình hoạt động nh nào, ta giả sử tất giá trị dx1 , dx2 , dy1 , dy2 dơng Sau nhận xét độ dốc đờng nối p0 với p1 dy1 / dx1, đờng nối p0 với p2 dy2 / dx2 Do đó, độ dốc đờng thứ hai lớn đờng thứ đờng từ p0 sang p1 , p2 ngợc chiều kim đồng hồ ngợc lại So sánh độ dốc bất tiện đờng theo phơng thẳng đứng ( dx1 hay dx2 = ), tính tích dx1 * dx2 để tránh trờng hợp Do độ dốc khơng cần phải dơng Hàm ccw trả lại giá trị cho trờng hợp p2 p0 p1, -1 p0 p2 p1 p1 p0 p2 gán ccw = Chúng ta dùng trực tiếp ccw để cài đặt hàm intersect ( xét giao ) Nếu hai đầu đoạn thẳng hai bên đoạn kia, nghĩa có giá trị ccw khác chúng giao nhau:

Function intersect ( l1 , l2 : line ) : boolean; Begin

intersect:=(( ccw(l1.p1,l1.p2,l2.p1)

* ccw(l1.p1,l1.p2,l2 p2)) <= 0) and (( ccw(l1.p1,l1.p2,l2 p1)

* ccw(l1.p1,l1.p2,l2 p2)) <= 0); End;

Giải pháp có vẽ dùng số lợng lớn tính tốn để giải toán đơn giản Ngời đọc mạnh dạn thử tìm phơng pháp đơn giảm nhng ý phải đầy đủ trờng hợp 2/ Đờng khép kín đơn:

Để thấy đợc đặc điểm riêng toán ứng với tập hợp điểm, xét tốn tìm đờng đi, qua tập hợp n điểm xác định, qua tất điểm, không giao cuối trở điểm bắt đầu Đờng nh gọi đờng khép kín đơn

Để giái tốn ta phải chọn điểm làm "điểm gốc" Sau tính góc tạo cách vẽ đờng từ điểm tập hợp đến gốc vẽ theo phơng ngang Sau đó, thứ tự điểm theo thứ tự tăng dần góc tơng ứng, cuối nối điểm cạnh lại

Gọi dx , dy khoảng cách từ điểm gốc đến điểm khác theo trục hồnh tung góc cần tính giải thuật cotan dy / dx Nhng hàm có vẽ chậm, ta thay hàm khác tơng tự nhng dễ tính hơn, dy / ( dy + dx ) Chơng trình sau trả lại giá trị từ đến 360, khơng phải góc tạo p1 p2 so với phơng ngang nhng có thuộc tính nh góc

(12)

Var dx , dy , ax , ay : integer; Begin

dx:=p2.x - p1.x; ax:= abs(dx); dy:=p2.y - p1.y; ay:= abs(dy); If (dx=0) and (dy=0) then t:=0 else t:=dy/(ax+ay);

If dx < then t:=2-t else If dy < then t:=4+t; theta := t*90;

End;

3/ Điểm nằm đa giác:

Tiếp theo, xét toán tự nhiên: cho điểm đa giác biểu diễn mảng điểm, xác định xem điểm nằm hay đa giác Một giải pháp dễ hiểu để giải toán vẽ đọan thẳng dài điểm theo hớng đếm số lợng đoạn thẳng tạo đợc cắt qua đa giác Nếu số lẽ, điểm nằm đa giác ngợc lại điều dễ thấy theo dõi xãy từ điểm nằm ngồi đa giác Tuy nhiên, khơng phải nh thế, số giao điểm trùng với đa giác, đoạn thẳng dùng để kiểm tra trùng với cạnh đa giác

Nhu cầu xử lý tình đỉnh cảu đa giác rơi đoạn thẳng kiểm tra buộc phải làm nhiều đếm số giao điểm cạnh đa giác với đoạn thẳng kiểm tra Thực chất, muốn vòng quanh đa giác, tăng biến đếm ta di từ bên đoạn thẳng kiểm tra sang bên khác Một cách để thực đơn giản bỏ qua điểm rơi đoạn thẳng kiểm tra, nh chơng trình sau đây:

Function inside (t:point):boolean; Var count,i,j:integer;

lt,lp:line; Begin

count:=0; j:=0; p[0]:=p[N]; p[N+1]:=p[1]; lt.p1:=t; lt.p2:=t; lt.p2.x:=maxint; For i:=1 to N

Begin

lp.p1 := p [i]; lp.p2 := p [i]; If not intersect (lp,lt) then Begin

lp p2 := p [j]; j := i;

If intersect (lp,lt) then count := count + 1; End;

End;

inside := ((count mod 2) = 1); End;

Chơng trình dùng đờng thẳng kiểm tra theo phơng ngang để dễ tính tốn Biến j đợc dùng để lu trữ số điểm cuối đa giác mà khơng nằm đoạn kiển tra Chơng trình giả sử p [ ] điểm có tọa độ x nhỏ số tất điểm có tọa độ y nhỏ nhất, p [ ] nằm đoạn kiểm tra p [ ] khơng thể Cùng đa giác biểu diễn N mảng khác nhau, nhng điều cho thấy áp dụng quy luật chuẩn cho p [ ] lại tiện lợi Nếu điểm kết tiếp đa giác mà không nằm đoạn kiểm tra, phía nh điểm thứ j đoạn kiểm tra khơng cần phải tăng biến đếm giao điểm ( count ) Ngợc lại, có đợc giao điểm

(13)

điểm khơng có đoạn kiểm tra có giao điểm với đa giác Trong trờng hợp này, thủ tục nh tìm nhị phân dùng để xác định O ( log N ) bớc để biết đợc điểm có bên hay khơng

III Cặp ghép:

Giíi thiệu chung:

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 cặp ghp Hai cặp ghp (x , y) (x1, y1) đợc gọi rời x # x1 y # y1 Tập M gồm cặp ghép rời đợc gọi tập cặp ghép

Thơng thờng tốn xây dựng cặp ghép đợc tiếp cận theo hớng: Hoặc thoả mãn số điều kiện ghép cặp đấy, ngời ta quan tâm đến khả ghép cặp tối đa, lợng hố việc ghép cặp, ngời ta quan tâm đến việc tối u hoá theo giá trị lợng hố

Vì số tập cặp ghép hữu hạn, nên có phơng pháp xây dựng tầm cỡ thử tất khả Tuy nhiên, số khả nh lớn (cỡ n!) Vì thế, ngời ta quan tâm đến việc tìm kiếm thuật giải hữu hiệu, dễ cài đặt chơng trình có tính khả thi cao Bài tốn nhằm giới số mụ hình ghép cặp nh

Cặp ghép đầy đủ tối u a Giới thiệu toán

Một cặp ghép, cho tất phần tử X Y đợc ghép cặp (nghĩa có đủ n cặp với n số phần tử X Y), đợc gọi ghép cặp đầy đủ

Rõ ràng song ánh p: X -> Y xác định tập ghép cặp đầy đủ, cặp ghép đợc viết dới dạng (x , p(x)), x thuộc X Từ suy có tất n! cách xây dựng tập cặp ghép đầy đủ khác

Với tập cặp ghép đầy đủ, cách tự nhiên, ngời ta quan tâm đến tập cặp ghép "tốt nhất" theo nghĩa đợc lợng hoá Tập cặp ghép đợc gọi "Tập cặp ghép đầy đủ tối -u",

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 mơ hình ngời ta quan tâm dến việc ghép cặp cho có hiệu qủa

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

Bài tốn vừa nêu thờng đợc phát biểu dới dạng mô hình thực tế tốn phân cơng dới đây:

Bài tốn phân cơng: Có n ngời n công việc Biết Cij số tiền làm giao công việc j cho ngời thứ i thực Hãy tìm cách phân cơng ngời việc để tổng số tiền làm lớn b Phơng pháp tham lam

Đây phơng pháp gần đúng, xuất phát từ việc chọn tối u bớc khơng đảm bảo đợc tính tối u tồn cục Tuy nhiên, cho phơng án, gần với ph-ơng án tối u:

Xuất phát từ Cij đóng vai trò bảng hành Tập cặp ghép đợc khởi gán rỗng Tìm dịng i cột j khỏi bảng hành lặp lại bớc thứ bảng rỗng Xố dịng i, cột j khỏi bảng hành lặp lại bớc bảng rỗng Thí dụ, xét bảng trọng số với n = 4:

(14)

cặp ghép đợc chọn lần lợt (1 7) (x3, y2), (x2, y1), (x4, y4), (x1, y3)

Với phơng án ta có tổng trọng số 25 Trờng hợp cách ghép tìm đợc cha phải cặp ghép đầy đủ tối u( xem lại ví dụ dới)

c ịnh lý sở

Vic xõy dng tập cặp ghép đầy đủ tối u dựa vào dấu hiệu nhận biết tập ghép đầy đủ tối u Dĩ nhiên việc thử dấu hiệu việc so sánh với tất cặp ghép, mà phải đợc mang tính khả thi Để lam điều ngời ta xây dựng hàm số F, xác định tập phần tử Xi thuộc X , Yj thuộc Y , mà ta gọi nhãn phần tử Nhãn F đợc gọi nhãn chấp nhận đợc thõa mãn bất đẳng thức F(Xi)+F(Yj)>=Cij với Xi thuộc X , Yj thuộc Y Tập cặp ghép M nhãn F đợc gọi tơng thích với thỗ mãn đẳng thức F(Xi) +F(Yj)=Ci với (Xi,Yj)thuộc M , Noi riêng , tập cặp ghép rỗng đợc xem nh tơng thích với nhãn

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

Dựa vào định lý vừa chứng minh , ngời ta có hớng tiếp cận cặp ghép đầy đủ tối u :

* Một , xuất phát từ cặp ghép đầy đủ M , ngời ta xây dựng nhãn F tơng thích với M Nếu F chấp nhận đợc , M tối u Trái lại , ngời ta điều chỉnh M F tơng thích chấp nhận đợc M tội u

* Hai , xuất phát từ nhãn F chấp nhận đợc cặp ghép M tơng ứng với F ( rỗng ) , ngời ta tăng dần số cặp ghép M cho đảm bảo tim đợc nhãn F tơng thích với M chấp nhận đợc Quá trình tăng kết thúc M đầy đủ M tối u

Dới trình bầy thuật tốn tim cặp ghép đầy đủ tội u theo hớng thứ hai d Thuật toán Kuhn-Munkes

Nội dung chủ yếu phơng pháp xuất phát từ tập cặp ghép cha đâỳ đủ (co thể lập hợp rỗng ) , ta tăng dần số cặp ghép cho trở thành đầy đủ , cặp ghép thu đợc đồng thời thỗ mãn tính tối u Có nhiều hình thức trình bày phơng pháp Dới cách trình bầy ngơn ngữ đồ thị với thao tác tìm kiếm Cách có nhiều u điểm : trực giác , dễ pháp biểu , dể chứng minh đặc biệt , dể cài đặt chơng trình việc tìm dờng đồ thị thao tác quen thuộc

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

- Mỗi cặp phần tử Xi thuộc X , Yj thuộc Y thoã mãn đẳng thức F(Xi)+F(Yj)=Cij xác định cạnh th ,

- Cạnh có hớng từ X sang Y cặp (Xi ,Yj) không thuộc M gọi (là cạnh thuận) ngợc lại , có xu híng tõ Y sang X nÕu cỈp (Xi ,Yj) thuộc M (gọi cạnh nghịch)

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

Bíc 1:

(15)

F( xi ) := Max {C[ i , j ] , yj thuéc Y } F( yj ) := yj thuéc Y

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

Chú ý , xuất pháp từ nhãn F chấp nhận đợc bất ký tập cặp ghép M tơng ứng với F

Bíc 2:

Tìm đỉnh tự thuộc X: Tìm đỉnh u thuộc X cha đợc ghép cặp Nếu khơng cịn đỉnh X cha ghép cặp kết thúc, tập cặp ghép M hành tập cập ghép tối u Trái lại sang bớc

Bíc 3:

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

- Nếu đến đợc đỉnh z thuộc Y cha ghép cặp ghi nhận đờng từ u -> z (gọi đờng tăng cặp ghép) chuyển sang bớc tăng cặp ghép đờng

- Nếu không tồn đờng đị nh chuyển sang bớc sửa nhón F Bc 4:

Tăng cặp ghép: §iÒu chØnh M nh sau:

- Giữ nguyên cặp ghép M nằm đờng tăng cặp ghép

- Trên đờng tăng cặp ghép, thay đổi cặp ghép M (cạnh ngợc) băng cặp ghép cạnh thuật (về mặt đồ thị nghĩa đổi chiều cạnh đờng tăng cặp ghép)

Sau bớc này, số cặp ghép thuộc M đợc tăng them đỉnh u trở thành ghép cặp, ngồi ra, tính tơng thích F M đợc bảo tồn Sau quay lại bớc để thực việc sửa nhãn tự khác

Bíc 5: Sưa nh·n:

Gọi S tập đỉnh thuộc X T tập cặp ghép thuộc Y đợc trình tìm đờng bớc Việc sửa nhãn đợc tiến hnh nh sau:

- Tìm lợng sửa nh·n:

d := Min { F(xi) + F(yj) - C[i,j] , yj thuộc T} - Gán lại nh·n:

F(xi) := F(xi) - d víi xi thuéc S F(yj) := F(yj) + d víi yj thc T

Sau đó, quay trở lại bớc để lặp lại tìm đờng tăng cặp ghép (với đỉnh xuất phát u cũ nhãn F mới)

Chú ý rằng, sau thay đổi, nhãn F giữ nguyên tính chấp nhận đợc tính tơng thích M Ngồi có thêm cặp (xi, yj) thoả mãn F(xi) + F(yj) = C[i,j], thế, sau số lần đổi sữa nhãn, chắn tăng đợc cặp ghép

Dới sơ đồ minh hoạ bớc nêu: (Sơ đồ)

Nhận xét rằng, tăng cặp ghép, đỉnh đợc tiến ghép cặp không trở thành tự do, việc tìm đỉnh tự đợc tiến hành Quá trình tìm tập cặp ghép đầy đủ tối u đợc mơ qua doạn chơng trinh sau:

(16)

IF <u cßn tù do> THEN BEGIN

WHILE NOT <Tìm thấy đờng tăng cặp ghép từ u> DO <sửa nhãn>

END; e VÝ dô

Quay trá l¹i thÝ dơ tríc Nh·n F chÊp nhËn ban đầu là: F 0 0

6 8 9 7

Xuất phát từ cặp ghép M rỗng, lần lợt tăng cặp ghép cho đỉnh tự x1, x2, x3, ta nhận đợc M={ (x1, y4), (x2, y1), (x3, y2) } đồ thị G(F,M) tơng ứng:

Việc tìm đờng tăng cặp ghép tơng đỉnh tự x4 không tìm thấy cho ta tập S = {x1, x4}, T ={y4) Tiến hành sữa nhãn tập cặp ghép này, ta đợc d=1 nhãn F F 0

5 8 9

nhãn F thêm đợc cẵp1, y2 thoả mãm F(x1) + F(x2) = C[1,2] ta đợc đồ thị G(F,M):

Đờng tăng cặp ghép x4 không tồm Tuy nhiên S T đợc mở rộng thêm: S ={x1, x3, x4} T = {y2, y4} lợng nhãn đợc sủa tập d = 1:

(17)

Lần F thêm đợc cặp x4, y1 thoả mãm F(x4) + F(y1) = C[4,1] đợc đồ thị G(F,M):

Việc tìm kiếm cha kết thúc cho S = {x1, x2, x3, x4}, T = {y1, y2, y4} Lợng nhãn đợc sửa lần 2, ta nhận đợc:

F 2 6

với đồ thị G(F,M) (thêm cạnh x2, y3):

Việc tìm kiếm đồ thị kết thúc y1 cho ta đờng tăng cặp ghép: x4 -> y1 -> x2 -> y3

đờng này, cặp ghép cũ (x2, y1) đợc thay cặp ghép (x2, y3) (x4, y1) Kết cuối cho tập cặp ghép đầy đủ tối u

Ngày đăng: 11/05/2021, 00:39

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

TÀI LIỆU LIÊN QUAN

w