Việc xác định trạng thái bài toán như vậy sẽ đảm bảo đường đi tìm được luôn thỏa mãn ràng buộc: “Chỉ được phép đi trên các tuyến đường, không được phép đi xuyên qua các công trình”... Bư
Trang 1ĐẠI HỌC BÁCH KHOA HÀ NỘI
TRƯỜNG CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG ──────── * ───────
BÀI TẬP LỚN
MÔN: NHẬP MÔN TRÍ TUỆ NHÂN TẠO
Đề tài: Phần mềm tìm đường đi trên bản đồ
Nhóm: 30
Mã lớp học: 144916
Giáo viên hướng dẫn: PGS.TS Trần Đình Khang
Danh sách sinh viên thực hiện:
STT Họ và tên Mã sinh
viên
1 Lương Hoài Nam 20210623 Nam.LH210623@sis.hust.edu.vn
2 Bùi Thế Phong 20215445 Phong.BT215445@sis.hust.edu.vn
3 Đinh Trí Khoa 20215403 Khoa.DT215403@sis.hust.edu.vn
4 Nguyễn Long Nhật 20215440 Nhat.NL215440@sis.hust.edu.vn
5 Phan Hoàng Nam 20215434 Nam.PH215434@sis.hust.edu.vn
Hà Nội, tháng 12 năm 2023
Trang 2Mục lục
Mục lục 2
Mục lục hình ảnh 3
1 Mô tả bài toán: 4
2 Biểu diễn bài toán: 4
3 Phương pháp tìm kiếm: 8
4 Công cụ thực hiện: 12
5 Kết quả: 12
Trang 3Mục lục hình ảnh
Hình 1 Mô phỏng các trạng thái trên bản đồ 5
Hình 2 Đường đi trước khi cải tiến thuật toán 10
Hình 3 Đường đi sau khi cải tiến thuật toán 10
Hình 4 Minh họa kết quả bài toán - 1 11
Hình 5 Minh họa kết quả bài toán - 2 12
Hình 6 Minh họa kết quả bài toán – 3 12
Trang 41 Mô tả bài toán:
- Xét một mảnh bản đồ của phường Hàng Bồ, quận Hoàn Kiếm, Hà Nội Bài toán yêu cầu tìm đường đi giữa 2 điểm A và B bất kỳ và biểu diễn đường đi đó trên bản đồ
- Ràng buộc:
Chỉ được phép đi trên các tuyến đường, không được phép đi xuyên qua các công trình
Không được phép đi trên cùng một tuyến đường nhiều hơn 1 lần
2 Biểu diễn bài toán:
- Trạng thái bài toán: {(lat, lng)}, trong đó lat tương ứng với vĩ độ, lng tương ứng với kinh độ Các trạng thái này sẽ bao gồm tất cả các giao lộ trên mảnh bản đồ:
(21.033773176965717, 105.84793937443122),
(21.033731516947956, 105.84724726031048),
(21.033718239526593, 105.84698253583295),
(21.03429206772195, 105.8470029349314),
(21.034419745253814, 105.84700829934943),
(21.034364668684873, 105.84737844419348),
(21.034285582343745, 105.84803436032504),
(21.03488562345316, 105.84815472132074),
(21.035003286596158, 105.84750294453012),
(21.035610086660785, 105.84646070216799),
(21.03556502437502, 105.84705347036028),
(21.035504941306097, 105.84757381890917),
(21.035407306267413, 105.84823364232683),
(21.036165853731504, 105.84839189265871),
(21.036213419285374, 105.847724022614),
(21.036265991722, 105.84706688140535),
(21.033934999862513, 105.84989536671564)
Biểu diễn các trạng thái này trên mảnh bản đồ:
Trang 5Việc xác định trạng thái bài toán như vậy sẽ đảm bảo đường đi tìm được luôn thỏa mãn ràng buộc: “Chỉ được phép đi trên các tuyến đường, không được phép đi xuyên qua các công trình”
- Tập các hành động:
(21.033773176965717, 105.84793937443122) -> (21.033731516947956, 105.84724726031048)
(21.033773176965717, 105.84793937443122) -> (21.034285582343745, 105.84803436032504)
(21.033773176965717, 105.84793937443122) -> (21.033934999862513, 105.84989536671564)
(21.033731516947956, 105.84724726031048) -> (21.033718239526593, 105.84698253583295)
(21.033731516947956, 105.84724726031048) -> (21.034364668684873, 105.84737844419348)
(21.033731516947956, 105.84724726031048) -> (21.033773176965717, 105.84793937443122)
(21.033718239526593, 105.84698253583295) -> (21.033731516947956, 105.84724726031048)
Trang 6(21.033718239526593, 105.84698253583295) -> (21.03429206772195, 105.8470029349314)
(21.03429206772195, 105.8470029349314) -> (21.034419745253814, 105.84700829934943)
(21.03429206772195, 105.8470029349314) -> (21.033718239526593, 105.84698253583295)
(21.034419745253814, 105.84700829934943) -> (21.03429206772195, 105.8470029349314)
(21.034419745253814, 105.84700829934943) -> (21.034364668684873, 105.84737844419348)
(21.034419745253814, 105.84700829934943) -> (21.03556502437502, 105.84705347036028)
(21.034364668684873, 105.84737844419348) -> (21.034285582343745, 105.84803436032504)
(21.034364668684873, 105.84737844419348) -> (21.035003286596158, 105.84750294453012)
(21.034364668684873, 105.84737844419348) -> (21.034419745253814, 105.84700829934943)
(21.034364668684873, 105.84737844419348) -> (21.033731516947956, 105.84724726031048)
(21.034285582343745, 105.84803436032504) -> (21.033773176965717, 105.84793937443122)
(21.034285582343745, 105.84803436032504) -> (21.034364668684873, 105.84737844419348)
(21.034285582343745, 105.84803436032504) -> (21.03488562345316, 105.84815472132074)
(21.03488562345316, 105.84815472132074) -> (21.035003286596158, 105.84750294453012)
Trang 7(21.03488562345316, 105.84815472132074) -> (21.035407306267413, 105.84823364232683)
(21.03488562345316, 105.84815472132074) -> (21.034285582343745, 105.84803436032504)
(21.035003286596158, 105.84750294453012) -> (21.035504941306097, 105.84757381890917)
(21.035003286596158, 105.84750294453012) -> (21.03488562345316, 105.84815472132074)
(21.035003286596158, 105.84750294453012) -> (21.034364668684873, 105.84737844419348)
(21.035610086660785, 105.84646070216799) -> (21.03556502437502, 105.84705347036028)
(21.03556502437502, 105.84705347036028) -> (21.035610086660785, 105.84646070216799)
(21.03556502437502, 105.84705347036028) -> (21.036265991722, 105.84706688140535)
(21.03556502437502, 105.84705347036028) -> (21.035504941306097, 105.84757381890917)
(21.03556502437502, 105.84705347036028) -> (21.034419745253814, 105.84700829934943)
(21.035504941306097, 105.84757381890917) -> (21.035407306267413, 105.84823364232683)
(21.035504941306097, 105.84757381890917) -> (21.036213419285374, 105.847724022614)
(21.035504941306097, 105.84757381890917) -> (21.03556502437502, 105.84705347036028)
(21.035504941306097, 105.84757381890917) -> (21.035003286596158, 105.84750294453012)
Trang 8(21.035407306267413, 105.84823364232683) -> (21.036165853731504, 105.84839189265871)
(21.035407306267413, 105.84823364232683) -> (21.035504941306097, 105.84757381890917)
(21.035407306267413, 105.84823364232683) -> (21.03488562345316, 105.84815472132074)
(21.036165853731504, 105.84839189265871) -> (21.036213419285374, 105.847724022614)
(21.036165853731504, 105.84839189265871) -> (21.035407306267413, 105.84823364232683)
(21.036213419285374, 105.847724022614) -> (21.036265991722, 105.84706688140535)
(21.036213419285374, 105.847724022614) -> (21.035504941306097, 105.84757381890917)
(21.036213419285374, 105.847724022614) -> (21.036165853731504, 105.84839189265871)
(21.036265991722, 105.84706688140535) -> (21.036213419285374, 105.847724022614)
(21.036265991722, 105.84706688140535) -> (21.03556502437502, 105.84705347036028)
(21.033934999862513, 105.84989536671564) -> (21.033773176965717, 105.84793937443122)
Các hành động này tương ứng với việc di chuyển từ 1 giao lộ đến 1 trong các giao lộ liền kề
3 Phương pháp tìm kiếm:
Đầu vào bài toán: Người dùng click vào 2 điểm trên bản đồ
Đầu ra bài toán: Đường đi giữa 2 điểm đó
Phương pháp tìm kiếm:
Trang 9Bước 1: Xác định trạng thái đầu, trạng thái đích.
- Xác định trạng thái đầu:
+ Kiểm tra tất cả các cặp giao lộ kề nhau, chọn các cặp giao lộ mà điểm xuất phát nằm trên đoạn đường giới hạn bởi cặp giao lộ này
+ Trạng thái đầu sẽ là giao lộ gần nhất với điểm xuất phát trong các cặp giao
lộ tìm được
+ Nếu không tìm được cặp giao lộ thỏa mãn yêu cầu trên thì trạng thái đầu sẽ
là giao lộ gần nhất đối với điểm xuất phát
- Xác định trạng thái đích:
+ Kiểm tra tất cả các cặp giao lộ kề nhau, chọn các cặp giao lộ mà điểm kết thúc nằm trên đoạn đường giới hạn bởi cặp giao lộ này
+ Trạng thái đích sẽ là giao lộ gần nhất với điểm kết thúc trong các cặp giao
lộ tìm được
+ Nếu không tìm được cặp giao lộ thỏa mãn yêu cầu trên thì trạng thái đích
sẽ là giao lộ gần nhất đối với điểm kết thúc
Bước 2: Tìm đường đi từ trạng thái đầu đến trạng thái đích:
+ Sử dụng thuật toán A* với hàm đánh giá:
f(n) = g(n) + h(n)
Trong đó: g(n) là tổng khoảng cách đường đi thực tế từ trạng thái đầu đến trạng thái đang xét
h(n) là khoảng cách ước lượng (khoảng cách đường chim bay) từ trạng thái đang xét đến trạng thái đích, được tính theo công thức Haversine:
Giả sử trạng thái đích là (lat2, lng2), trạng thái hiện tại là (lat1, lng1), ta có: h(n) = 2 * 6731000 * arcsin(sqrt(sin²((π / 180) * (lat2 – lat1) / 2) + cos((π / 180) * lat1) * cos((π / 180) * lat2) * sin²((π / 180) * (lng2 – ln1) / 2))) + Mô tả chi tiết thuật toán:
o Lưu trữ và cập nhật liên tục 2 tập hợp Open và Close, trong đó Open lưu các trạng thái sẽ được xét, còn Close lưu các trạng thái đã được xét đến rồi
và sẽ không được xét lại Tập Open được khởi tạo với trạng thái đầu n , tập0
Close được khởi tạo rỗng
Trang 10o Lưu trữ 1 mảng d[n] là tổng khoảng cách đường đi thực tế từ trạng thái đầu đến trạng thái n, 1 mảng trace[n] là trạng thái ngay liền trước trạng thái n trong đường đi cuối cùng tìm được Khởi tạo d[n ] = 0, còn lại thì bằng inf.0
o Định nghĩa 1 hàm distance(n, n*) là khoảng cách giữa 2 trạng thái n và n*
o Khi tập Open vẫn còn chứa ít nhất 1 trạng thái, thực hiện liên tục các công việc sau:
Chọn trạng thái n có hàm đánh giá f(n) nhỏ nhất trong tập Open Xét các hành động từ trạng thái n sang 1 trạng thái n*, nếu n* không thuộc Close thì đưa n* vào Open
Cập nhật d[n*] = min(d[n*], d[n] + distance(n, n*)) và trace[n*] = n nếu d[n*] có sự thay đổi
Đưa n ra khỏi Open và đưa n vào Close
Nếu tập Open hoặc Close đã chứa trạng thái đích thì kết thúc tìm kiếm
o Dựa vào mảng trace[] đã được tính toán, ta có thể tìm được 1 đường đi từ trạng thái đầu đến trạng thái đích Thêm điểm xuất phát và điểm kết thúc do người dùng chọn vào đầu và cuối đường đi tìm được, ta đã có được 1 đường đi hoàn chỉnh giữa 2 điểm và đảm bảo việc không đi xuyên qua bất
cứ công trình nào
Bước 3: Cải tiến thuật toán:
- Tình huống: Giả sử A, B lần lượt là 2 điểm được người dùng lựa chọn Gọi n là0
trạng thái đầu, n là trạng thái tiếp theo,… Đường đi tìm được sẽ có dạng:1
A -> n -> n -> … -> n -> n -> B0 1 k-1 k
Nếu A nằm trên đoạn đường nối giữa n và n , thì đường đi tìm được sẽ vi0 1
phạm ràng buộc: “Không được phép đi trên cùng một tuyến đường nhiều hơn 1 lần”
- Hình ảnh minh họa cho trường hợp trên:
Trang 11- Giải pháp:
+ Kiểm tra xem A có nằm giữa n và n không, bằng cách so sánh tổng0 1
khoảng cách từ A đến n và khoảng cách từ A đến n , với khoảng cách từ n và n 0 1 0 1
Nếu 2 giá trị này xấp xỉ bằng nhau thì A nằm giữa n và n và ta cần phải loại bỏ n0 1 0
khỏi đường đi
+ Tương tự, ta cũng cần thực hiện cải tiến trên với các trạng thái cuối: nk-1, nk
và điểm kết thúc B Nếu B nằm giữa n và n thì ta cần loại bỏ n khỏi đường đi.k-1 k k
- Hình ảnh đường đi tìm được sau khi cải tiến thuật toán:
Trang 12Như vậy, sau khi thực hiện cải tiến, đường đi tìm được giữa A và B đã chắc chắn thỏa mãn tất cả các rang buộc Lưu ý rằng ta không cần kiểm tra đường đi giữa các trạng thái trung gian từ n đến n nhờ vào tính tối ưu của thuật toán A*.1 k-1
4 Công cụ thực hiện:
- Ngôn ngữ lập trình: JavaScript Đây là ngôn ngữ được hỗ trợ bởi API của Google Map: Maps JavaScript API
- Maps JavaScript API hỗ trợ hệ thống trong việc tạo một bản đồ có thể tương tác với người dùng, cụ thể các công việc mà API này hỗ trợ:
o Tạo một vùng giới hạn mảnh bản đồ của phường Hàng Bồ, dựa trên các tọa
độ được cung cấp Vùng giới hạn này được tô màu để người dùng nhận biết được những vị trí có thể tương tác được
o Tạo 1 marker với mỗi vị trí mà người sử dụng click lên bản đồ Vị trí xuất phát được đánh dấu màu đỏ, vị trí kết thúc được đánh dấu màu xanh
o Mô phỏng đường đi trên bản đồ bằng cách tạo đường thẳng nối các điểm trên đường đi với nhau Khi người dùng di chuột vào đường đi, có thể hiển thị độ dài của đường đi đó (độ dài đường đi được tính toán trước)
5 Kết quả:
- Hình ảnh minh họa kết quả bài toán:
Trang 13Hình 5 Minh họa kết quả bài toán - 2
Trang 14- Địa chỉ trang web: https://naml03.github.io/Map-Project/
- Link github: https://github.com/namL03/Map-Project