Thuật toán Dijkstra được sử dụng đểtìm đường đi ngắn nhất giữa hai đỉnh trong đồ thị có trọng số không âm.. Dưới đâylà một số khái niệm liên quan đến thuật toán Dijkstra: - Đồ Thị Graph:
Trang 1BỘ GIÁO DỤC VÀ ĐÀO TẠO ĐẠI HỌC KINH TẾ TP HỒ CHÍ MINH (UEH)
TRƯỜNG CÔNG NGHỆ VÀ THIẾT KẾ
✍
ĐỒ ÁN MÔN HỌC
ĐỀ TÀI
TÌM ĐƯỜNG ĐI NGẮN NHẤT BẰNG THUẬT TOÁN DIJKSTRAHọc Phần: Cấu Trúc Dữ Liệu & Giải Thuật Danh Sách Nhóm 7:
1 Trần Huy Hoàng2 Mạch Gia Huy3 Huỳnh Bảo Nguyên4 Lê Vũ Long5 Trầm Phúc Tài
Chuyên Ngành:KỸ THUẬT PHẦN MỀM
Khóa:K48
Giảng Viên: TS Đặng Ngọc Hoàng Thành
Tp Hồ Chí Minh, Ngày 06 tháng 12 năm 2023
Trang 2MỤC LỤC
MỤC LỤC 2
CHƯƠNG 1 THUẬT TOÁN DIJKSTRA 3
1.1 Các Khái Niệm Liên Quan 3
1.2 Cấu Trúc và Cài Đặt Thuật Toán 3
1.3 Thuật Toán Dijkstra 5
CHƯƠNG 2 PHÂN TÍCH VÀ THIẾT KẾ LỚP 8
2.1 Phân Tích Bài Toán Tìm Kiếm Đường Đi Ngắn Nhất Dijkstra 8
2.2 Sơ Đồ Lớp 12
2.3 Cài Đặt Lớp 12
CHƯƠNG 3 THIẾT KẾ GIAO DIỆN 19
3.1 Giao Diện Menu Chính 19
3.2 Chi Tiết Chức Năng 20
CHƯƠNG 4 THẢO LUẬN & ĐÁNH GIÁ 21
Trang 3CHƯƠNG 1 THUẬT TOÁN DIJKSTRA
1.1 Các Khái Niệm Liên Quan
Thuật toán Dijkstra là một thuật toán trong lĩnh vực đồ thị, được phát triển bởi nhàtoán học Edsger W Dijkstra vào năm 1956 Thuật toán Dijkstra được sử dụng đểtìm đường đi ngắn nhất giữa hai đỉnh trong đồ thị có trọng số không âm Dưới đâylà một số khái niệm liên quan đến thuật toán Dijkstra:
- Đồ Thị (Graph): Đồ thị là một tập hợp các đỉnh và các cạnh nối giữa chúng.Trong trường hợp thuật toán Dijkstra, thông thường sử dụng đồ thị có trọngsố không âm
- Đỉnh (Vertex): Là các điểm trong đồ thị Trong ngữ cảnh của thuật toánDijkstra, một đỉnh có thể là một thành phố, một điểm giao thông, hoặc bất kỳđiểm nào khác mà bạn muốn xác định đường đi ngắn nhất đến
- Cạnh (Edge): Là các liên kết giữa các đỉnh trong đồ thị Mỗi cạnh có mộttrọng số, thể hiện chi phí hoặc khoảng cách giữa các đỉnh liên kết
- Trọng Số (Weight): Là giá trị gán cho mỗi cạnh, thường thể hiện khoảngcách hoặc chi phí đi từ một đỉnh đến đỉnh khác
- Bảng Khoảng Cách (Distance Table): Là một bảng dùng để theo dõi khoảngcách tốt nhất đã biết từ một đỉnh xuất phát đến các đỉnh khác
- Tập Đỉnh Đã Xét (Visited Set): Là tập hợp các đỉnh mà thuật toán đã xétxong
- Đỉnh Xuất Phát (Source Vertex): Là đỉnh ban đầu từ đó thuật toán bắt đầutìm đường đi ngắn nhất
- Đỉnh Đích (Destination Vertex): Là đỉnh mà bạn muốn tìm đường đi ngắnnhất đến
- Priority Queue (Hàng Đợi Ưu Tiên): Là một cấu trúc dữ liệu giúp lưu trữ cácđỉnh cùng với ước lượng khoảng cách tốt nhất từ đỉnh xuất phát đến chúng,để lựa chọn đỉnh có ước lượng nhỏ nhất nhanh chóng
1.2 Cấu Trúc và Cài Đặt Thuật Toán
- Đồ Thị (Graph): đồ thị vô hướng chứa các đỉnh và các cặp cạnh liên quan,tạo ra một adjList để chứa các cặp cạnh
Trang 4* Thêm cạnh vào đồ thị: thêm các cặp cạnh theo 2 chiều thuận ngược vàkhoảng cách của các điểm liên quan do đây là đồ thị vô hướng.
Trang 5- Đỉnh Đích (Destination Vertex):- Priority Queue (Hàng Đợi Ưu Tiên):
1.3 Thuật Toán Dijkstra
1 Đặt khoảng cách tới nguồn là 0 và khoảng cách đến các đỉnh còn lại là vôcùng
Trang 62 Đặt đỉnh hiện tại vào nguồn.
3 Gắn cờ đỉnh hiện tại khi đã ghé thăm
4 Đối với tất cả các đỉnh liền kề với đỉnh hiện tại, đặt khoảng cách từ nguồnđến đỉnh liền kề bằng khoảng cách tối thiểu hiện tại của nó và tổng trọng sốcủa cạnh từ đỉnh hiện tại đến đỉnh liền kề và khoảng cách từ nguồn đến đỉnhhiện tại
Trang 75 Từ tập hợp các đỉnh chưa thăm, đặt tùy ý một đỉnh làm đỉnh hiện tại mới,miễn là tồn tại một cạnh sao cho nó là cạnh nhỏ nhất trong tất cả các cạnh từmột đỉnh trong tập các đỉnh đã thăm đến một đỉnh trong tập các đỉnh chưathăm đỉnh Để nhắc lại: Đỉnh hiện tại mới phải chưa được thăm và có cáccạnh có trọng số tối thiểu tính từ đỉnh đã thăm đến đỉnh đó Điều này có thểđược thực hiện một cách đơn giản bằng cách lặp qua tất cả các đỉnh đã thămvà tất cả các đỉnh chưa thăm liền kề với các đỉnh đã thăm đó, giữ đỉnh cócạnh có trọng số nhỏ nhất nối nó Lặp lại các bước 3-5 cho đến khi tất cả cácđỉnh được gắn cờ là đã truy cập.
Trang 8CHƯƠNG 2 PHÂN TÍCH VÀ THIẾT KẾ LỚP2.1 Phân Tích Bài Toán Tìm Kiếm Đường Đi Ngắn Nhất Dijkstra
Đối với bài toán tìm kiếm đường đi ngắn nhất, thuật toán Dijkstra là một trongnhững giải thuật phổ biến được sử dụng rộng rãi Ý tưởng cơ bản của thuật toánDijkstra là xác định các đỉnh gần nhất từ đỉnh nguồn và cập nhật chi phí ngắn nhấtđến tất cả các đỉnh kề của đỉnh đang xét Thuật toán tiếp tục lặp lại quá trình nàycho đến khi tất cả các đỉnh đều đã được xét.Việc sử dụng thuật toán Dijkstra để dòđường được áp dụng rộng rãi trong các lĩnh vực ở đời sống hiện nay Trong đóGoogle Map có lẽ là 1 đặc trưng được nhiều người biết đến, Google Map được biếtđến với khả năng tìm đường ngắn nhất giữa 2 địa điểm vô cùng tốt và đằng sauthuật toán của nó cũng là sử dụng các thuật toán Dijkstra với số lượng vô cùng lớnvì đây là thuật toán có độ phức tạp rất thấp (O((V + E) * log(V)), với V là số đỉnhvà E là số cạnh trong đồ thị) Bởi thế việc thể hiện 1 phần thuật toán lên một môhình bản đồ là vô cùng thực tế trong dự án lần này
Ứng dụng thuật toán Dijkstra trong Google Map
Vào với phần phân tích, về các điểm, bọn em sẽ cho bất kỳ trên nền màn hìnhthành phố, vì nếu sử dụng đường đi thực sẽ tốn rất nhiều thời gian và đồ khó cũng
Trang 9sẽ tăng lên, bởi thế bọn em sẽ minh họa các đường đi bằng các đường thẳng, trongđó các địa điểm sẽ là các đỉnh, giữa các đỉnh sẽ có đường đi (hoặc không), khoảngcách giữa 2 đỉnh sẽ được tính bằng công thức Euclid Mỗi điểm sẽ là một địa điểmmà chúng ta mong muốn đến hoặc sẽ đến, bởi thế việc tìm được đường đi ngắnnhất giữa vô vàn các điểm là một vấn đề vô cùng nan giải.
Trước khi bắt đầu thuật toán, chúng ta cần khởi tạo đồ thị và cấu trúc dữ liệu chocác điểm và các cạnh trên mô hình 2D cũng như 3D Mỗi điểm được biểu diễnbằng một struct <Point1>, bao gồm các thuộc tính như tọa độ x, y, z, và kích thước(left, width, top, height) Cấu trúc <Node> được sử dụng để lưu trữ thông tin củamỗi đỉnh trong quá trình thực hiện thuật toán Tiếp theo là đến cấu trúc dữ liệutương ứng, việc sử dụng vòng For và duyệt các mảng rồi đánh dấu sẽ mang lại độphức tạp thuật toán rất lớn, bời thể em sẽ sử dụng Priority Queue (Hàng chờ ưutiên) đây là 1 cấu trúc dữ liệu rất mạnh và hữu ích trong thuật toán Dijkstra này -
Trang 10một hàng chờ ưu tiên được triển khai bằng cách định nghĩa lại từ SortedSet Điềunày giúp quản lý các đỉnh và khoảng cách theo thứ tự ưu tiên và 1 hàm sắp xếp đểxếp các điểm có khoảng cách nhỏ nhất lên đỉnh hàng đợi, khoảng cách giữa 2 điểmnhau thì sẽ được tính theo công thức Euclid Việc khởi tạo sẽ bắt đầu khi ta chobiết số đỉnh của đồ thị ấy (Graph g = new Graph(20)), tham số này có thể đượcthay đổi tùy thuộc vào số lượng đỉnh trong đồ thị thực tế Đồ thị được biểu diễndưới dạng danh sách kề (adjList), mỗi đỉnh của đồ thị có danh sách các đỉnh kềkèm theo trọng số tương ứng Sau khi khởi tạo các đỉnh, ta bắt đầu sẽ gán các giátrị cho từng đỉnh, các giá trị của từng đỉnh chứa bao gồm X, Y, Z (Số thứ tự củađỉnh), Left, Width, Top, Height Trong đó X, Y của các đỉnh đề tính khoảng cách,Z để sử dụng khi nối các đỉnh với nhau (AddEdge) và cuối cùng 4 giá trị Left,Width, Top, Height để vẽ các đường nối lại với nhau Sau tạo đỉnh, ta sẽ tạo cáccạnh nối mỗi đỉnh, với hàm AddEdge có 2 tham số là 2 đỉnh với nhau, từ đó ta sẽtạo ra 1 cạnh nối 2 đỉnh đó lại (Phục vụ mục đích tìm đường đi sau này) Sau khiđã khởi tạo xong được các đỉnh và các cạnh mong muốn, chúng ta sẽ bắt đầu điđến với thuật toán Dijkstra.
Thuật toán Dijkstra, một phương pháp tìm đường đi ngắn nhất nổi tiếng, bắt đầubằng việc chuẩn bị một loạt các biến để theo dõi thông tin quan trọng Cụ thể,chúng ta khởi tạo các mảng để lưu trữ khoảng cách tới từng đỉnh, đỉnh trước đỉnhtrên đường đi ngắn nhất, và các thuộc tính khác của các đỉnh trong đồ thị Mỗi đỉnhđược mô tả bằng một struct, chứa tọa độ và các thuộc tính khác quan trọng Đểhiệu quả hóa quá trình duyệt, chúng ta sử dụng một hàng chờ ưu tiên, nơi các đỉnhđược tổ chức theo thứ tự khoảng cách ngắn nhất sẽ nằm trên đỉnh hàng đợi Đỉnhxuất phát được đưa vào hàng chờ với khoảng cách ban đầu là 0 Trong quá trìnhlặp, thuật toán trích xuất đỉnh có khoảng cách ngắn nhất từ hàng chờ Sau đó, nóduyệt qua các đỉnh kề và cập nhật thông tin nếu có một đường đi mới tốt hơn sovới đường đi trước đó Khi thuật toán hoàn tất, chúng ta có thể lấy thông tin vềđường đi ngắn nhất từ đỉnh xuất phát đến một đỉnh bất kỳ Trong đó mảngprevVertex để lưu lại các đường đi trước đó tới đỉnh đó mà với khoảng cách ngắnnhất Sau đó, ở hàm PrintPath được sử dụng để hiển thị và vẽ đường đi trên đồ thịvới 2 tham số là đỉnh bắt đầu và đỉnh kết thúc, từ đó hàm PrintPath sẽ dò ngược lạitừ đỉnh kết thúc và gọi hàm Marking để vẽ lên 2 cặp cạnh, việc này sẽ tiếp tục chođến khi hàm vẽ nối cả 2 đỉnh start và end lại với nhau Kết quả in ra là đường đingắn nhất từ đỉnh với tham số Start tới đỉnh có tham số là End
Trang 11Kết quả của thuật toán là khoảng cách ngắn nhất từ 2 điểm ta chọn, không chỉ thế,mỗi điểm còn chứa thông tin về đỉnh trước đó, vô cùng thuận tiện cho việc tái tạođường đi cụ thể hoặc các phương thức mà cần đến các giá trị cụ thể đó Sự tích hợpcủa hàng chờ ưu tiên giúp xử lý các đỉnh theo thứ tự tăng dần của khoảng cách, tốiưu hóa quá trình tìm kiếm Hàm PrintPath không chỉ là công cụ trực quan hóa kếtquả mà còn giúp hiểu rõ cách thuật toán quyết định đường đi và làm thế nào nóđược biểu diễn trên đồ thị Kết quả cuối cùng của thuật toán không chỉ là mộtkhoảng cách số học, mà còn là sự kết hợp tinh tế giữa các thuộc tính như tọa độ,kích thước và vị trí của các điểm trên đồ thị.
Trang 122.2 Sơ Đồ Lớp
2.3 Cài Đặt Lớp
a Struct Point1- Biểu diễn tọa độ của các điểm (x,y) và số thứ tự của mỗi điểm z
Trang 13- Lưu trữ vị trí các button trên mặt phẳng bằng các trường dữ liệu left (tọađộ bên trái của button) , width, top, height (giả sử là chia đôi (top + width)sẽ là vị trí của button).
b Struct Node- Lưu trữ khoảng cách tạm thời từ đỉnh xuất phát đến đỉnh hiện tại và chỉ số
của các điểm khi được thêm vào qua biến distance và index
c Class CompareNode- Sắp xếp những điểm có khoảng cách nhỏ nhất lên trên.- Sử dụng để so sánh các đối tượng kiểu Node trong một PriorityQueue
d Class PriorityQueue- Xây dựng một hàng đợi ưu tiên được sắp xếp theo thứ tự tăng dần được
định nghĩa bởi một IComparer<T>.- Lớp PriorityQueue<T> được kế thừa từ lớp SortedSet<T>, một tập hợp
sắp xếp các phần tử duy nhất SortedSet<T> được sử dụng để đảm bảorằng các phần tử trong PriorityQueue được sắp xếp theo thứ tự tăng dần(hoặc theo quy tắc được định nghĩa bởi IComparer<T>)
Trang 14- Có hai hàm tạo, một không có tham số và một có tham số comparer Hàmtạo không có tham số sử dụng sắp xếp mặc định (theo thứ tự tăng dần củakiểu dữ liệu), còn hàm tạo có tham số comparer cho phép người dùng tựđịnh nghĩa quy tắc sắp xếp.
- Phương Thức Enqueue(T item) thêm một phần tử vào PriorityQueue.Trong trường hợp này, nó được triển khai bằng cách sử dụng phương thứcAdd(item) của lớp SortedSet<T>, vì SortedSet<T> giữ các phần tử đã sắpxếp
- Phương Thức Dequeue() trích xuất và trả về phần tử đầu tiên củaPriorityQueue, tức là phần tử có ưu tiên cao nhất Trong trường hợp này,nó sử dụng First() để lấy phần tử đầu tiên, sau đó gọi Remove(item) đểloại bỏ phần tử đó khỏi PriorityQueue
e Class Graph- Sử dụng để biểu diễn đồ thị Trong hàm tạo, đồ thị được khởi tạo với số
đỉnh (V) và danh sách kề (adjList) với các cặp cạnh thuận nghịch liênquan
- Hàm AddEdge thêm một cạnh giữa hai đỉnh u và v vào đồ thị, tính trọngsố của cạnh dựa trên khoảng cách giữa hai điểm tương ứng
- Hàm AddPoint thêm một điểm mới vào đồ thị.- Hàm CalculateDistance tính khoảng cách Euclid giữa hai điểm dựa trên
tọa độ x và y của chúng
Trang 15- Thuật toán Dijkstra.- Mảng lưu khoảng cách từng điểm (distance) đã được tính trước đó và lưu
lại các điểm đã đi qua (prevVertex, prevX, prevY, prevLeft, prevWidth,prevTop, prevHeight)
- Hàm Dijkstra thực hiện thuật toán Dijkstra để tìm đường đi ngắn nhất từđỉnh start đến đỉnh end
- Ban đầu, khoảng cách từ cạnh 0 tới cạnh 0 là 0, khoảng cách từ 0 đến cácsố còn lại là vô cực
- Sử dụng một mảng distance để lưu trữ khoảng cách ngắn nhất từ đỉnh xuấtphát đến các đỉnh khác và một hàng đợi ưu tiên (PriorityQueue<Node>)để lựa chọn đỉnh tiếp theo có khoảng cách nhỏ nhất
- Đầu tiên là thêm cặp cạnh (0,0) vào trước và lần lượt các cặp cạnh tiếptheo, lấy điểm u và khoảng cách để so sánh Nếu tổng của đỉnh đang xét(u) + trọng số của 2 đỉnh u và v bé hơn khoảng cách cũ thì lưu lại đườngđi đó với tọa độ điểm tương ứng và đôn hàng chờ ưu tiên lên thêm.- Duyệt qua các đỉnh kề của đỉnh hiện tại, cập nhật khoảng cách và thông
tin đỉnh trước đỉnh hiện tại nếu có đường đi mới ngắn hơn.- Cuối cùng, gọi hàm PrintPath để in ra đường đi ngắn nhất
Trang 17f Void PrintPath- Lưu lại các biến để dò ngược lại các cạnh trước đó (preVertex) của
cạnh hiện tại đang xét (current) đồ thị và dùng hàm Reverse để đảolại
- Tạo một danh sách path để lưu trữ thông tin về các điểm trên đườngđi
- Sử dụng vòng lặp while để duyệt ngược từ đỉnh kết thúc (end) về đỉnhxuất phát (start), lấy thông tin của các điểm trên đường đi và thêm vàodanh sách path
- Sau khi thu được danh sách path, thực hiện bước này để đảo ngượcthứ tự của nó
- Thêm thông tin về điểm kết thúc (points[end]) vào cuối danh sáchpath
- Sử dụng vòng lặp for để duyệt qua các điểm trong danh sách path
Trang 18- Trong mỗi bước, lấy thông tin về điểm hiện tại (currentTuple) và điểmtrước đó (previousTuple).
- Tính khoảng cách giữa hai điểm bằng hàm EuclidDistance.- Cộng khoảng cách này vào biến kc (được giả sử là biến toàn cục).- Gọi hàm Marking để vẽ đường đi giữa hai điểm, với tham số là tọa độ
trung điểm giữa các button
Trang 19CHƯƠNG 3 THIẾT KẾ GIAO DIỆN3.1 Giao Diện Menu Chính
Giao diện menu chính được thiết kế nhằm đảm bảo người dùng có trải nghiệmthuận lợi và dễ sử dụng, với màu xanh nước biển cùng cỡ chữ hài hòa, người dùngsẽ thuận tay và êm mắt hơn khi sử dụng ứng dụng để tìm kiếm các đường, đồngthời cũng rất đơn giản và vào thẳng về phần thuật toán Dijkstra Giao diện này sẽbao gồm các phần quan trọng như sau:
1 Phần tìm kiếm gián tiếp: Bao gồm 2 ComboBox để chứa các địa điểm trênbản đồ và nút Search để thực hiện việc tìm kiếm, ứng dụng sẽ in ra đường đingắn nhất, tìm kiếm gián tiếp để người dùng khi biết cụ thể vị trí mình đangở và muốn tìm nhanh nhất
2 Phần tìm kiếm trực tiếp: Bao gồm 20 điểm trên các bản đồ, mỗi điểm sẽ cócạnh tương ứng nối với nhau, khi người dùng bấm được 2 điểm (khác nhau),ứng dụng sẽ in ra đường đi ngắn nhất Phần tìm kiếm trực tiếp khi ngườidùng chưa biết rõ vị trí mình muốn tới mà chỉ xem là đâu sẽ là nơi gần nhấtcó thể tới
3 Phần Địa điểm gần đó: Sẽ hiện lên các điểm xung quanh các đỉnh mà tađang chọn, các địa điểm sẽ được mặc định cho đỉnh ấy và không thay đổi.Giúp cho người dùng biết thêm thông tin về các địa điểm nổi tiếng xungquanh đỉnh ấy
Trang 20Giao diện sẽ tối ưu các chức năng ở màn hình chính để người dùng có thể trảinghiệm hết chức năng mà không cần phải mất thời gian nhấn các nút đổi Tab qualại giữa từng chức năng, việc này sẽ giúp người dùng trải nghiệm được tính năngcủa ứng dụng một cách tốt nhất.
3.2 Chi Tiết Chức Năng
Thanh chọn điểm bắt đầu được và thanh chọn điểm đến đặt ở vị trí nổi bật trên giaodiện, giúp người dùng nhanh chóng xác định và chọn điểm xuất phát và điểm đếncho thuật toán Dijkstra Các thanh này cũng có thể hỗ trợ tính năng tìm kiếm đểngười dùng dễ dàng lựa chọn từ danh sách các đỉnh có sẵn
Sau khi thuật toán Dijkstra thực hiện xong, giao diện sẽ hiển thị đường đi ngắnnhất từ điểm bắt đầu đến điểm đến Đường đi này sẽ được đánh dấu bằng đường đỏtrên bản đồ Đơn vị đo lường khoảng cách sẽ được hiển thị rõ ràng bằng khoảngcách Euclid của từng cặp đỉnh được xét Đường đi được in ra trên màn hình làđường đi tối ưu nhất của 2 điểm mà người dùng chọn vào, ngoài ra khi sử dụngchức năng tìm kiếm, việc này làm người dùng có thể thuận tiện hơn để tìm kiếmnhanh hơn vì nếu đồ thị cỡ lớn, không chỉ có 20 điểm mà sẽ còn nhiều hơn, bởi thểchức năng tìm kiếm là vô cùng quan trọng với người dùng muốn tìm cụ thể nơimình đang ở và giúp không bị rối mắt với chằng chịt các đỉnh trên đồ thị.Giao diện cũng gồm tính năng “Địa điểm gần đó” hiển thị các khu vực xung quanhđịa điểm mà người dùng nhập Các địa điểm gần đó của mỗi điểm là cố định vàkhông phải biến, được bọn em nhập vào với các địa điểm nổi tiếng ngoài đời thật