Luận văn tập trung nghiên cứu và giải quyết một bài toán định tuyến xe (Vehicle Routing ProblemVRP) thực tế, bắt nguồn từ nhu cầu cải tiến hoạt động điều phối các xe giao hàng của công ty sữa Abbott Nutrition Việt Nam (Abbott), với mục đích đề ra là giảm 15% chi phí vận tải cho công ty. Bài toán vận tải của công ty là một dạng kết hợp của nhiều biến thể của bài toán VRP với những đặc điểm đặc trưng như: Có một kho hàng Đồ thị biểu diễn đường đi là đồ thị bất đối xứng. Đội xe có nhiều loại phương tiện có sức chứa khác nhau Cho phép xe thực hiện nhiều chuyển trong một ngày. Điểm giao hàng có ràng buộc loại xe được phép đến giao hàng Để giải quyết bài toán này, luận văn sử dụng Phần mềm Visual Studio Code với sự hỗ trợ của công cụ giải ORTools viết bằng ngôn ngữ lập trình Python dựa trên “giải thuật tiết kiệm”. Giải thuật được thử nghiệm trên 24 bộ dữ liệu thực tế trong tháng 92019, kết quả sau đó được so sánh với kết quả khi sử dụng giải thuật mô phỏng tôi luyện và kết quả điều phối thực tế từ công ty.
ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC BÁCH KHOA -o0o - LUẬN VĂN TỐT NGHIỆP CẢI THIỆN LỘ TRÌNH VẬN CHUYỂN CHO MỘT CÔNG TY PHÂN PHỐI SỮA SVTH: NGUYỄN THỊ TƯỜNG VY MSLV: ISE-16-49 Thành Phố Hồ Chí Minh, tháng 07 năm 2020 BỘ GIÁO DỤC VÀ ĐÀO TẠO CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM ĐHQG TP.HCM – TRƯỜNG ĐH BÁCH KHOA Độc lập – Tự – Hạnh phúc KHOA CƠ KHÍ BỘ MƠN KỸ THUẬT HỆ THỐNG CÔNG NGHIỆP NHIỆM VỤ LUẬN VĂN TỐT NGHIỆP Họ tên: NGUYỄN THỊ TƯỜNG VY Đầu đề luận văn: Cải thiện lộ trình vận chuyển cho công ty phân phối sữa Nhiệm vụ: - Tìm hiểu tổng quan hoạt điều phối xe cơng ty, từ xác định tốn phù hợp Mơ hình hóa tốn thực tế cơng ty Xây dựng chương trình giải tốn điều phối xe Đánh giá hiệu chương trình so với kết điều phối Ngày giao nhiệm vụ luận văn: 30/03/2020 Ngày hoàn thành nhiệm vụ: 22/07/2020 Họ tên người hướng dẫn: Phần hướng dẫn TS Phan Thị Mai Hà Toàn phần Nội dung yêu cầu LVTN thông qua Bộ môn Ngày _tháng _năm _ CHỦ NHIỆM BỘ MÔN NGƯỜI HƯỚNG DẪN CHÍNH _ PHẦN DÀNH CHO KHOA, BỘ MÔN: Người duyệt (chấm sơ bộ): Đơn vị: Ngày bảo vệ: _ Điểm tổng kết: Nơi lưu trữ luận văn: LỜI CẢM ƠN Luận văn “Cải thiện lộ trình vận chuyển cho cơng ty phân phối sữa” hồn thành với giúp đỡ tận tình thầy giáo Bộ môn Kỹ Thuật Hệ thống Công nghiệp, trường Đại học Bách Khoa - Đại học Quốc gia TP Hồ Chí Minh, động viên từ gia đình, bạn bè nỗ lực thân suốt trình học tập thực luận văn Đầu tiên, em xin gửi lời cảm ơn chân thành đến Phan Thị Mai Hà, người có định hướng giúp em hoàn thành luận văn tốt nghiệp Trong suốt thời gian thực tận tình dẫn, giúp đỡ cung cấp cho em kiến thức, tài liệu cần thiết để hoàn thành luận văn Xin gửi lời cảm ơn đến anh chị công ty Abbott nhiệt tình giúp đỡ, tạo điều kiện thuận lợi cho em suốt trình học tập làm việc công ty Cuối cùng, em xin gửi lời cảm ơn tới gia đình, bạn bè tin tưởng, giúp đỡ, động viên em suốt trình làm luận văn tốt nghiệp Do thời gian kiến thức có hạn chắn luận văn tránh khỏi thiếu sót, hạn chế Kính mong nhận bảo góp ý q Thầy, Cơ Xin chúc người ln mạnh khỏe, đạt nhiều thành tích công tác, học tập nghiên cứu khoa học Em xin chân thành cảm ơn! Tp Hồ Chí Minh, tháng năm 2020 Sinh viên thực TÓM TẮT LUẬN VĂN Luận văn tập trung nghiên cứu giải toán định tuyến xe (Vehicle Routing Problem-VRP) thực tế, bắt nguồn từ nhu cầu cải tiến hoạt động điều phối xe giao hàng công ty sữa Abbott Nutrition Việt Nam (Abbott), với mục đích đề giảm 15% chi phí vận tải cho cơng ty Bài tốn vận tải cơng ty dạng kết hợp nhiều biến thể toán VRP với đặc điểm đặc trưng như: - Có kho hàng - Đồ thị biểu diễn đường đồ thị bất đối xứng - Đội xe có nhiều loại phương tiện có sức chứa khác - Cho phép xe thực nhiều chuyển ngày - Điểm giao hàng có ràng buộc loại xe phép đến giao hàng Để giải toán này, luận văn sử dụng Phần mềm Visual Studio Code với hỗ trợ công cụ giải OR-Tools viết ngơn ngữ lập trình Python dựa “giải thuật tiết kiệm” Giải thuật thử nghiệm 24 liệu thực tế tháng 9/2019, kết sau so sánh với kết sử dụng giải thuật mô luyện kết điều phối thực tế từ công ty Kết thu cho thấy “giải thuật tiết kiệm” cho kết tốt giải thuật mô luyện 14/24 liệu, đồng thời kết từ “giải thuật tiết kiệm” cho chi phí vận tải thấp tất liệu so với kết điều phối thực tế, giúp giảm 17.56 % chi phí vận tải, hồn tồn đáp ứng mục đích đặt ban đầu MỤC LỤC TRANG BÌA NHIỆM VỤ LUẬN VĂN TỐT NGHIỆP .ii LỜI CẢM ƠN iii TÓM TẮT LUẬN VĂN iv DANH MỤC HÌNH ẢNH .vii DANH MỤC BẢNG BIỂU viii DANH MỤC CÁC TỪ VIẾT TẮT .ix Chương GIỚI THIỆU 1.1 Lý thực đề tài 1.2 Mục đích mục tiêu đề tài .2 1.3 Phạm vi đối tương nghiên cứu 1.4 Cấu trúc luận văn .2 Chương CƠ SỞ LÝ THUYẾT VÀ PHƯƠNG PHÁP LUẬN 2.1 Cơ sở lý thuyết 2.1.1 Khái niệm mơ hình hóa [1] .4 2.1.2 Tổng quan toán VRP 2.1.3 Bài toán VRP với nhiều chuyến (Vehicle routing problem with multiple tripsVRPMT) 2.1.4 Giải thuật tiết kiệm 10 2.1.5 Giải thuật mô luyện 11 2.1.6 Các công cụ hỗ trợ 11 2.2 Phương pháp luận 13 Chương PHÂN TÍCH HIỆN TRẠNG VÀ XÁC ĐỊNH VẤN ĐỀ 15 3.1 Giới thiệu đối tượng nghiên cứu 15 3.1.1 Giới thiệu chung .15 3.1.2 Sản phẩm dinh dưỡng Abbott Việt Nam .15 3.1.3 Cơ cấu tổ chức công ty 16 3.2 Tổng quan phận vận tải 17 3.2.1 Kho hàng 17 3.2.2 Khách hàng .17 3.2.3 Hàng hóa 17 3.2.4 Đội xe .17 3.2.5 Quy trình vận hành 18 3.2.6 3.3 Yêu cầu, ràng buộc giao hàng .20 Phân tích trạng .20 3.3.1 Trong thuê xe 20 3.3.2 Trong vận hành thực tế 23 3.4 Phân tích nguyên nhân gây rớt đơn vận hành 24 Chương XÂY DỰNG MƠ HÌNH BÀI TỐN 28 4.1 Mơ hình tốn gốc .28 4.2 Xây dựng mơ hình tốn cơng ty 30 4.2.1 Khái quát 30 4.2.2 Thiết lập mô hình 31 4.3 Giải mơ hình 33 4.3.1 Dữ liệu đầu vào 33 4.3.2 Tính tốn tham số .37 4.3.3 Giải mơ hình 40 Chương KIỂM TRA VÀ ĐÁNH GIÁ KẾT QUẢ 47 5.1 Kiểm tra kết .47 5.2 Đánh giá kết 50 Chương KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN 55 6.1 Kết luận 55 6.2 Hướng phát triển 55 TÀI LIỆU THAM KHẢO PHỤ LỤC A: BẢNG BIỂU A1 PHỤ LỤC B: CODE LẬP TRÌNH B1 DANH MỤC HÌNH ẢNH Hình 2.1 Giải pháp hoạch định tuyến đường cho 15 điểm giao hàng với xe .5 Hình 2.2 Biểu đồ thể mối quan hệ loại VRP Hình 2.3 Phương pháp luận 14 Hình 3.1 Một số sản phẩm công ty Abbott Việt Nam .16 Hình 3.2 Cơ cấu tổ chức 16 Hình 3.3 Quy trình vận hành 19 Hình 3.4 Biểu đồ nguyên nhân việc giao hàng trễ .25 Hình 4.1 Kết phân chuyến 46 Hình 5.1 Kết sử dụng xe tăng cường 54 DANH MỤC BẢNG BIỂU Bảng 3.1 Thơng tin nhóm xe, loại xe 18 Bảng 3.2 Hiện trạng sử dụng xe tháng 9/2019 21 Bảng 3.3 Chi phí thuê xe .22 Bảng 3.4 Thống kê số lượng đơn hàng rớt tháng 9/2019 24 Bảng 3.5 Lý giải nguyên nhân gây giao hàng trễ 25 Bảng 3.6 Thống kê kết thu nhập 27 Bảng 4.1 Danh sách đơn hàng ngày 3/9/2019 .33 Bảng 4.2 Dữ liệu kho 34 Bảng 4.3 Danh sách cửa hàng .34 Bảng 4.4 Dữ liệu xe .36 Bảng 4.5 Ma trận khoảng cách nút i nút j .37 Bảng 4.6 Ma trận thời gian di chuyển nút i nút j 38 Bảng 4.7 Kết phân chuyến 45 Bảng 5.1 Kiểm tra tải trọng, thời gian, khoảng cách 47 Bảng 5.2 Kiểm tra ràng buộc .49 Bảng 5.3 Kết thực nghiệm 50 Bảng 5.4 Kết sử dụng xe53 DANH MỤC CÁC TỪ VIẾT TẮT STT Từ viết tắt Tên tiếng Anh Ý nghĩa AVRP Asymmetric VRP Bài toán VRP với khoảng cách bất đối xứng CVRP Capacitated Constrained VRP Bài toán VRP với ràng buộc sức chứa DVRP Distance-Constrained VRP Bài toán VRP với ràng buộc độ dài tối đa quãng đường mà xe phép MDVRP Multi-Depot VRP Bài toán VRP với nhiều kho hàng MOVRP Multi Objective VRP Bài toán VRP đa mục tiêu FMEA Failure Modes and Effects Analysis phương pháp phân tích phương thức xảy sai lỗi ảnh hưởng SA Simulated Annealing Thuật tốn mơ luyện kim SDVRP VRP with sitedependent Bài toán VRP với yêu cầu loại xe phù hợp RPN Risk Priority Number Rủi so ưu tiên số 10 VRP Vehicle Routing Problem Bài toán định tuyến xe hàng 11 VRPB VRP with Backhauls Bài toán VRP nhập xuất hàng kết hợp 12 VRPPD VRP with Pickup and Delivery Bài toán VRP nhập xuất hàng đồng thời 13 VRPMT VRP with multiple trips Bài toán VRP cho phép xe nhiều chuyến 14 VRPTW VRP with Time Windows Bài toán VRP với cửa sổ thời gian Chương GIỚI THIỆU Chương giới thiệu lý lựa chọn đề tài, mục tiêu nghiên cứu, đối tượng, phạm vi giới hạn đề tài tổng quan cấu trúc luận văn, nhằm giúp người đọc có nhìn tổng quan nghiên cứu 1.1 Lý thực đề tài Trong năm gần đây, toán định tuyến xe (Vehicle Routing Problem-VRP) thu hút nhiều ý quan tâm ngày tăng giải pháp vận tải công nghệ khác việc sử dụng chúng hậu cần vận chuyển Ngày có nhiều cơng ty cố gắng tổ chức việc giao hàng tốt cách sử dụng giải pháp công nghệ đề xuất Mỗi tốn VRP thực tế thường có ràng buộc đặc trưng riêng, nhìn chung tất tốn NP-khó Đề tài tập trung nghiên cứu giải toán VRP thực tế, bắt nguồn từ nhu cầu cải tiến hoạt động điều phối xe giao hàng công ty sữa Abbott Nutrition Việt Nam (Abbott), sở Tp Hồ Chí Minh Hiện nay, Abbott thực việc điều phối xe giao hàng tay với quy trình sau: Hàng ngày, kho R1_HCM công ty Abbott thực việc điều phối hàng hóa cho khoảng trăm cửa hàng thành phố Vì số lượng đơn hàng lớn, địa điểm giao thay đổi ngày, với yêu cầu ràng buộc khác đặt trình giao hàng, nên hàng ngày phải tốn nhiều thời gian cho việc xếp đơn hàng, khó đảm bảo phương tiện sử dụng hợp lý, tuyến đường giao hàng ngắn, … dẫn đến chi phí vận tải cao Bên cạnh việc để đáp ứng nhu cầu ngày cao, số lượng cửa hàng ngày tăng mà đạt tin tưởng khách hàng thông qua việc đáp ứng tốt nhu cầu yếu tố vơ quan trọng Do đó, cơng ty Abbott có nhu cầu cải thiện hoạt động điều phối vận chuyển hàng hóa kho hàng R1_HCM Đó lý hình thành đề tài “Cải thiện lộ trình vận chuyển cho công ty phân phối sữa”, với mong muốn áp dụng kiến thức nghiên cứu vào mơi trường doanh nghiệp Từ góp phần vào phát triển công ty thông qua việc giảm thiểu chi phí vận tải Ngồi ra, việc tổ chức điều phối tuyến đường tốt ảnh hưởng đến khía cạnh sinh thái cách làm giảm ô nhiễm, vấn đề quan trọng cần quan tâm Load(430) Time(3.236) -> 107299 Load(440) Time(3.708) -> 107046 Load(480) Time(4.223) -> R1_HCM Load(0) Time(4.963) -> 107304 Load(20) Time(5.479) -> 107274 Load(80) Time(5.83) -> 107290 Load(180) Time(6.08) -> 107175 Load(190) Time(6.563) -> 107253 Load(250) Time(6.973) -> 107058 Load(290) Time(7.466) -> R1_HCM Load(290) Time(7.852) Distance of the route: 52421 m Route for vehicle - 500: R1_HCM Load(0) Time(0.0) -> 107270 Load(40) Time(0.516) -> 107295 Load(110) Time(0.949) -> R1_HCM Load(0) Time(1.401) -> 107035 Load(70) Time(1.832) -> 107000 Load(120) Time(2.236) -> 107066 Load(140) Time(2.599) -> 107298 Load(170) Time(3.099) -> 107125 Load(280) Time(3.424) -> 107220 Load(300) Time(3.87) -> 107221 Load(330) Time(4.12) -> 107148 Load(370) Time(4.5) -> 107031 Load(380) Time(4.891) -> 107052 Load(390) Time(5.426) -> 107276 Load(430) Time(5.805) -> 107275 Load(490) Time(6.055) -> R1_HCM Load(490) Time(6.589) Distance of the route: 30567 m Route for vehicle - 1500: R1_HCM Load(0) Time(0.0) -> 107140 Load(110) Time(0.399) -> 107167 Load(120) Time(1.086) -> 107225 Load(520) Time(1.637) -> 107141 Load(780) Time(2.101) -> 107142 Load(1460) Time(2.415) -> 107160 Load(1480) Time(3.031) -> 107164 Load(1490) Time(3.284) -> R1_HCM Load(0) Time(4.058) -> 107069 Load(460) Time(4.607) -> 107248 Load(600) Time(4.959) -> 107151 Load(670) Time(5.588) -> 107076 Load(850) Time(5.838) -> 107150 Load(1070) Time(6.088) -> R1_HCM Load(1070) Time(6.492) Distance of the route: 35292 m Route for vehicle - 1500: R1_HCM Load(0) Time(0.0) -> 107079 Load(540) Time(0.837) -> 107254 Load(840) Time(1.572) -> 107038 Load(980) Time(2.252) -> 107223 Load(1200) Time(2.691) -> 107030 Load(1210) Time(3.022) -> 107117 Load(1220) Time(3.272) -> 107226 Load(1230) Time(3.679) -> R1_HCM Load(0) Time(4.235) -> 107010 Load(50) Time(4.782) -> 107227 Load(180) Time(5.144) -> 107024 Load(350) Time(5.425) -> R1_HCM Load(0) Time(6.071) -> 107289 Load(60) Time(6.423) -> 107287 Load(1140) Time(6.673) -> 107288 Load(1360) Time(6.923) -> R1_HCM Load(1360) Time(7.272) Distance of the route: 46496 m Route for vehicle - 1700: R1_HCM Load(0) Time(0.0) -> 107249 Load(80) Time(0.404) -> 107170 Load(110) Time(1.071) -> 107071 Load(720) Time(1.419) -> 107080 Load(1010) Time(1.969) -> 107323 Load(1250) Time(2.469) -> 107260 Load(1700) Time(2.799) -> R1_HCM Load(0) Time(3.556) -> 107152 Load(20) Time(3.955) -> 107263 Load(280) Time(4.205) -> 107139 Load(520) Time(4.455) -> 107222 Load(820) Time(5.051) -> 107130 Load(950) Time(5.344) -> 107165 Load(970) Time(5.818) -> 107250 Load(1030) Time(6.104) -> 107262 Load(1100) Time(6.465) -> R1_HCM Load(1100) Time(6.873) Distance of the route: 35200 m Route for vehicle 10 - 1700: R1_HCM Load(0) Time(0.0) -> 107055 Load(20) Time(0.429) -> 107002 Load(70) Time(0.739) -> 107003 Load(90) Time(0.989) -> 107004 Load(160) Time(1.239) -> 107325 Load(300) Time(1.771) -> 107219 Load(490) Time(2.044) -> 107259 Load(1420) Time(2.548) -> 107153 Load(1430) Time(3.043) -> 107057 Load(1450) Time(3.414) -> 107015 Load(1460) Time(3.664) -> 107261 Load(1550) Time(4.05) -> R1_HCM Load(0) Time(4.458) -> 107077 Load(1560) Time(5.007) -> R1_HCM Load(1560) Time(5.569) Distance of the route: 23209 m Total vehicles used: Total cost: 2671044 VND Ngày 6/9 Route for vehicle - 80: R1_HCM Load(0) Time(0.0) -> 107367 Load(10) Time(0.478) -> 107378 Load(20) Time(1.085) -> 107374 Load(30) Time(1.341) -> 107420 Load(40) Time(1.639) -> 107488 Load(50) Time(2.074) -> 107399 Load(60) Time(2.574) -> 107542 Load(70) Time(2.854) -> 107337 Load(80) Time(3.517) -> R1_HCM Load(80) Time(3.959) Distance of the route: 23175 m Route for vehicle - 500: R1_HCM Load(0) Time(0.0) -> 107365 Load(10) Time(0.566) -> 107533 Load(40) Time(1.143) -> 107566 Load(70) Time(1.565) -> 107502 Load(140) Time(2.212) -> 107639 Load(200) Time(2.675) -> 107640 Load(230) Time(3.165) -> 107628 Load(300) Time(3.643) -> 107402 Load(340) Time(4.024) -> 107496 Load(350) Time(4.522) -> 107493 Load(470) Time(4.772) -> 107424 Load(480) Time(5.192) -> R1_HCM Load(480) Time(5.589) Distance of the route: 38646 m Route for vehicle - 1500: R1_HCM Load(0) Time(0.0) -> 107590 Load(180) Time(0.352) -> 107514 Load(190) Time(0.662) -> 107406 Load(200) Time(1.186) -> 107426 Load(300) Time(1.642) -> 107391 Load(440) Time(2.257) -> 107479 Load(650) Time(2.929) -> 107484 Load(950) Time(3.231) -> 107416 Load(980) Time(3.567) -> 107609 Load(1460) Time(3.939) -> 107537 Load(1480) Time(4.398) -> R1_HCM Load(1480) Time(4.806) Distance of the route: 26471 m Route for vehicle - 1500: A15 R1_HCM Load(0) Time(0.0) -> 107603 Load(240) Time(0.984) -> 107390 Load(270) Time(1.578) -> 107389 Load(380) Time(1.828) -> 107615 Load(410) Time(2.385) -> 107498 Load(520) Time(2.642) -> 107584 Load(630) Time(3.135) -> 107585 Load(930) Time(3.385) -> 107366 Load(940) Time(3.802) -> 107610 Load(980) Time(4.09) -> 107400 Load(990) Time(4.551) -> 107578 Load(1100) Time(5.015) -> 107330 Load(1130) Time(5.265) -> 107482 Load(1190) Time(5.756) -> 107621 Load(1330) Time(6.032) -> 107571 Load(1440) Time(6.339) -> R1_HCM Load(1440) Time(6.841) Distance of the route: 39751 m Route for vehicle - 1700: R1_HCM Load(0) Time(0.0) -> 107333 Load(10) Time(0.401) -> 107521 Load(20) Time(0.73) -> 107535 Load(70) Time(1.067) -> 107385 Load(120) Time(1.327) -> 107386 Load(160) Time(1.577) -> 107412 Load(220) Time(1.827) -> 107577 Load(260) Time(2.078) -> 107568 Load(310) Time(2.471) -> 107541 Load(440) Time(2.856) -> 107567 Load(650) Time(3.335) -> 107618 Load(710) Time(3.765) -> 107425 Load(860) Time(4.214) -> 107495 Load(1080) Time(4.699) -> 107494 Load(1280) Time(4.949) -> 107593 Load(1290) Time(5.312) -> 107522 Load(1300) Time(5.795) -> 107532 Load(1330) Time(6.091) -> R1_HCM Load(1330) Time(6.59) Distance of the route: 24906 m Route for vehicle 10 - 1700: R1_HCM Load(0) Time(0.0) -> 107579 Load(20) Time(0.399) -> 107524 Load(40) Time(0.679) -> 107364 Load(50) Time(0.956) -> 107483 Load(310) Time(1.577) -> 107619 Load(420) Time(1.931) -> 107620 Load(430) Time(2.321) -> 107622 Load(440) Time(2.662) -> 107588 Load(530) Time(3.018) -> 107586 Load(570) Time(3.268) -> 107587 Load(590) Time(3.518) -> 107576 Load(610) Time(4.044) -> 107595 Load(620) Time(4.294) -> 107575 Load(690) Time(4.544) -> 107611 Load(760) Time(5.075) -> 107598 Load(840) Time(5.325) -> 107635 Load(1080) Time(5.876) -> 107634 Load(1320) Time(6.126) -> 107633 Load(1370) Time(6.376) -> 107332 Load(1420) Time(6.769) -> R1_HCM Load(1420) Time(7.405) Distance of the route: 27200 m Total vehicles used: Total cost: 2152301 VND Ngày 7/9 Route for vehicle - 80: R1_HCM Load(0) Time(0.0) -> 23929 Load(40) Time(1.144) -> 111481 Load(48) Time(2.09) -> 23921 Load(58) Time(2.669) -> 23866 Load(68) Time(3.371) -> 23948 Load(78) Time(4.079) -> R1_HCM Load(0) Time(4.698) -> 23968 Load(80) Time(5.543) -> R1_HCM Load(80) Time(6.351) Distance of the route: 60013 m Route for vehicle - 500: R1_HCM Load(0) Time(0.0) -> 23934 Load(150) Time(0.567) -> R1_HCM Load(0) Time(1.136) -> 23957 Load(200) Time(1.567) -> 23956 Load(215) Time(1.817) -> R1_HCM Load(0) Time(2.249) -> 23935 Load(20) Time(2.778) -> 111477 Load(43) Time(3.166) -> 111478 Load(54) Time(3.416) -> 23961 Load(104) Time(3.738) -> 23962 Load(114) Time(3.988) -> 111454 Load(135) Time(4.238) -> 23958 Load(215) Time(4.689) -> 23960 Load(265) Time(4.942) -> 23910 Load(335) Time(5.228) -> 23965 Load(435) Time(5.697) -> 23964 Load(455) Time(6.256) -> 23967 Load(495) Time(6.844) -> R1_HCM Load(495) Time(7.348) Distance of the route: 38109 m Route for vehicle - 500: R1_HCM Load(0) Time(0.0) -> 23941 Load(10) Time(0.534) -> 23946 Load(20) Time(0.938) -> 23945 Load(30) Time(1.366) -> 111453 Load(49) Time(1.627) -> 23970 Load(119) Time(2.213) -> 23936 Load(219) Time(2.704) -> 23959 Load(269) Time(3.085) -> 23870 Load(279) Time(3.52) -> 23917 Load(429) Time(4.695) -> 23953 Load(449) Time(5.851) -> 23943 Load(469) Time(6.488) -> R1_HCM Load(469) Time(6.977) Distance of the route: 80241 m Route for vehicle - 1500: R1_HCM Load(0) Time(0.0) -> 23868 Load(100) Time(0.458) -> 23867 Load(120) Time(0.708) -> 23919 Load(150) Time(1.468) -> 23954 Load(160) Time(1.976) -> 23860 Load(300) Time(2.432) -> 111724 Load(424) Time(2.682) -> 23861 Load(514) Time(2.932) -> 23859 Load(554) Time(3.182) -> 23925 Load(594) Time(3.478) -> 111722 Load(670) Time(3.728) -> 23914 Load(710) Time(3.978) -> 23913 Load(750) Time(4.237) -> 23915 Load(760) Time(4.497) -> 23858 Load(960) Time(5.046) -> 23911 Load(1140) Time(5.576) -> 23864 Load(1200) Time(5.976) -> R1_HCM Load(1200) Time(6.484) Distance of the route: 27329 m Route for vehicle - 1500: R1_HCM Load(0) Time(0.0) -> 111464 Load(4) Time(0.52) -> 111594 Load(104) Time(0.78) -> 23966 Load(154) Time(1.172) -> 23862 Load(194) Time(1.503) -> 23923 Load(344) Time(1.896) -> 23928 Load(444) Time(2.284) -> 111487 Load(506) Time(2.673) -> 23857 Load(646) Time(3.175) -> 111723 Load(708) Time(3.425) -> 23924 Load(808) Time(3.725) -> 111721 Load(823) Time(4.096) -> 23926 Load(1183) Time(4.439) -> 23938 Load(1203) Time(4.707) -> 23931 Load(1303) Time(5.241) -> 23949 Load(1373) Time(5.743) -> R1_HCM Load(1373) Time(6.334) Distance of the route: 30102 m Route for vehicle - 1700: R1_HCM Load(0) Time(0.0) -> 23952 Load(20) Time(0.612) -> 23873 Load(70) Time(0.929) -> 23874 Load(80) Time(1.179) -> 23916 Load(180) Time(2.334) -> 23927 Load(280) Time(3.247) -> 111479 Load(318) Time(3.979) -> 23872 Load(348) A16 Time(4.466) -> 23942 Load(358) Time(4.801) -> 111459 Load(359) Time(5.242) -> 23912 Load(399) Time(5.492) -> 23863 Load(919) Time(5.971) -> 111465 Load(1429) Time(6.366) -> R1_HCM Load(1429) Time(6.714) Distance of the route: 60823 m Route for vehicle 10 - 1700: R1_HCM Load(0) Time(0.0) -> 111725 Load(749) Time(0.593) -> 23922 Load(1099) Time(0.964) -> 111589 Load(1113) Time(1.382) -> 23950 Load(1133) Time(1.926) -> 23944 Load(1163) Time(2.188) -> 23930 Load(1183) Time(2.531) -> 23939 Load(1193) Time(2.924) -> 23951 Load(1213) Time(3.274) -> 23865 Load(1273) Time(3.604) -> 23869 Load(1393) Time(4.349) -> 23940 Load(1563) Time(5.088) -> 111455 Load(1586) Time(5.513) -> 23871 Load(1596) Time(5.763) -> 23937 Load(1606) Time(6.35) -> R1_HCM Load(1606) Time(6.711) Distance of the route: 42233 m Total vehicles used: Total cost: 2555881 VND Ngày 9/9 Route for vehicle - 80: R1_HCM Load(0) Time(0.0) -> 108384 Load(8.6) Time(0.391) -> R1_HCM Load(0) Time(0.813) -> 108383 Load(17.0) Time(1.219) -> R1_HCM Load(0) Time(1.63) -> 108357 Load(24.0) Time(2.328) -> 108295 Load(59.0) Time(2.651) -> R1_HCM Load(0) Time(3.316) -> 108397 Load(5.0) Time(3.836) -> 108374 Load(27.0) Time(4.356) -> 108386 Load(41.0) Time(4.947) -> 108332 Load(45.0) Time(5.284) -> 108371 Load(60.0) Time(5.764) -> 108297 Load(74.0) Time(6.306) -> R1_HCM Load(74.0) Time(6.844) Distance of the route: 41381 m Route for vehicle - 80: R1_HCM Load(0) Time(0.0) -> 108422 Load(24.0) Time(0.718) -> 108423 Load(54.0) Time(0.968) -> 108439 Load(69.0) Time(1.218) -> 108402 Load(77.0) Time(1.823) -> R1_HCM Load(77.0) Time(2.41) Distance of the route: 15335 m Route for vehicle - 500: R1_HCM Load(0) Time(0.0) -> 108150 Load(11.0) Time(0.806) -> 108147 Load(178.0) Time(1.432) -> 108300 Load(180.0) Time(2.079) -> 108404 Load(250.0) Time(2.541) -> 108448 Load(313.0) Time(3.082) -> 108350 Load(337.0) Time(3.56) -> 108349 Load(372.0) Time(3.81) -> 108392 Load(421.0) Time(4.313) -> 108380 Load(463.0) Time(4.579) -> 108388 Load(477.0) Time(5.043) -> 108367 Load(485.0) Time(5.688) -> R1_HCM Load(0) Time(6.238) -> 108437 Load(155.0) Time(6.605) -> 108319 Load(431.0) Time(7.033) -> 108391 Load(466.0) Time(7.413) -> R1_HCM Load(466.0) Time(7.855) Distance of the route: 48173 m Route for vehicle - 500: R1_HCM Load(0) Time(0.0) -> 108376 Load(14.0) Time(0.578) -> 108408 Load(22.0) Time(0.832) -> 108395 Load(36.0) Time(1.108) -> 108294 Load(90.0) Time(1.534) -> 108310 Load(160.0) Time(1.91) -> 108299 Load(195.0) Time(2.423) -> 108438 Load(241.0) Time(2.766) -> 108417 Load(250.0) Time(3.196) -> 108149 Load(431.0) Time(3.576) -> 108442 Load(474.0) Time(4.212) -> R1_HCM Load(0) Time(4.673) -> 108348 Load(21.0) Time(5.232) -> 108329 Load(139.0) Time(5.482) -> 108445 Load(197.0) Time(5.867) -> 108421 Load(399.0) Time(6.369) -> 108365 Load(407.0) Time(6.887) -> 108146 Load(472.0) Time(7.28) -> R1_HCM Load(472.0) Time(7.786) Distance of the route: 45535 m Route for vehicle - 1500: R1_HCM Load(0) Time(0.0) -> 108322 Load(72.0) Time(0.399) -> 108436 Load(221.0) Time(1.032) -> 108337 Load(1241.0) Time(1.282) -> 108358 Load(1260.0) Time(1.751) -> 108440 Load(1349.0) Time(2.134) -> 108441 Load(1427.0) Time(2.553) -> 108360 Load(1457.0) Time(2.941) -> 108324 Load(1478.0) Time(3.334) -> R1_HCM Load(0) Time(3.743) -> 108145 Load(34.0) Time(4.253) -> 108144 Load(174.0) Time(4.503) -> 108328 Load(180.0) Time(4.944) -> 108425 Load(384.0) Time(5.194) -> 108424 Load(502.0) Time(5.444) -> 108335 Load(718.0) Time(6.16) -> 108340 Load(1228.0) Time(6.64) -> R1_HCM Load(1228.0) Time(7.149) Distance of the route: 34800 m Route for vehicle 10 - 1700: R1_HCM Load(0) Time(0.0) -> 108323 Load(355.0) Time(0.399) -> 108325 Load(709.0) Time(0.649) -> 108345 Load(952.0) Time(1.296) -> 108407 Load(974.0) Time(1.661) -> 108298 Load(1010.0) Time(2.049) -> 108370 Load(1031.0) Time(2.434) -> 108301 Load(1101.0) Time(2.813) -> 108396 Load(1241.0) Time(3.065) -> 108151 Load(1631.0) Time(3.724) -> 108414 Load(1682.0) Time(4.065) -> R1_HCM Load(0) Time(4.63) -> 108434 Load(166.0) Time(4.982) -> 108352 Load(181.0) Time(5.232) -> R1_HCM Load(181.0) Time(5.581) Distance of the route: 26225 m Total vehicles used: Total cost: 1779192 VND A17 PHỤ LỤC B: CODE LẬP TRÌNH Phụ lục B1: Code Python dử dụng để tính ma trận khoảng cách, thời gian import requests import numpy as np import pandas as pd import json def get_route(origin_location, destination_location): request_url = f'https://router.hereapi.com/v8/routes? transportMode=truck&origin={origin_location[0]}, {origin_location[1]}&destination={destination_location[0]}, {destination_location[1]}&return=summary&apikey=_MJgzQXKgDXGYJ40g6rUAN39ddZZxdpnqkxcxYby WFE' responses = requests.get(request_url) responses = responses.json() print(responses) distance = responses['routes'][0]['sections'][0]['summary']['length'] time = responses['routes'][0]['sections'][0]['summary']['duration'] return distance, time def input_processing(): cusinput = pd.read_excel('./input/CUS.xlsx', index_col = 0) orderinput = pd.read_excel('./input/ORDER1.xlsx', index_col = 0) vehicleinput = pd.read_excel('./input/VEHICLE.xlsx', index_col = 0) vehicle_capacities = list(vehicleinput.iloc[:]['Trọng tải']) km_costs = list(vehicleinput.iloc[:]['Chi phí xăng dầu']) man_costs = list(vehicleinput.iloc[:]['Chi phí nhân viên']) num_vehicles = len(vehicle_capacities) B1 order_code = [cusinput.iloc[0]['Mã cửa hàng']] order_code.extend([cusinput.iloc[0]['Mã cửa hàng']] * 20) order_code.extend(list(orderinput.iloc[:]['Mã đơn hàng'])) order_demand = [0] order_demand.extend([-max(vehicle_capacities)] * 20) order_demand.extend(list(orderinput.iloc[:]['Khối lượng'])) num_locations = len(order_code) distance_matrix = np.zeros((num_locations, num_locations), dtype = int) time_matrix = np.zeros((num_locations, num_locations), dtype = int) for r in range(num_locations): for c in range(num_locations): if r == c: distance_matrix[r][c] = time_matrix[r][c] = elif r in range(21) and c in range(21): distance_matrix[r][c] = 99999 time_matrix[r][c] = 99999 elif r in range(1, 21): distance_matrix[r][c] = distance_matrix[r-1][c] time_matrix[r][c] = time_matrix[r-1][c] elif c in range(1, 21): distance_matrix[r][c] = distance_matrix[r][c-1] time_matrix[r][c] = time_matrix[r][c-1] else: B2 origin_code = cusinput.iloc[0]['Mã cửa hàng'] if r in range(21) else orderinput.iloc[r - 21]['Mã cửa hàng'] destination_code = cusinput.iloc[0]['Mã cửa hàng'] if c in range(21) else orderinput.iloc[c - 1]['Mã cửa hàng'] print(origin_code) print(destination_code) origin_index = cusinput[cusinput['Mã cửa hàng'] == str(origin_code)].index.values[0] destination_index = cusinput[cusinput['Mã cửa hàng'] == str(destination_code)].index.values [0] origin_location = (cusinput.iloc[origin_index]['Vĩ độ'], cusinput.iloc[origin_index]['Kinh độ']) destination_location = (cusinput.iloc[destination_index]['Vĩ độ'], cusinput.iloc[destination_ind ex]['Kinh độ']) distance, time = get_route(origin_location, destination_location) distance_matrix[r][c] = distance time_matrix[r][c] = time data = {} data['distance_matrix'] = distance_matrix.tolist() data['time_matrix'] = time_matrix.tolist() data['order_code'] = order_code data['order_demand'] = order_demand data['vehicle_capacities'] = vehicle_capacities data['km_costs'] = km_costs data['man_costs'] = man_costs B3 data['num_vehicles'] = num_vehicles data['depot'] = with open('./input/data.json', 'w') as f: json.dump(data, f) def load_data(file_path): with open(file_path, 'r') as f: data = json.load(f) data['distance_matrix'] = np.array(data['distance_matrix']) data['time_matrix'] = np.array(data['time_matrix']) return data if name == ' main ': input_processing() B4 Phụ lục B2: Trình bày tìm lời giải cho toán phân phối import numpy as np import pandas as pd from ortools.constraint_solver import routing_enums_pb2 from ortools.constraint_solver import pywrapcp from get_data import load_data cusinput = pd.read_excel('./input/CUS.xlsx', index_col = 0) orderinput = pd.read_excel('./input/ORDER1.xlsx', index_col = 0) vehicleinput = pd.read_excel('./input/VEHICLE.xlsx', index_col = 0) def print_solution(data, manager, routing, solution): """Prints solution on console.""" # Display dropped orders global dropped_orders dropped_orders = [] for order in range(routing.Size()): if manager.IndexToNode(order) not in range(1, 21): if solution.Value(routing.NextVar(order)) == order: dropped_orders.append(data['order_code'][manager.IndexToNode(order)]) # Display routes count_vehicle_used = total_distance = total_load = total_load_ratio = time_dimension = routing.GetDimensionOrDie('Time') B5 total_time = for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) time_var_0 = time_dimension.CumulVar(index) route_distance = route_load = route_load_var = cumul_route = plan_output1 = '\nRoute for vehicle {0} - {1}:\n'.format(vehicle_id + 1, data['vehicle_capacities'] [vehicle_id]) while not routing.IsEnd(index): if manager.IndexToNode(index) in range(1, 21): route_load = route_load_var += cumul_route += else: route_load += data['order_demand'][manager.IndexToNode(index)] route_load_var += data['order_demand'][manager.IndexToNode(index)] time_var = time_dimension.CumulVar(index) plan_output1 += ' {0} Load({1}) Time({2}) ->'.format( data['order_code'][manager.IndexToNode(index)], route_load, roun d(solution.Value(time_var)/3600,3)) previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += data['distance_matrix'][manager.IndexToNode(previous_index)] [manager.IndexToNode(index)] B6 route_load_ratio = round(route_load_var/(data['vehicle_capacities'] [vehicle_id]*cumul_route)*100,3) if route_distance != 0: time_var = time_dimension.CumulVar(index) plan_output1 += ' {0} Load({1}) Time({2})'.format( data['order_code'][manager.IndexToNode(index)], route_load, roun d(solution.Value(time_var)/3600,3)) count_vehicle_used += route_time = solution.Value(time_var) - solution.Value(time_var_0) plan_output1 += '\nDistance of the route: {} m\n'.format(route_distance) plan_output1 += 'Load of the route: {} kg\n'.format(route_load_var) plan_output1 += 'Load ratio of the route: {} %\n'.format(route_load_ratio) plan_output1 += 'Time of the route: {} h'.format(round(route_time/3600,3)) print(plan_output1) else: route_time = total_distance += route_distance total_load += route_load_var total_load_ratio += route_load_ratio total_time += route_time print('\nTotal distance of all routes: {} m'.format(total_distance)) print('Total load of all routes: {} kg'.format(total_load)) print('Average load ratio of all routes: {} %'.format(round(total_load_ratio/count_vehicle_used,3) if co unt_vehicle_used != else total_load_ratio)) print('Total time of all routes: {} h'.format(round(total_time/3600,3))) print('Total vehicles used:', count_vehicle_used) B7 print('Dropped orders:', dropped_orders) def main(): """Solve the VRP.""" data = load_data('./input/data.json') print('\nDistance matrix:\n', data['distance_matrix']) print('\nTime matrix:\n', np.round(data['time_matrix']/3600,3)) print('Order code:', data['order_code']) print('Order demand:', data['order_demand']) # Create the routing index manager manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data[ 'depot']) # Create Routing Model routing = pywrapcp.RoutingModel(manager) # Create and register a length transit callback list_index = [] for vehicle_id in range(routing.vehicles()): cost = data['km_costs'][vehicle_id] def length_callback(from_index, to_index, km_cost = cost): """Returns the distance between the two nodes.""" from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return data['distance_matrix'][from_node][to_node]/1000*km_cost length_transit_callback_index = routing.RegisterTransitCallback(length_callback) list_index.append(length_transit_callback_index) # Define cost of each arc B8 routing.SetArcCostEvaluatorOfVehicle(list_index[vehicle_id], vehicle_id) # Define cost of each vehicle for vehicle_id in range(10): routing.SetFixedCostOfVehicle(data['man_costs'][vehicle_id], vehicle_id) # Create and register a duration transit callback def duration_callback(from_index, to_index): """Returns the travel time between the two nodes.""" # Convert from routing variable Index to duration matrix NodeIndex from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return data['time_matrix'][from_node][to_node] + 900 duration_transit_callback_index = routing.RegisterTransitCallback(duration_callback) # Ràng buộc trọng tải xe def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex from_node = manager.IndexToNode(from_index) return data['order_demand'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, max(data['vehicle_capacities']),data['vehicle_capacities'],True,'Capacity') capacity_dimension = routing.GetDimensionOrDie('Capacity') for location_idx in range(routing.nodes()): B9 if location_idx not in range(1, 21): index = manager.NodeToIndex(location_idx) capacity_dimension.SlackVar(index).SetValue(0) # Ràng buộc trọng tải xe tối đa điểm giao for order_idx, order in enumerate(data['order_code']): if order == cusinput.iloc[0]['Mã cửa hàng']: continue order_index = orderinput[orderinput['Mã đơn hàng'] == order].index.values[0] order_CH = orderinput.iloc[order_index - 1]['Mã cửa hàng'] order_CH_index = cusinput[cusinput['Mã cửa hàng'] == str(order_CH)].index.values[0] max_vehicle = cusinput.iloc[order_CH_index]['Trọng tải tối đa'] vehicle_req = list(vehicleinput[vehicleinput['Trọng tải']