Thuật toán sắp xếp MergeSort

Một phần của tài liệu Xử lý song song áp dụng đối với một số bài toán trong lý thuyết đồ thị (Trang 56 - 69)

Bài toán trộn: Cho 2 dãy a a1, 2,...,anb b1, ,...,2 bm đã được sắp xếp tăng dần, yêu cầu trộn 2 dãy thành một dãy kí hiệu là c c1, ,...,2 cn+m cũng được sắp xếp tăng dần.

Việc giải quyết bài toán trộn được thực hiện bằng thủ tục sau đây

Procedure Merge(A,B,C); Var i,j,k:integer; Begin i:=1;j:=1; For k:=1 to n+m do If A[i]<B[j] then Begin C[k]:=A[i];i:=i+1;end Else Begin C[k]:=B[j];j:=j+1;end; End;

Xuất phát từ bài toán trộn, thuật toán Mergesort được tiến hành theo hai giai đoạn như sau

Giai đoạn phân rã:

+ Phân tập cần sắp xếp thành 2 tập có lực lượng đều nhau S = S1 ÈS2, phần tử phân chia chính là phần tử có chỉ số k = n div 2.

+ Quá trình phân đôi được tiến hành theo nguyên tắc đệ quy. + Việc phân rã sẽ dừng khi tất cả các tập chỉ còn 1 phần tử. Giai đoạn hòa nhập:

+ Tiến hành trộn 2 dãy liên tiếp thành một dãy tăng dần bằng việc sử dụng thuật toán trộn Merge().

+ Việc hòa nhập các dãy sẽ dừng khi tất cả đã được hợp nhất thành 1 dãy. Toàn bộ thuật toán được mô tả bằng thủ tục đệ quy như sau:

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

Procedure Megre_sort(l,r:Integger); {l–đầu trái đoạn, r-đầu phải đoạn}

Var k:integer; Begin

If l<r then Begin

k:=(l+r) div 2;{Điểm chia đôi}

Mergesort(l,k);Mergesort(k+1,r);{Lời gọi đệ quy}

Merge(); {Trộn hai dãy}

End; End;

Cách chia đôi các phần như trong thuật toán MergeSort sẽ tạo ra cấu trúc cây nhị phân. Nếu n là luỹ thừa của 2 thì chúng ta được cây cân bằng.

Để cài đặt một cách hiệu quả trong các hệ đa bộ xử lý thì phải sử dụng lại những bộ xử lý đã thực hiện xong công việc được phân công. Trong từng bước, mỗi bộ xử lý nhận một phần của danh sách và truyền phần còn lại cho bộ xử lý khác. Giả sử dãy ban đầu gồm 8 phần tử, khi đó quá trình phân rã và hòa nhập lại được phân chia cho 8 bộ xử lý được mô tả trong hình sau đây:

Hình 3.1: Quá trình phân rã và hòa nhập trong Mergesort

P3 P0 P1 P2 P0 P6 P0 P2 P4 P0 P4 P7 P4 P5 P6 P6 P0 P2 P4 P0 P4 P0

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

Đánh giá độ phức tạp của thuật toán

Trong thuật toán Mergesort có 2logn bước thực hiện song song, trong mỗi bước có thể thực nhiều phép toán song song tuỳ thuộc vào số bộ xử lý của hệ thống. Chúng ta giả thiết rằng các danh sách con được truyền cho các bộ xử lý tương ứng bằng nhau và chúng được ghép lại để tạo ra một danh sách con được sắp xếp.

 Trước tiên chúng ta tính giá truyền thông, giả sử có p bộ xử lý. Trong giai đoạn phân chia có những thao tác truyền dữ liệu sau: Truyền dữ liệu trong từng bước Truyền thông của bộ xử lý

tstartup + (n/2)tdata P0 P4

tstartup + (n/4)tdata P0 P2; P4 P6

tstartup + (n/8)tdata P0 P1; P2 P3; P4 P5; P6 P7

