Tải bản đầy đủ (.docx) (27 trang)

Nghiên cứu và đánh giá hiệu năng cao thuật toán nổi tiếng đồ thị sử dụng MPI

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (598.45 KB, 27 trang )

TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
---------

-------------------------------------------

Báo cáo bài tập lớn mơn học: Tính tốn hiệu năng cao - HPC
CHỦ ĐỀ:
Nghiên cứu và đánh giá hiệu năng cao thuật toán nổi tiếng
đồ thị sử dụng MPI
GVHD: TS. Đào Mạnh Hà
Nhóm: 18
Nguyễn Trung Kiên

Mã SV: 2021606975

Nguyễn Mạnh Hùng

Mã SV: 2021608268

Nguyễn Phương Nam

Mã SV: 2021606316


Hà Nội, 2023
MỤC LỤC
MỤC LỤC
LỜI NÓI ĐẦU
CHƯƠNG 1: XÁC ĐỊNH VÀ PHÂN TÍCH BÀI TỐN
1.2. MPI trong tính tốn hiệu năng cao


1.2.1. Định nghĩa
1.2.2. Mơ hình lập trình MPI
1.2.3. Cấu trúc chương trình MPI
1.2.4. Hạn chế
1.3. Visual studio 2022
1.3.1. Định nghĩa
1.3.2. Tính năng
1.3.2.1. Biên tập mã
1.3.2.2. Trình gỡ lỗi
CHƯƠNG 2: THIẾT KẾ THUẬT TỐN
2.1. Thuật tốn đồ thị mpi
2.2. Source code thuật toán đồ thị MPI
CHƯƠNG 3: SO SÁNH VÀ ĐÁNH GIÁ KẾT QUẢ ĐẠT ĐƯỢC

3.1. Giới thiệu
3.2. Mơ hình thực nghiệm
3.3. So sánh và đánh giá kết quả chương trình thử nghiệm
3.4. Kết quả và so sánh
3.5. Ứng Dụng Thực Tế và Hướng Phát Triển
3.5.1: Ứng dụng thực tế
3.5.2: Hướng phát triển
CHƯƠNG 4. KẾT LUẬN

1


LỜI NĨI ĐẦU
Trong thời đại số hóa ngày nay, xử lý và phân tích dữ liệu đồ thị là một
phần quan trọng của nhiều ứng dụng thực tế, từ mạng xã hội đến hệ thống giao
thơng và tối ưu hóa các quy trình kinh doanh. Đồng thời, lập trình song song là

một yếu tố quyết định để tận dụng hiệu suất của các hệ thống tính tốn hiện đại.
Trong ngữ cảnh này, chúng ta không thể phớt lờ qua vai trò của Message
Passing Interface (MPI) - một giao thức truyền thơng cho lập trình song song.
Tiểu luận này đặt ra một câu hỏi cơ bản nhưng quan trọng: "Làm thế nào chúng
ta có thể tối ưu hóa hiệu suất của các thuật tốn đồ thị thơng qua việc sử dụng
MPI?" Chúng ta sẽ khám phá sự kết hợp mạnh mẽ giữa lập trình đồ thị và MPI
Mục tiêu của chúng ta khơng chỉ là hiểu rõ cách các thuật tốn đồ thị hoạt
động, mà còn là xem xét cách chúng có thể được triển khai trên mơi trường
song song sử dụng MPI để tối ưu hóa thời gian xử lý và tận dụng tài ngun
tính tốn. Qua q trình nghiên cứu này, chúng ta có thể khơng chỉ có cái nhìn
sâu sắc về hiệu suất của các thuật tốn đồ thị mà còn thấy rõ ứng dụng thực tế
của chúng trong một thế giới đang ngày càng phụ thuộc vào dữ liệu và tính tốn
song song. Hãy bắt đầu hành trình khám phá này và đặt ra câu hỏi: "Làm thế
nào chúng ta có thể tối ưu hóa sức mạnh của đồ thị và MPI để giải quyết những
thách thức ngày nay và tương lai?".
Trong quá trình thực hiện đề tài, được sự giúp đỡ của “TS. Đào Mạnh
Hà” nhiệt tình hướng dẫn. Tuy nhiên vì kiến thức cịn chưa vững nên trong q
trình tìm hiểu và đánh giá có thể cịn những thiếu sót và hạn chế, mong được
thầy xem và cho đưa ra nhận xét giúp chúng em hiểu và tiếp thu những kiến
thức mới. Cũng như hoàn thành bài tập lớn này một cách hoàn thiện hơn
Chúng em xin trân trọng cảm ơn!
Sinh viên nhóm 18 thực hiện

