Mô tả chức năng của từng lớp, từng phương thức.- Lớp Node: Lưu tên đỉnh và trọng số Và biến con trỏ *next sẽ lưu địa chỉ của node tiếp theo trong danh sách liên kết.. Với Nodeint vertex
Trang 1TRƯỜNG ĐẠI HỌC GIAO THÔNG VÂN TẢI KHOA CÔNG NGHỆ THÔNG TIN o0o
Bài tập lớn môn học
CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT
Giảng viên hướng dẫn: TS Hoàng Văn Thông
Sinh viên thực hiện: Đỗ Minh Giang
Lớp: CNTT VA 1
Hà Nội tháng 11 năm 2022
1
Trang 2M c L c ục Lục ục Lục
Hà Nội tháng 11 năm 2022 2
Đề Bài 2
Phân tích bài toán 3
Phân tích đề bài: 3
Mô tả chức năng của từng lớp, từng phương thức 4
Phân tích thời gian chạy của từng phương thức có trong các lớp 14
Danh sách tài liệu tham khảo 15
1
Trang 3I.Đề Bài
1 Xây dựng lớp biểu diễn đồ thị đồ thị (Graph) vô hướng có trọng số bằng danh sách kề Mỗi đỉnh của đồ thị là một số tự nhiên có giá trị duy nhất trong đồ thị Mỗi cung của đồ thị được xác lập bằng một cặp đỉnh và một trọng số là số thực
2 Cài đặt các thao tác cơ bản trên đồ thị như sau
− Khởi tạo một đồ thị ban đầu rỗng có n đỉnh
− InsertEdge(int s, int d, float weight): bổ sung một cung có trọng số w
giữa hai đỉnh u, v (u, v<=n)
− InsertVertex(name): thêm một đỉnh mới vào đồ thị (đỉnh n+1, n+2,…)
− GetWeight(int s, int d): lấy ra trọng số của một cạnh
− Print: hiển thị hiện trạng của đồ thị
− Cài đặt thuật toán Dijkstra tìm đường đi ngắn nhất trong đồ thị
3 Xây dựng một chương trình nhận đầu vào là một file text chứa thông tin về một đồ thị cho trước, tạo lập đồ thị, hiển thị đồ thị lên và từng bước của quá trình tìm đường đi ngắn nhất từ đỉnh (u, v) được người dùng nhập từ bàn phím
2
Trang 4Phân tích bài toán
Phân tích đề bài:
1.1 Xây dựng một đồ thị (Graph) vô hướng có trọng số là một số thực bằng danh sách kề
1.2 Với các thao tác sau:
1.2.1 Khởi tạo một đồ thị ban đầu rỗng có n đỉnh
1.2.2 Tạo 1 phương thức InsertEdge để bổ sung trọng số w giữa
hai đỉnh u, v với u, v nhỏ hơn n
1.2.3 Tạo 1 phương thức thêm 1 đỉnh mới cho đồ thị InsertVertex 1.2.4 Tạo 1 phương thức lấy trọng số GetWeight
1.2.5 Tạo 1 phương thức in trạng thái của đồ thị Print
1.2.6 Cài đặt thuật toán Dijkstra để tìm đường đi ngắn nhất trong
đồ thị
1.3 Xây dựng chương trình nhận đầu vào là một file text bao gồm các thông tin của đồ thị, in đồ thị lên màn hình, hiển thị quá trình tìm đường đi ngắn nhất từ (u,v) được người dùng nhập từ bàn phím
3
Trang 5Mô tả chức năng của từng lớp, từng phương thức.
- Lớp Node:
Lưu tên đỉnh và trọng số
Và biến con trỏ *next sẽ lưu địa chỉ của node tiếp theo trong danh sách liên kết
Với Node(int vertex) truyền 1 kiểu dữ liệu là kiểu nguyên làm tên đỉnh, sau đó gán tên đỉnh chính bằng dữ liệu vừa truyền và cho trọng số bằng -1 vì trọng số cần xác định với 2 đỉnh, tiếp đó con trỏ next sẽ được gán bằng null vì danh sách mới khởi tạo
1 node
4
Trang 6- Lớp Graph:
Được khởi tạo với 2 thuộc tính là numVer để lưu số đỉnh của đồ thị và con trỏ mang kiểu dữ liệu Node trỏ tới địa chỉ của mảng danh sách liên kết đơn
Phương thức khởi tạo Constructor có đối là số đỉnh của đồ thị int numVer Đầu tiên
sử dụng con trỏ this gán giá trị đỉnh bằng giá trị truyền vào numVer Tiếp theo khởi tạo một list với kiểu dữ liệu node và số đỉnh cộng với 3 (để lưu giá trị của 2 đỉnh và 1 trọng số) Sử dụng vòng for để duyệt hết giá trị của của biến Tiếp tục khởi tạo một con trỏ temp kiểu dữ liệu Node để tạo 1 nốt mới sau đó gán biến temp vào danh sách liên kết đơn list
5
Trang 7Phương thức InsertEdge thuộc lớp Graph với đầu vào được truyền đỉnh thứ 1 int s và đỉnh thứ 2 int d và trọng số có kiểu số thực double Đầu tiên khởi tạo một biến temp với kiểu dữ liệu node Sau đó con trỏ next sẽ trỏ đến địa chỉ của của s Sau đó gán giá trị của phần tử đầu tiên của danh sách liên kết bằng temp Và cuối cùng gán trọng số giữ 2 đỉnh d và s bằng biến weight
6
Trang 8Phương thức InsertVertex thêm một đỉnh của đồ thị Đầu tiên cộng thêm 1 vào biến
số đỉnh của đồ thị numVer Tiếp theo khởi tạo con trỏ temp có kiểu dữ liệu là node
và truyền số đỉnh vào Sau đó thêm vào danh sách liên kết và gán bằng biến temp
7
Trang 9Phương thức in đồ thị theo danh sách kề ra ngoài màn hình Sử dụng vòng For để duyệt từ i = 0 đến i = số đỉnh Khởi tạo một biến temp bằng phần tử thứ i trong danh sách liên kết đơn Tiếp tục sử dụng vòng lặp while khi nào biến team khác rỗng Lấy
ra đỉnh và trọng số đi kèm trong danh sách liên kết rồi in ra màn hình Mỗi vòng lặp while gắn temp bằng địa chỉ của node tiếp theo
8
Trang 10Hai phương thước đọc dữ liệu Phương thức thứ nhất Read với đối số truyền vào là n
là số đỉnh của đồ thị Khai báo 2 biến a, b sẽ là từng đỉnh của đồ thị và biến c kiểu dữ liệu số thực nhận trọng số giữa 2 đỉnh Sử dụng vòng for để duyệt từ phần tử thứ 0 tới thứ n và nhận 3 giá trị a, b, c sau đó con trỏ this sẽ trỏ tới phương thức InsertEdge để tạo 1 cạnh trong đồ thị với 2 đỉnh là giá trị a, b và trọng số c
Phương thức đọc init là phương thức đọc file nhận dữ liệu cho thuật toán Dijstra Đầu tiên là câu lệnh mở file và chỉ với chức năng đọc file
9
Trang 11Bước 1: Từ đỉnh gốc, khởi tạo khoảng cách tới chính nó là 00, khởi tạo khoảng cách nhỏ
nhất ban đầu tới các đỉnh khác là +\infty+∞ Ta được danh sách các khoảng cách tới các đỉnh
Bước 2: Chọn đỉnh a có khoảng cách nhỏ nhất trong danh sách này và ghi nhận Các lần
sau sẽ không xét tới đỉnh này nữa
Bước 3: Lần lượt xét các đỉnh kề b của đỉnh a Nếu khoảng cách từ đỉnh gốc tới
đỉnh b nhỏ hơn khoảng cách hiện tại đang được ghi nhận thì cập nhật giá trị và đỉnh
kề a vào khoảng cách hiện tại của b
10
Trang 12Bước 4: Sau khi xét tất cả đỉnh kề b của đỉnh a Lúc này ta được danh sách khoảng cách
tới các điểm đã được cập nhật Quay lại Bước 2 với danh sách này Thuật toán kết thúc
khi chọn được khoảng cách nhỏ nhất từ tất cả các điểm
Hai phương thức truy vết và phương thức in dùng để ghi lại đường đi, các đỉnh đã duyệt qua và lưu vào stack Sau đó in ra đường đi ngắn nhất đã tìm được
11
Trang 15Phân tích thời gian chạy của từng phương thức có trong các lớp
void InsertEdge(int s,int d,double weight)
Bao gồm 2 câu lệnh khởi tạo và 6 câu lệnh gán Nên thời gian chạy của phương thức là:
O(1)
void InsertVertex()
Bao gồm 1 câu lệnh khởi tạo vào 2 câu lệnh gán, thời gian chạy của phương thức là:
O(1)
void Print()
Bao gồm 2 vòng lặp lồng nhau và 2 câu lệnh in, thời gian chạy của phương thức là:
O(mn) + O(1)
void Read(int n)
Phương thức gòm những câu lệnh khởi tạo và 1 vòng lặp và đệ quy nên thời gian chạy:
O(log n)
void init()
Bao gồm 2 vòng lặp có thời gian chạy là
O(1) + O(n) + O(n)
void DIJKSTRA()
Thời gian chạy của thuật toán trên là
O(n)
14
Trang 16Danh sách tài liệu tham khảo
https://gist.github.com Nên tảng chia sẻ giữa các lập trình viên.
https://chidokun.github.io/2021/09/dijkstra-algorithm Tài liệu và ý tưởng về thuật toán Dijkstra.
https://usaco.guide/bronze/time-comp?
lang=cpp&fbclid=IwAR3c5bRxhlkRXC22fglKAYhPcag-S8CNV5fNaq_fScU0Q4skQazlkOlaa0I Tài liệu tham khảo phân tích thời gian chạy của thuật toán.
https://topdev.vn Tài liệu tham khảo danh sách liên kết đơn.
15