2. Trong giai đoạn hòa nhập có những sự trao đổi dữ liệu:

tstartup + (n/8)tdata P0 P1; P2 P3; P4 P5; P6 P7 tstartup + (n/4)tdata P0 P2; P4 P6

tstartup + (n/2)tdata P0 P4

Cả hai giai đoạn thực hiện log p bước.

Vậy giá truyền thông của cả hai giai đoạn là:

tcomm = 2(tstartup + (n/2)tdata + tstartup + (n/4)tdata + tstartup + (n/8)tdata …) = 2(log p)tstartup + 2ntdata

 Thời gian tính toán

Các phép toán chỉ thực hiện trong giai đoạn ghép hai danh sách con để tạo ra danh sách lớn hơn. Thuật toán ghép thực hiện duyệt lần lượt từ đầu hai danh sách con để chọn phần tử nhỏ hơn đưa vào danh sách mới.Công việc này cần nhiều nhất là 2n-1 bước so sánh hai danh sách con, mỗi danh sách có n phần tử. Vậy số các phép hòa nhập thực hiện là:

tcomp =1 P0; P2; P4; P6

tcomp =3 P0; P2

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

Công thức tổng quát sẽ là:

tcomp = 1 + 3 + … + (2i – 1), i = 1, 2, …, log n.

Kết luận: Độ phức tạp thời gian tính toán của thuật toán Mergesort song song

sử dụng n bộ xử lý là O(n).

Hoàn toàn tương tự, chúng ta có thể song song hóa thuật toán tuần tự QuickSort. Độ phức tạp tính toán trong thuật toán song song cũng là O n( ).

Sau đây để sử dụng một trong các thuật toán sắp xếp dạng song song vào thiết kế các thuật toán song song trong các bài toán thuộc mô hình đồ thị, chúng ta sẽ kí hiệu thủ tục sắp xếp song song là Parall_Sort ().

3.2. Song song hóa một số thuật toán tối ƣu trên đồ thị

Trong chương 2, chúng ta đã đưa ra một số các thuật toán dạng tuần tự để giải quyết các mô hình tối ưu trong đồ thị như: Thuật toán Kruskal, thuật toán Prim tìm cây khung nhỏ nhất, thuật toán Dijkstra xác định đường đi ngắn nhất và thuật toán tô mầu đồ thị. Trong phần này, trên cơ sở các thuật toán tuần tự, chúng ta sẽ phân tích và đưa ra các giải pháp thiết kế các thuật toán song song tương ứng.

3.2.1 Song song hóa thuật toán Kruskal

Xuất phát từ thuật toán tuần tự đã được đưa ra trong chương 2, chúng ta sẽ tiến hành song song hóa thuật toán Kruskal như sau:

Phương án 1:

Thuật toán tuần tự gồm 2 bước cơ bản

Bước 1: Sắp xếp các cạnh theo giá trị trọng số tăng dần

Bước 2: Xuất phát từ cây khung bằng rỗng, ta kết nạp dần các cạnh vào cây khung sao cho cạnh sau không tạo thành chu trình với các cạnh đã kết nạp.

Để song song hóa, ta thấy ngay trong bước 1, ta có thể sử dụng một trong các thuật toán sắp xếp song song đã được đưa ra ở trên để thực hiện việc sắp xếp. Đối với bước 2, việc kết nạp các cạnh bắt buộc phải tiến hành tuần tự do sự phụ thuộc của các tiến trình. Do đó trong phương án 1, việc song song hóa thuật toán Kruskal được mô tả như sau:

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

Procedure Kruskal_Parall_1; Begin

Parall_sort(C); {Sắp xếp song song các cạnh tăng dần} T=;

While |T| <(n-1) and (E  ) Do {Kết nạp tuần tự các cạnh vào cây khung} Begin

Chọn e là cạnh có độ dài nhỏ nhất trong E;

E:=E\  e  ;