2


CHƯƠNG 1: XÁC ĐỊNH VÀ PHÂN TÍCH BÀI TỐN
1.1. Thuật toán đồ thị sử dụng MPI
1.1.1. Định nghĩa
Thuật toán đồ thị sử dụng MPI thường được thiết kế để giải quyết các

vấn đề liên quan đến đồ thị trên các cụm máy tính song song sử dụng
thư viện MPI (Message Passing Interface).
1.1.2. Phân loại
Dưới đây là một số thuật toán đồ thị phổ biến được triển khai với MPI:
● Thuật toán Duyệt Đồ thị(Graph Traversal):
Duyệt đồ thị là một vấn đề quan trọng trong nhiều ứng dụng, như
tìm đường đi ngắn nhất, kiểm tra liên thơng, hay tìm các thành
phần liên thơng. Thuật tốn sử dụng MPI để phân chia đồ thị và
thực hiện các công việc duyệt trên từng nút.
● Thuật tốn tìm đường đi ngắn nhất (Shortest Path):
Dùng để tìm đường đi ngắn nhất giữa hai đỉnh trong đồ thị. Thuật
tốn như Bellman-Ford hay Dijkstra có thể được song song hóa sử
dụng MPI để tối ưu hiệu suất tính tốn trên cụm máy tính.
● Thuật tốn liên kết cây (Spanning Tree):
Xây dựng một cây liên kết của đồ thị, bao gồm tất cả các đỉnh và
một số cạnh mà khơng có chu trình. Thuật tốn Prim và Kruskal là
những ví dụ có thể được song song hóa bằng MPI.
● Thuật toán Sắp xếp Đồ thị (Graph Sorting):
Sắp xếp các đỉnh của đồ thị theo một tiêu chí nào đó. Thuật tốn
này có thể được thực hiện song song trên cụm máy tính sử dụng
MPI để tăng tốc quá trình sắp xếp.
● Thuật tốn Luồng Mạng Tối Đa (Maximum Flow):
Tìm luồng mạng tối đa trong đồ thị có trọng số. Các thuật tốn như
Ford-Fulkerson có thể được song song hóa để tận dụng khả năng
tính tốn song song của MPI.
● Thuật tốn Phân Cụm Cộng Đồng (Community Detection):
Tìm các cụm cộng đồng trong đồ thị. Thuật toán Girvan-Newman,
3



