Danh sách bảng:Table 1: Bảng Phân công nhiệm vụ và đánh giá mức độ hoàn thành...3Table 2: Đánh giá mức độ phù hợp của các cách biểu diễn đồ thị...4Danh sách hình ảnh:Pic 1: Giải thuật gi
Trang 1TR ƯỜ NG Đ I H C BÁCH KHOA HÀ N I Ạ Ọ Ộ
Cấấu trúc d li u và gi i thu t ữ ệ ả ậ
Đào Đông Phong 20214036 Ph4ng Minh Hiê6u 20200861 V9 Đăng Trung 20214118 V9 Hoàng Long 20213988
Hà N i, 3/2023 ộ
Trang 2Mục lục
1 Giới thiệu 4
1.1 Lý do chọn đề tài 4
1.2 Bảng phân công nhiệm vụ và mức độ hoàn thành 5
2 Phương pháp lựa chọn 5
2.1 Cấu trúc dữ liệu 5
2.2 Giải thuật 7
3 Triển khai cài đặt 10
3.1 Ngôn ngữ lập trình và thư viện 10
3.2 Tổ chức chương trình và đóng gói 10
4 Kết luận 14
4.1 Đánh giá về mức độ hoàn thành 14
4.2 Bài học rút ra 14
4.3 Các khó khăn khi học tập môn Cấu trúc dữ liệu & Giải thuật 14
Trang 3Danh sách bảng:
Table 1: Bảng Phân công nhiệm vụ và đánh giá mức độ hoàn thành 3 Table 2: Đánh giá mức độ phù hợp của các cách biểu diễn đồ thị 4 Danh sách hình ảnh:
Pic 1: Giải thuật giải quyết bài toán đặt ra 6 Pic 2: Giải thuật Dijkstra 7
Trang 41 Giới thiệu
1.1 Lý do chọn đề tài
Trong cuộc sống, khi cQn xảy ra tình huống không muốn như tai n愃⌀n hoă Tc cQn tìm sự trợ giúp về mă Tt y tế mô Tt cách khUn cấp viê Tc tìm bê Tnh viê Tn gQn nhất và đưWng đi ngXn nhất đến bê Tnh viê Tn ấy là mô Tt viê Tc hết sức cQn thiết
và phQn nào quyết định đến khả năng cứu chữa
Định nghĩa bài toán cQn giải quyết
Đề tài “Tìm bê Tnh viê Tn gQn nhất và đưWng đi ngXn nhất đến bê Tnh viê Tn ấy”
Bài toán: Tìm bê Tnh viê Tn gQn nhất và đưWng đi ngXn nhất đến bê Tnh viê Tn ấy
Input: Vị trí hiê Tn t愃⌀i Start
Output: Bê Tnh viê Tn gQn nhất và đưWng đi đến bê Tnh viê Tn ấy
Trang 51.2 Bảng phân công nhiệm vụ và mức độ hoàn thành
Mô tả công việc ThWi gian bXt
đQu ThWi gian kết thúc Thành viên thực hiện Mức độ hoàn thành Thành lập nhóm 07/11/2022 07/11/2022 Cả nhóm 100% Lựa chọn đề tài bài
tập lớn 07/11/2022 20/11/2022 Cả nhóm 100% Tìm hiểu thông tin và
đọc các tài liệu liên
quan đến đề tài lựa
chọn
20/11/2002 27/11/2022 Cả nhóm 100%
Tổng hợp kiến thức 27/11/2022 27/11/2022 Cả nhóm 100% Phân chia nhiệm vụ
giới thiệu bài tập lớn
của nhóm
27/11/2022 27/11/2022 Phong 100%
Làm slide giới thiệu
bài tập lớn
27/11/2022 29/11/2022 Trung 100% Giới thiệu bài tập lớn
của nhóm với lớp
30/11/2022 30/11/2022 Long 100% Chỉnh sửa l愃⌀i đề tài
theo gợi ý của cô
30/11/2022 31/12/2022 Cả nhóm 100% Nghiên cứu thuật toán
tìm đưWng đi ngXn
nhất Dijkstra
03/01/2023 10/01/2023 Cả nhóm 100%
Đưa ra giải thuật để
giải quyết bài toán
11/01/2023 16/01/2023 Hiếu + Hiếu 100% Biến đổi từ giải thuật
thành code 17/01/202328/01/2023 18/01/202306/02/2023 Phong + Long 100% Test + sửa lỗi 06/02/2023 09/02/2023 Cả nhóm 100%
Table 1: B ng Phân công nhi m v và đánh giá m c đ hoàn thànhả ệ ụ ứ ộ
2 Phương pháp lựa chọn
2.1 Cấu trúc dữ liệu
- Cấu trúc dữ liệu “Bản đồ phưWng Hàng Bông” là một đơn đồ thị
vô hướng G(V,E) bao gồm:
+ Tập đỉnh V: là tập hữu h愃⌀n phQn tử, mỗi phQn tử đ愃⌀i diện cho một tọa độ trên bản đồ gọi là một đỉnh
+ Tập các c愃⌀nh E: Mỗi phQn tử có d愃⌀ng (u,v,z) gọi là c愃⌀nh với u,v (u ≠ v) và có trọng số z là phQn tử thuộc tập đỉnh V
+ Tâ Tp các bê Tnh viê Tn F: Mỗi tâ Tp con của tâ Tp đỉnh V, mỗi phQn
tử là mô Tt bê Tnh viê Tn
Trang 6- Biểu diễn đồ thị của một cấu trúc dữ liệu bản đồ còn phụ thuộc vào
nhiều yếu tố:
+ Bài toán cụ thể cQn giải quyết: xây dựng một ứng dụng tìm
Bê Tnh viê Tn gQn nhất và đưWng đi đến bê Tnh viê Tn ấy
+ Thuật toán cụ thể cài đặt: thuật toán Dijkstra
+ Bộ nhớ đòi hỏi khi biểu diễn: Số lượng phQn tử thuộc tập
đỉnh là gQn 500 phQn tử
+ PhQn lớn các đỉnh chỉ có 2 c愃⌀nh, độ phức t愃⌀p đồ thị thấp + Tốc độ xử lí: cQn xử lí nhanh chóng vì nhu cQu truy vấn dữ
liệu thưWng xuyên của ngưWi sử dụng
- Cách biểu diễn đồ thị được lựa chọn: Biểu diễn đồ thị bởi danh sách
c愃⌀nh(mảng các danh sách liên kết)
+ Cách đánh giá: Đánh giá theo mức độ phù hợp
Cách biểu diễn Đánh giá
Ma trân đỉnh kề Tốn bộ nhớ, có lợi về thWi gian, phù hợp cho đồ thị có độ
phức t愃⌀o cao và các đỉnh liên kết chặt chẽ với nhau, có thể cài đặt thuật toán
Ma trận c愃⌀nh kề
Danh sách kề Có lợi về bộ nhớ, phù hợp cho đồ thị có độ phức t愃⌀p thấp,
đỉnh có ít c愃⌀nh kề, dễ cài đặt, có thể cài đặt thuật toán Danh sách c愃⌀nh Có lợi về bộ nhớ, không thuận tiện thao tác với đồ thị, có thể
cài đặt thuật toán
Table 2: Đánh giá m c đ phù h p c a các cách bi u diễễn đôồ thứ ộ ợ ủ ể ị
+ Đánh giá lựa chọn: trung bình
Trang 7Danh sách c愃⌀nh trong lý thuyết đồ thị được lưu trữ vào mảng một chiều, mỗi phQn tử của mảng sẽ thể hiện thông tin của 2 đỉnh kề nhau
Với mô tả bên trên b愃⌀n có thể t愃⌀o cho riêng mình một struct dữ liệu của một c愃⌀nh gồm 2 thông tin, và khai báo một mảng thuộc dữ liệu đó Tuy nhiên trong code tham khảo về nhập dữ liệu cho danh sách c愃⌀nh trong lý thuyết đồ thị dưới đây, mình sẽ t愃⌀o 2 mảng riêng mà không dùng struct
Code biểu diễn đồ thị bằng danh sách c愃⌀nh c++:
#define NMAX 100
int x[NMAX*NMAX+1], y[NMAX*NMAX+1];
int n, m, u, v;
cin >> n >> m;
for (int i=1; i<=m; i++)
{
cin >>x[i]>>y[i];
}
2.2 Giải thuật
Giải thuật để giải quyết bài toán được minh họa thông qua flowchart 1 như sau:
Pic 1: Gi i thu t gi i quyễết bài toán đ t raả ậ ả ặ
Trang 8
Flowchart 2 dùng để minh họa thuật toán Dijkstra:
Pic 2: Gi i thu t Dijkstraả ậ
Bước 1: BXt đQu chương trình
Bước 2: Đưa vào thông tin vị trí xuất phát A và vị trí muốn tới B
Bước 3: Khởi t愃⌀o khoảng cách từ A tới chính nó là 0, tới các vị trí còn l愃⌀i
là ∞ và tập S rỗng
Bước 4: Kiểm tra tập các vị trí có rỗng không
4.1: Nếu rỗng thì nhảy đến bước 9
4.2: Nếu không rỗng thì nhảy tới bước 5
Bước 5: Đưa vị trí C có khoảng cách nhỏ nhất trong tập các vị trí vào tập
S và xóa nó khỏi tập các vị trí
Bước 6: Kiểm tra các vị trí D kề với C có khoảng cách bằng ∞ không 6.1: Nếu bằng thì nhảy đến bước 8
6.2: Nếu không thì nhảy đến bước 7
Bước 7: Kiểm tra các vị trí D kề với C có khoảng cách lớn hơn khoảng cách C + khoảng cách CD không
7.1: Nếu lớn hơn thì nhảy đến bước 8
Trang 97.2: Nếu không lớn hơn thì nhảy đến bước 4
Bước 8: Đặt l愃⌀i khoảng cách D bằng khoảng cách C + khoảng cách CD
và lưu vị trí kề trước của D là C
Bước 9: Khởi t愃⌀o tập min rỗng
Bước 10: Đưa vị trí B vào tập min
Bước 11: Đưa vị trí E là vị trí kề trước của vị trí vừa thêm vào tập min vào tập min
Bước 12: kiểm tra vị trí E có phải A hay không
12.1: Nếu E là A thì nhảy đến bước 13
12.2: Nếu E không phải A nhảy tới bước 11
Bước 13: Đưa thông tin về đưWng đi ngXn nhất vào chương trình Bước 14: Kết thúc chương trình
Trang 103 Triển khai cài đặt
3.1 Ngôn ngữ lập trình và thư viện
+ C++
+ Thư viện:bits/stdc++.h
3.2 Tổ chức chương trình và đóng gói
a) Tổ chức chương trình gồm các bước sau:
(1) Khai báo các thư viện làm việc;
(2) Khai báo các hằng và biến toàn cục cQn thiết:
+Hằng số: const int N = 500; (Số lượng đỉnh tối đa của tập đỉnh V)
+ Biến số: int n, m, k; với n là số lượng đỉnh thực tế đưa vào chương trình, m là số đưWng đi trong đồ thị và k là số bê Tnh viê Tn trong đồ thị
(3) vector<pair<int,int> > a[N]: là mảng danh sách liên kết với
a[i].second là trọng số của c愃⌀nh nối giữa i và a[i].first
+vector<int> bv: là danh sách liên kết biểu thị các bê Tnh viê Tn trong đồ thị
(4) Hàm thuật toán Dijktra tìm bê Tnh viê Tn gQn nhất và truy vết đưWng đi đến bê Tnh viê Tn gQn nhất
(5) Chương trình chính
Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 500;
int n,m,k;
vector<pair<int,int> > a[N];
vector<int> bv,path;
int trace[N],f[N];
int dijkstra(int s){
for(int i = 1;i<=n;i++)
f[i]=1e9+7,
trace[i]=-1;
f[s]=0;
Trang 11priority_queue<pair<int,int> > pq;
pq.push(make_pair(0,s));
while(!pq.empty()){
int du = pq.top().first;
int u = pq.top().second;
pq.pop();
if(f[u] != du) continue;
for(pair<int,int> p : a[u]){
int v = p.first;
int dv = p.second;
if(f[v] > f[u]+dv) f[v] = f[u]+dv, trace[v]=u, pq.push(make_pair(f[v],v)); }
}
f[n+1]=1e9+7;
int kq= n+1;
for(int t:bv)
if(f[t] < f[kq])
kq=t;
path.clear();
int t = kq;
while(t!=0) {
path.push_back(t);
t=trace[t];
}
reverse(path.begin(),path.end());
return kq;
}
int main()
{
Trang 12freopen("a.inp", "r", stdin);
freopen("a.out", "w", stdout);
cin>>n>>m>>k;
for(int i=1;i<=m;i++) {
int x,y,z;
cin>>x>>y>>z;
a[x].push_back(make_pair(y,z)); a[y].push_back(make_pair(x,z)); }
for(int i =1;i<=k;i++){
int b;
cin>>b;
bv.push_back(b);
}
int s;
cin>>s;
cout<<dijkstra(s)<<'\n';
for(int x:path)
cout<<x<<' ';
}
Testcase:
Input:
20 22 4
1 2 110
2 3 38
3 4 42
4 7 39
7 6 140
5 6 42
1 14 90
7 8 120
8 9 240
9 10 98
10 11 180
Trang 138 15 65
15 14 13
15 12 12
12 14 10
12 13 68
10 13 230
11 13 140
11 16 60
16 18 31
11 17 38
17 19 30
16 17 18 19 2
Output:
17
2 1 14 12 13 11 17
Trang 144 Kết luận
4.1 Đánh giá về mức độ hoàn thành
Theo đánh giá chung của cả nhóm thì bài tập lớn này đã hoàn thành
được 85%, bài toán đặt ra đã được giải quyết và đã biểu diễn được
đưWng đi trên bản đồ Tuy nhiên vẫn còn nhiều h愃⌀n chế như: do h愃⌀n chế về thWi gian, nên nhóm chưa thể mở rô Tng ph愃⌀m vi tìm kiếm bê Tnh
viê Tn ra toàn quâ Tn, thành phố, để bài toán chính xác hơn cQn thu nhâ Tp
nhiều đỉnh hơn
4.2 Bài học rút ra
Qua bài tập lớn này nhóm rút ra được bài học về việc phân chia công
việc phù hợp với năng lực từng cá nhân NhW việc này mà tiến trình
làm việc được đUy nhanh và mXc phải ít lỗi Bên c愃⌀nh đó việc phân
chia công việc phù hợp năng lực từng cá nhân giúp cho việc giải đáp
thXc mXc một cách dễ dàng, ngoài những buổi họp nhóm để báo cáo
tiến độ, giải đáp thXc mXc cũng như phân chia công việc phát sinh
thêm thì các thành viên có thể liên hệ trực tiếp tới cá nhân phụ trách
công việc nếu có bất kỳ thXc mXc nào
4.3 Các khó khăn khi học tập môn Cấu trúc dữ liệu & Giải thuật
Trong quá trình làm bài tập lớn cũng như học tập môn học, nhóm cũng
như các cá nhân gặp không ít khó khăn Do lựa chọn đề tài liên quan
đến graph cũng như đưWng đi ngXn nhất nên thWi gian đQu nhóm chưa
thể bXt tay vào làm luôn mà phải tìm hiểu trước về kiến thức Bên
c愃⌀nh đó thì trong thWi gian học tập t愃⌀i giảng đưWng, ngoài kiến thức cô cung cấp thông qua slide và bảng viết ra thì các thành viên cQn xem
thêm qua tài liệu trên m愃⌀ng, tuy nhiên do h愃⌀n chế về m愃⌀ng t愃⌀i khu vực D9 của nhà trưWng cũng như h愃⌀n chế về mặt thiết bị đã dẫn tới có
những phQn kiến thức chưa nXm rõ, một số bài kiểm tra chưa thể đ愃⌀t
được điểm số như mong muốn Mong cô và nhà trưWng có thể xem xét
về vấn đề này
Trang 155 Tài liệu tham khảo
[1] Nguyễn Tuấn’s Blog, “Thuật toán Dijkstra: Tìm đưWng đi ngXn nhất”, 09/11/2021 [Online] Available: Thuật toán Dijkstra: Tìm đưWng đi ngXn nhất (chidokun.github.io)
[2] Cấu trúc dữ liệu và giải thuật, Đỗ Xuân Lôi