If (T ekhông chứa chu trình ) then T:=Te; End;

End.

Đánh giá độ phức tạp của thuật toán song song

Khi thực hiện sắp xếp bước 1, hiển nhiên độ phức tạp là O n( ) nếu dùng thuật toán sắp xếp song song theo hạng hoặc dùng Merge_sort. Trong giai đoạn 2 khi kết nạp các cạnh thì thuật toán sử dụng 1 vòng lạp do đó độ phức tạp vẫn là

( )

O n .

Kết luận: Độ phức tạp của thuật toán Kruskal_Parall_1 là O n( )

Phƣơng án 2

Giả sử G có n đỉnh, không mất tính tổng quát ta có thể viết V = {1, 2,..., }n

Đầu vào của thuật toán là ma trận trọng số W = (w )ij n n´ trong đó

ij

w = + ¥ nếu

không tồn tại cạnh ( , )i j .

Mô hình tính toán song song là mảng tuyến tính sao cho E = m là số cạnh của đồ thị được phân đều nhau cho các bộ xử lý. Thuật toán thực hiện log2n bước lặp.

Thuật toán song song tìm cây cực tiểu được phát biểu hình thức như sau:

/* C là vector các thành phần liên thông */ /* B là vector trung gian */

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

/* T(k)-tập các đỉnh được sinh ra trong mỗi bước lặp */

Procedure Kruskal_Parall_2 ;

Begin

forall i:=1 to n do C(i) = i; for k = 1 to log2n do Begin

Bước 1:

forall i in paralel do

T(i) = Min {w(i,j)|A(i,j) = 1 and C(j)C(i)} forall i in paralel do

T(i) = Min {T(j)|C(i) = i and T(j) i} Bước 2:

forall i in paralel do B(i) = T(i); repeat log2n times

forall i in paralel do T(i) = T(T(i)); forall i in paralel do

C(i) = Min{B(T(i)),T(i)}; End ;

Độ phức tạp của thuật toán trên là log2n. Kết quả đã được chứng minh trong tài liệu [7].

3.2.2 Song song hóa thuật toán Prim

Xét thuật toán tuần tự Prim được trình bày trong chương 2, để song song hóa chúng ta có thể thiết kế theo các phương án sau đây:

Phƣơng án 1: Xuất phát từ tư tưởng của thuật toán Prim là thuật toán lân cận

gần nhất tức là với một đỉnh bấy kỳ thì đỉnh gần nhất trong các đỉnh kề chắc chắn sẽ thuộc cây khung. Do đó ta có thể sử dụng n bộ xử lý, trong đó bộ xử lý thứ k sẽ xác

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

định đỉnh kề gần nhất của đỉnh thứ k từ đó hợp nhất các cạnh thu được, ta sẽ được cây khung cần tìm. Các bộ xử lý trên sẽ hoạt động độc lập trong quá trình tìm kiếm.

Có 2 khả năng sau đây xảy ra:

+ Kết thúc giai đoạn 1, n bộ xử lý xác định được đủ n cạnh, khi đó ta sẽ thu được cây khung nhỏ nhất. Thuật toán được mô tả bằng chương trình song song sau đây:

Procedure Prim_Parall_1 ;

Begin

: ;

T = Æ

Forall k:=1 to n do {xác định đỉnh kề gần nhất đối với đỉnh thứ k } Begin

+ Xác định đỉnh A(j) kề gần nhất với A(k) + Truyền cạnh E(k,j) về cho bộ xử lý tổng ; End ;

+ T := T ÈE k j( , );{Bộ xử lý tổng hợp nhất các cạnh thu được để xây dựng cây khung nhỏ nhất}

End ;

+ Kết thúc giai đoạn 1, n bộ xử lý xác định được không đủ n cạnh, khi đó các cạnh sẽ lập nên 1 số thành phần liên thông rời nhau, ta sẽ thu được cây khung nhỏ nhất khi tiếp tục nối các thành phần liên thông bằng các cạnh ngắn nhất giữa chúng.