Louvain, hay Label Propagation có thể được song song hóa sử
dụng MPI để tăng hiệu suất tính tốn.
Khi triển khai các thuật tốn này sử dụng MPI, việc chia cơng việc, quản
lý giao tiếp, và tối ưu hóa hiệu suất trở thành những yếu tố quan trọng để
đạt được khả năng mở rộng và hiệu suất cao trên các cụm máy tính song
song.
1.2. MPI trong tính tốn hiệu năng cao
1.2.1. Định nghĩa
MPI (Message Passing Interface) là một giao diện lập trình ứng dụng
(API) đã phát triển từ lâu, nhằm hỗ trợ việc xây dựng ứng dụng có tính chất
song song, sử dụng nhiều tiến trình. Giao diện này cung cấp một bộ các hàm và
quy ước để quản lý truyền thơng giữa các tiến trình khác nhau trong mơi trường
song song.
MPI cung cấp các chức năng chính như khởi tạo mơi trường MPI, phân
chia chương trình thành nhiều tiến trình chạy đồng thời, truyền dữ liệu giữa
chúng, và đồng bộ hóa các hoạt động của chúng. Mơ hình thường sử dụng là
một tiến trình chính (master) tại máy ngun thủy, có trách nhiệm khởi tạo
chương trình, phân cơng nhiệm vụ, và nhận kết quả từ các tiến trình phụ (slave).
Các tiến trình phụ chạy độc lập trên máy (hoặc CPU) phụ, nhận dữ liệu ban đầu,
thực hiện tính tốn và gửi kết quả về tiến trình chính.
MPI là một cơ sở mạnh mẽ để phát triển ứng dụng song song trên các hệ
thống có nhiều xử lý, bao gồm các lệnh để quản lý q trình truyền thơng và
đồng bộ hóa giữa các tiến trình.
1.2.2. Mơ hình lập trình MPI
- Ban đầu MPI được thiết kế cho các kiến trúc bộ nhớ phân tán, kiến trúc rất
phổ biến thời kỳ 1980 đến đầu năm 1990.

4



Hình 1.3: Mơ hình MPI giai đoạn 1980 - 1990
- Xu hướng công nghệ thay đổi, bộ nhớ chia sẻ kết hợp với mạng máy tính tạo
ra dạng lai của hai hệ thống bộ nhớ chia sẻ và bộ nhớ phân tán.
- Thực thi MPI tương thích với cả hai kiểu kiến trúc trên và cũng tương thích
với các kiểu kết nối và giao thức khác nhau.

Hình 1.4: Mơ hình MPI ngày nay
- Ngày nay MPI có thể chạy trên hầu hết các nền tảng phần cứng:
● Bộ nhớ chia sẻ
● Bộ nhớ phân tán
● Dạng lai 2 loại trên

5


1.2.3. Cấu trúc chương trình MPI

Hình 1.5: Cấu trúc chương trình MPI
1.2.4. Hạn chế
Tuy có khả năng cung cấp hiệu năng cao và có thể chạy trên cả các kiến
trúc sử dụng bộ nhớ chia sẻ lẫn phân tán, nhưng các chương trình MPI địi hỏi
người lập trình phải tự phân chia chương trình thành các khối cho tiến trình
chính và phụ bằng các câu lệnh 2 tường minh. Các công việc khác như gửi và
nhận dữ liệu, đồng bộ hóa tiến trình… cũng cần được chỉ rõ bằng các câu lệnh
và tham số cụ thể. Điều này gây khó khăn và địi hỏi nhiều cơng sức đối với
người lập trình, thể hiện qua ba khía cạnh lớn. Thứ nhất là MPI đòi hỏi phải tổ
chức ngay từ đầu chương trình thành theo cấu trúc song song trên mơ hình
master-slave, một việc phức tạp hơn nhiều so với việc tổ chức chương trình
tuần tự vốn quen thuộc với tư duy của đa số lập trình viên.
Thứ hai là nếu MPI được sử dụng để song song hố các chương trình tuần

tự thì vì nó phá vỡ nghiêm trọng cấu trúc ban đầu của chương trình. Điều khó
khăn thứ ba gây nên bởi sự rắc rối của các câu lệnh MPI, với một loạt các tham
số khá khó hiểu cho mỗi câu lệnh. Do ba khó khăn vừa nêu, tuy có hiệu năng
6


cao và đã cung cấp một cách thức lập trình trừu tượng hóa nhưng MPI vẫn được
xem là assembler của việc lập trình song song.
1.3. Visual studio 2022
1.3.1. Định nghĩa
- Microsoft Visual Studio là một mơi trường phát triển tích hợp (IDE) từ
Microsoft. Microsoft Visual Studio còn được gọi là "Trình soạn thảo mã nhiều
người sử dụng nhất thế giới ", được dùng để lập trình C++ và C# là chính. Nó
được sử dụng để phát triển chương trình máy tính cho Microsoft Windows,
cũng như các trang web, các ứng dụng web và các dịch vụ web. Visual Studio
sử dụng nền tảng phát triển phần mềm của Microsoft như Windows API,
Windows Forms, Windows Presentation Foundation, Windows Store và
Microsoft Silverlight. Nó có thể sản xuất cả hai ngơn ngữ máy và mã số quản
lý.
- Visual Studio bao gồm một trình soạn thảo mã hỗ trợ IntelliSense cũng
như cải tiến mã nguồn. Trình gỡ lỗi tích hợp hoạt động cả về trình gỡ lỗi mức
độ mã nguồn và gỡ lỗi mức độ máy. Cơng cụ tích hợp khác bao gồm một mẫu
thiết kế các hình thức xây dựng giao diện ứng dụng, thiết kế web, thiết kế lớp
và thiết kế giản đồ cơ sở dữ liệu. Nó chấp nhận các plug-in nâng cao các chức
năng ở hầu hết các cấp bao gồm thêm hỗ trợ cho các hệ thống quản lý phiên
bản (như Subversion) và bổ sung thêm bộ công cụ mới như biên tập và thiết kế
trực quan cho các miền ngôn ngữ cụ thể hoặc bộ công cụ dành cho các khía
cạnh khác trong quy trình phát triển phần mềm.
- Visual Studio hỗ trợ nhiều ngơn ngữ lập trình khác nhau và cho phép trình
biên tập mã và gỡ lỗi để hỗ trợ (mức độ khác nhau) hầu như mọi ngơn ngữ lập

trình. Các ngơn ngữ tích hợp gồm có C,[4] C++ và C++/CLI (thông qua Visual
C++), VB.NET (thông qua Visual Basic.NET), C# (thông qua Visual C#) và
F# (như của Visual Studio 2010[5]). Hỗ trợ cho các ngôn ngữ khác như J+
+/J#, Python và Ruby thông qua dịch vụ cài đặt riêng rẽ. Nó cũng hỗ trợ XML/
XSLT, HTML/XHTML, JavaScript và CSS.

7


1.3.2. Tính năng
1.3.2.1.

Biên tập mã

- Giống như bất kỳ IDE khác, nó bao gồm một trình soạn thảo mã hỗ trợ tơ
sáng cú pháp và hồn thiện mã bằng cách sử dụng IntelliSense không chỉ cho
các biến, hàm và các phương pháp mà cịn các cấu trúc ngơn ngữ như vòng
điều khiển hoặc truy vấn. IntelliSense được hỗ trợ kèm theo cho các ngôn ngữ
như XML, Cascading Style Sheets và JavaScript khi phát triển các trang web
và các ứng dụng web. Các đề xuất tự động hoàn chỉnh được xuất hiện trong
một hộp danh sách phủ lên trên đỉnh của trình biên tập mã. Trong Visual
Studio 2008 trở đi, nó có thể được tạm thời bán trong suốt để xem mã che
khuất bởi nó. Các trình biên tập mã được sử dụng cho tất cả các ngôn ngữ
được hỗ trợ.
- Các trình biên tập mã Visual Studio cũng hỗ trợ cài đặt dấu trang trong mã
để điều hướng nhanh chóng. Hỗ trợ điều hướng khác bao gồm thu hẹp các khối
mã lệnh và tìm kiếm gia tăng, ngồi việc tìm kiếm văn bản thơng thường và
tìm kiếm Biểu thức chính quy. Các trình biên tập mã cũng bao gồm một bìa
kẹp đa mục và một danh sách cơng việc. Các trình biên tập mã hỗ trợ lưu lại
các đoạn mã được lặp đi lặp lại nhằm để chèn vào mã nguồn sử dụng về sau.