Procedure Prim_Parall_2 ;

Begin

: ;

T = Æ

Forall k:=1 to n do {xác định đỉnh kề gần nhất đối với đỉnh thứ k } Begin

+ Xác định đỉnh A(j) kề gần nhất với A(k) + Truyền cạnh E(k,j) về cho bộ xử lý tổng ; End ;

+ T := T ÈE k j( , );{Bộ xử lý tổng hợp nhất các cạnh thu được để xây dựng một số thành phần liên thông}

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

+ Bổ sung các cạnh ngắn nhất để hợp nhất các thành phần liên thông để tạo thành cây khung ngắn nhất.

End ;

Đánh giá độ phức tạp thuật toán

+ Mỗi bộ xử lý đều cần đọc từ kênh truyền vào thông tin của các đỉnh kề (tối đa là n-1 đỉnh và truyền đến bộ xử lý tổng cạnh tìm được. Do đó độ phức tạp truyền thông sẽ là

comp

t = ntstaup+ ntdata

+ Mỗi bộ xử lý đều cần xác định đỉnh kề gần nhất, do đó độ phức tạp khi so sánh là O n( )

+ Trong quá trình hợp nhất được thực hiện tuần tự bằng 1 vòng lặp. Do đó độ phức tạp cũng là O n( ).

Kết luận: độ phức tạp của thuật toán Prim_Parall tương đương với O n( ).

Phƣơng án 2:

Khi thực hiện tính toán gán nhãn trong thuật toán tuần tự, ta có thể sử dụng n

bộ xử lý trong đó bộ xử lý thứ k sẽ xác định nhãn của đỉnh thứ k sau đó các thông tin thu được lại truyền về bộ xử lý tổng để xác định cạnh có nhãn nhỏ nhất để kết nạp. Mỗi lần số lượng bộ xử lý được giảm đi 1. Quá trình xử lý được thực hiện đúng n-1 lần. Thuật toán có thể mô tả như sau:

Procedure Prim_Parall_3 ; Begin { }1 : ; T = ÆA = u For i:=1 to n do Begin

Forall k:=1 to n-i do {xác định nhãn đối với đỉnh thứ k } Begin

+ Xác định lại nhãn của đỉnh A(k)

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

End ;

+ T := T ÈE k j( , );{Gán cạnh có nhãn nhỏ nhất vào cây khung} + A = A È{u*}{Bổ sung đỉnh mới kết nạp vào tập đỉnh}

End ;

Độ phức tạp của thuật toán được đánh giá tương đương với O n( log )n

3.2.3. Song song hóa thuật toán Floyd

Phƣơng án 1: Xuất phát từ thuật toán tuần tự, ta có thể sử dụng n bộ xử lý để cùng đồng thời thực hiện thuật toán Floyd một cách song song như sau:

Procedure Floyd_Parall_1; Var i, j, k: integer;

Begin

Forall i:=1 to n do {Tiến hành thực hiện song song gán nhãn cho các đỉnh} For j:=1 to n do Begin A[i,j]:= C[i,j]; P[i,j]:= 0; End; For k:= 1 to n do Forall i:=1 to n do For j:=1 to n do

If A[i,k] + A[k,j] < A[i,j] then Begin

A[i,j]:= A[i,k] + A[k,j]; P[i,j]:= k;

End; End;

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

Đánh giá độ phức tạp: Hiển nhiên trong trường hợp sử dụng n bộ nhớ thì ta cần sử dụng 2 vòng lặp lồng nhau để thực hiện toàn bộ thuật toán. Do đó độ phức tạp của thuật toán là 2

( )

O n .

Phƣơng án 2: Ta cũng có thể sử dụng 2

n bộ xử lý để cùng đồng thời thực hiện thuật toán Floyd một cách song song. Thuật toán được mô tả như sau:

Procedure Floyd_Parall_2; Var i, j, k: integer;

Begin

Forall i:=1 to n do {Tiến hành thực hiện song song gán nhãn cho các đỉnh} Forall j:=1 to n do Begin A[i,j]:= C[i,j]; P[i,j]:= 0; End; For k:= 1 to n do Forall i:=1 to n do Forall j:=1 to n do

If A[i,k] + A[k,j] < A[i,j] then Begin

A[i,j]:= A[i,k] + A[k,j]; P[i,j]:= k;

End; End;

Cần chú ý rằng mỗi một lần lặp, ta cần cập nhật lại thông tin cho tất cả các bộ xử lý về giá trị mới của mảng A. Do đó trong trường hợp này giá trả cho truyền thông của thuật toán là lớn và đồng thời số lượng sử dụng bộ xử lý cũng rất nhiều.

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

3.2.4 Song song hóa thuật toán tô màu đồ thị

Ngoài thuật toán Welch – Powell tuần tự đã đưa ra trong chương 2, để giải quyết nhanh bài toán tô màu, ta có thể tạo ra một tiến trình cho từng cách tô màu và sau đó các tiến trình phải kiểm tra xem cách tô đó có hợp lệ hay không.

Giả sử V = n , hay mô tảV = {v v0, ,...,1 vn-1} và ma trận liền kề A của đồ thị G có cấp n ´ n . Ta sẽ sử dụng n tiến trình trong đó tiến trình P i( )k sẽ thực hiện tô mầu với số hiệu ik cho đỉnh v kk( = 0,1,...,n - 1), với 1£ ik £ c. Như vậy ta có c´ n tiến trình để thực hiện việc tô mầu cho n đỉnh.

Bắt đầu tất cả các tiến trình gán giá trị 1 vào bảng đại diện có c´ n phần tử. Mỗi tiến trình sẽ phải thực hiện nhiều nhất là n´ (n - 1) phép so sánh màu của hai đỉnh kề nhau để kiểm tra xem chúng có cùng màu hay không. Nếu A j k[ , ]= 1 và

j k

i = i thì cách tô màu đó không hợp lệ vì hai đỉnh v vj, k liền kề nhau mà lại bị tô cùng màu. Nếu phát hiện ra cách tô màu không hợp lệ thì đặt bảng đại diện về 0. Sau khi thực hiện xong tất cả các phép đối chiếu mà bảng đại diện vẫn giữ nguyên giá trị 1 thì cách tô màu đó là hợp lệ.

Thuật toán tô màu đồ thị song song trên PRAM được xây dựng như sau:

Procedure Tomau_Pram ; Begin spawn( 0 1 1 ( , ,..., n ) P i i i - ), 0 ik c, 0 k c forall ( 0 1 1 ( , ,..., n ) P i i i - ) do Begin candidate[ 0, ,...,1 n 1 i i i - ] = 1; for (j = 0; j < n; j++) for (k = 0; k < n; k++) if (A[j][k] ==1 &&ij = = ik) candidate[i i0, ,...,1 in-1] = 0;

Số hóa bởi Trung tâm Học liệu – Đại học Thái Nguyên http://www.lrc-tnu.edu.vn

valid = sum(candidate); /* Tính tổng */ if (valid > 0)

printf(“Valid coloring exists!\n”); else

printf(“Valid coloring does notexist!\n”); end

end

Ví dụ: cho trước đồ thị có 3 đỉnh và 2 màu đơn giản

Cách tô màu Giá trị bắt đầu Sau khi kiểm tra

Hình 3.2 Thuật toán tô màu đồ thị song song trên PRAM

Đánh giá độ phức tạp của thuật toán:

Hiển nhiên để tạo ra c´ n , ta cần log(c´ n ) đơn vị thời gian. Mỗi tiến trình

Một phần của tài liệu Xử lý song song áp dụng đối với một số bài toán trong lý thuyết đồ thị (Trang 56 - 69)

Tải bản đầy đủ (PDF)

(69 trang)