Một công cụ quản lý cho đoạn mã được xây dựng là tốt. Những công cụ này
nổi lên như các cửa sổ trơi nổi có thể được thiết lập để tự động ẩn khi không sử
dụng hoặc neo đậu đến các cạnh của màn hình. Các trình biên tập mã Visual
Studio cũng hỗ trợ cải tiến mã nguồn bao gồm tham số sắp xếp lại, biến và
phương pháp đổi tên, khai thác và đóng gói giao diện các lớp thành viên bên
trong những trạng thái giữa những thứ khác.
- Visual Studio có tính năng biên dịch nền (còn gọi là biên dịch gia tăng).
Như mã đang được viết, Visual Studio biên dịch nó trong nền để cung cấp
thông tin phản hồi về cú pháp và biên dịch lỗi, được đánh dấu bằng một gạch
dưới gợn sóng màu đỏ. Biên dịch nền không tạo ra mã thực thi, vì nó địi hỏi
một trình biên dịch khác hơn là để sử dụng tạo ra mã thực thi. Biên dịch nền
8


ban đầu được giới thiệu với Microsoft Visual Basic nhưng bây giờ đã được mở
rộng cho tất cả các ngôn ngữ.
1.3.2.2.

Trình gỡ lỗi

- Visual Studio có một trình gỡ lỗi hoạt động vừa là một trình gỡ lỗi cấp mã
nguồn và là một trình gỡ lỗi cấp máy. Nó hoạt động với cả hai mã quản lý
cũng như ngôn ngữ máy và có thể được sử dụng để gỡ lỗi các ứng dụng được
viết bằng các ngôn ngữ được hỗ trợ bởi Visual Studio. Ngồi ra, nó cũng có
thể đính kèm theo quy trình hoạt động và theo dõi và gỡ lỗi những quy trình.
Nếu mã nguồn cho quá trình hoạt động có sẵn, nó sẽ hiển thị các mã như nó
đang được chạy. Nếu mã nguồn khơng có sẵn, nó có thể hiển thị các tháo gỡ.
Các Visual Studio debugger cũng có thể tạo bãi bộ nhớ cũng như tải chúng sau
để gỡ lỗi. Các chương trình đa luồng cao cấp cũng được hỗ trợ. Trình gỡ lỗi có
thể được cấu hình sẽ được đưa ra khi một ứng dụng đang chạy ngồi Visual

Studio bị treo mơi trường.
- Trình gỡ lỗi cho phép thiết lập các breakpoint (mà cho phép thực thi được
tạm thời dừng lại tại một vị trí nhất định) và watch (trong đó giám sát các giá
trị của biến là việc thực hiện tiến bộ). Breakpoint có thể có điều kiện, nghĩa là
chúng được kích hoạt khi điều kiện được đáp ứng. Mã có thể được biểu diễn,
tức là chạy một dòng (của mã nguồn) tại một thời điểm. Nó có hoặc là bước
sang các chức năng để gỡ lỗi bên trong nó, hoặc là nhảy qua nó, tức là, việc
thực hiện các chức năng khơng có sẵn để kiểm tra thủ cơng. Trình gỡ lỗi hỗ trợ
Edit and Continue, nghĩa là, nó cho phép mã được chỉnh sửa khi nó đang được
sửa lỗi (chỉ có 32 bit, không được hỗ trợ trong 64 bit). Khi gỡ lỗi, nếu con trỏ
chuột di chuyển lên bất kỳ biến, giá trị hiện tại của nó được hiển thị trong phần
chú giải ("chú thích dữ liệu"), nơi mà nó cũng có thể được thay đổi nếu muốn.
Trong q trình viết mã, các trình gỡ lỗi của Visual Studio cho phép một số
chức năng được gọi ra bằng tay từ cửa sổ công cụ Immediate. Các thông số
cho phương thức được cung cấp tại các cửa sổ Immediate.

9


CHƯƠNG 2: THIẾT KẾ THUẬT TỐN

2.1.

Thuật tốn đồ thị mpi

Dưới đây là một bản dịch tiếng Việt của thuật toán Dijkstra để tìm đường đi
ngắn nhất trong đồ thị có trọng số, sử dụng MPI (Giao diện Truyền thông Tin
nhắn) trong mơi trường tính tốn song song:
1. Khởi tạo đồ thị:
- Mỗi tiến trình khởi tạo một phần đồ thị cục bộ của mình.

- Đồ thị có thể được biểu diễn dưới dạng ma trận kề hoặc danh sách kề.
2. Gán đỉnh nguồn:
- Một tiến trình (thường là tiến trình gốc) gán đỉnh nguồn cho chính nó.
3. Phát sóng đỉnh nguồn:
- Tiến trình gốc phát sóng đỉnh nguồn đến tất cả các tiến trình khác.
4. Thực hiện tính tốn đường đi ngắn nhất:
- Mỗi tiến trình tính tốn đường đi ngắn nhất cho phần đồ thị cục bộ của mình
bằng thuật tốn Dijkstra.
- Trong mỗi vịng lặp, tiến trình chọn đỉnh có khoảng cách ngắn nhất chưa
được thăm.
- Tiến trình cập nhật khoảng cách của các đỉnh kề nếu tìm thấy một đường đi

10


ngắn hơn.
5. Trao đổi thơng tin:
- Sau mỗi vịng lặp, các tiến trình cần trao đổi thơng tin về khoảng cách để
đảm bảo tính tốn đường đi ngắn nhất tồn cục được thực hiện chính xác.
- Điều này có thể được thực hiện bằng cách sử dụng các hàm truyền thông
MPI như `MPI_Send`, `MPI_Recv`, hoặc các hoạt động tập trung như
`MPI_Allreduce` hoặc `MPI_Allgather`.
6. Hồn thiện tính tốn:
- Khi tính tốn đường đi ngắn nhất hồn tất, mỗi tiến trình sẽ có phần đường
đi ngắn nhất cục bộ của nó.
7. Tổng hợp kết quả:
- Tiến trình gốc tổng hợp các khoảng cách đường đi ngắn nhất từ tất cả các
tiến trình khác.
- Điều này có thể được thực hiện bằng cách sử dụng hoạt động truyền thông
tập trung MPI `MPI_Gather` hoặc `MPI_Gatherv`.

Cần lưu ý rằng việc triển khai các thuật toán đồ thị song song bằng MPI đòi hỏi
xem xét cẩn thận về phân phối dữ liệu, cân bằng tải, chi phí truyền thơng và
đồng bộ hóa. Các chi tiết triển khai cụ thể, chẳng hạn như cách phân phối đồ thị
giữa các tiến trình, cách trao đổi thơng điệp và cách đồng bộ dữ liệu, sẽ phụ
thuộc vào thư viện MPI cụ thể và mơ hình lập trình bạn đang sử dụng.

2.2.

Source code thuật toán đồ thị MPI

#include <iostream>
#include <limits.h>
#include <mpi.h>
#include <random>
#include <ctime>
#define INF INT_MAX // Infinite distance
using namespace std;
// Function to find the node with the minimum distance value
int minDistance(int dist[], bool visited[], int n) {

11


int min = INF, min_index;
for (int v = 0; v < n; v++) {
if (!visited[v] && dist[v] <= min) {
min = dist[v];
min_index = v;
}
}

return min_index;
}
// Function to print the shortest path from source to destination
void printPath(int parent[], int j) {
if (parent[j] == -1)
return;
printPath(parent, parent[j]);
cout << j << " ";
}
// Function to perform Dijkstra's algorithm
void dijkstra(int** graph, int src, int n, int rank, int size) {
int* dist = new int[n]; // Array to store the shortest distances
bool* visited = new bool[n]; // Array to track visited nodes
int* parent = new int[n]; // Array to store the shortest path
// Initialize all distances as infinite and visited as false
for (int i = 0; i < n; i++) {
dist[i] = INF;
visited[i] = false;
}
dist[src] = 0; // Distance of source node from itself is always 0
parent[src] = -1; // Source node has no parent
// Find the shortest path for all nodes
for (int count = 0; count < n - 1; count++) {
int u = minDistance(dist, visited, n);
// Mark the selected node as visited
visited[u] = true;
// Update the distance values of the adjacent nodes
for (int v = 0; v < n; v++) {
if (!visited[v] && graph[u][v] && dist[u] != INF &&
dist[u] + graph[u][v] < dist[v]) {

dist[v] = dist[u] + graph[u][v];
parent[v] = u;
}

12


}
}
// Print the shortest paths from the source node
if (rank == 0) {
cout << "Shortest paths from source node " << src << ":" << endl;
for (int i = 0; i < n; i++) {
if (i != src) {
cout << "Path to node " << i << ": ";
printPath(parent, i);
cout << src << " with a distance of " << dist[i] << endl;
}
}
}
delete[] dist;
delete[] visited;
delete[] parent;
}
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int n; // Number of nodes in the graph

if (rank == 0) {
cout << "Enter the number of nodes in the graph: ";
cin >> n;
}
// Broadcast the number of nodes to all processes
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Define the graph as an adjacency matrix
int** graph = new int* [n];
for (int i = 0; i < n; i++) {
graph[i] = new int[n];
}
// Randomly generate the graph data
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist(1, 10); // Range of weights for the edges
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {

13


if (i == j) {
graph[i][j] = 0; // No self-loops
}
else if (i < j) {
graph[i][j] = dist(gen); // Generate a random weight for the edge
}
else {
// Use symmetry to fill in the lower triangular part of the matrix
graph[i][j] = graph[j][i];

}
}
}
int source = 0; // Source node for the shortest path computation
// Measure the execution time
double start_time = MPI_Wtime();
// Perform Dijkstra's algorithm
dijkstra(graph, source, n, rank, size);
// Calculate and print the execution time
double end_time = MPI_Wtime();
double execution_time = double(end_time - start_time) / CLOCKS_PER_SEC;
cout << "Execution time: " << execution_time << " seconds" << endl;
// Clean up memory
for (int i = 0; i < n; i++) {
delete[] graph[i];
}
delete[] graph;
return 0;
}

Kết quả chạy chương trình:
Số node n =10

14


Số node n =100

Số node n =1000


15


Số node n =1500

16


CHƯƠNG 3: SO SÁNH VÀ ĐÁNH GIÁ KẾT QUẢ ĐẠT
ĐƯỢC

17


3.1. Giới thiệu
Ngồi các thuật tốn trong DijKstra được tìm hiểu ở trên thì chương này,
chúng ta sẽ thực hiện so sánh và đánh giá hiệu năng cao của các thuật toán nổi
tiếng đồ thị sử dụng MPI khác. Các thuật toán được lựa chọn tham khảo bao
gồm:
1. Breadth-first search (BFS): Tìm kiếm theo chiều rộng
2. Depth-first search (DFS): Tìm kiếm theo chiều sâu
3. Shortest path algorithm (SPA): Tìm đường đi ngắn nhất
Các thuật tốn này đều có ý nghĩa quan trọng trong nhiều ứng dụng thực tế,
chẳng hạn như:
● BFS được sử dụng để tìm kiếm các nút trong một đồ thị, chẳng hạn như
trong các ứng dụng tìm kiếm dữ liệu.

Hình 3.1: Mơ tả q trình duyệt đồ thị ưu tiên chiều rộng
● DFS được sử dụng để tìm kiếm các nút trong một đồ thị theo chiều sâu,
chẳng hạn như trong các ứng dụng duyệt web.


18


Hình 3.2: Mơ tả q trình duyệt đồ thị ưu tiên chiều sâu
● SPA được sử dụng để tìm đường đi ngắn nhất giữa hai nút trong một đồ
thị, chẳng hạn như trong các ứng dụng định tuyến.

3.2. Mơ hình thực nghiệm
Code C++ chúng tôi đã cung cấp là một chương trình thực hiện thuật tốn

19



×