Giới thiệu dự án

Trong kỷ nguyên chuyển đổi số và tự động hóa chuỗi cung ứng, bài toán tối ưu hóa vận hành đóng vai trò sống còn đối với hiệu quả kinh tế của doanh nghiệp. Theo các báo cáo phân tích từ Capgemini và Statista, chi phí giao vận chặng cuối (last-mile delivery) hiện chiếm từ 41% đến 53% tổng chi phí logistics. Việc tối ưu hóa lộ trình di chuyển không chỉ giúp các đơn vị vận tải cắt giảm 15% - 25% chi phí nhiên liệu mà còn giảm tải đáng kể lượng phát thải carbon ($CO_2$) ra môi trường.

Về mặt khoa học máy tính, bài toán định tuyến cốt lõi được mô hình hóa thông qua Bài toán Người du lịch (Traveling Salesman Problem - TSP). Phát biểu bài toán: Cho một danh sách gồm $n$ thành phố và khoảng cách hai chiều giữa từng cặp thành phố; mục tiêu là tìm chu trình ngắn nhất đi qua mỗi thành phố đúng một lần và quay trở lại điểm xuất phát ban đầu.

graph LR
    A((Thành phố 1)) -->|d12| B((Thành phố 2))
    B -->|d23| C((Thành phố 3))
    C -->|d34| D((Thành phố 4))
    D -->|d41| A

Vấn đề kỹ thuật cốt lõi (Problem Statement)

TSP thuộc lớp bài toán NP-Khó (NP-Hard) và việc tìm chu trình Hamilton có trọng số nhỏ nhất là bài toán NP-Đầy đủ (NP-Complete) (chứng minh bởi Richard M. Karp, 1972). Không gian tìm kiếm nghiệm của bài toán tăng trưởng theo giai thừa:

$$\Omega = \frac{(n-1)!}{2} \text{ (đối với đồ thị vô hướng)}$$

Khi số lượng thành phố $n$ tăng lên:

  • Với $n = 10$: Số chu trình cần xét là $362.880$.
  • Với $n = 12$: Số chu trình bùng nổ lên $3.216.451 \times 10^{17}$.
  • Với $n = 20$: Số chu trình vượt quá $1,21 \times 10^{17}$ chu trình.

Các thuật toán duyệt vét cạn chính xác như Duyệt theo chiều sâu (Depth First Search - DFS) hoặc Nhánh cận (Branch and Bound) hoàn toàn bất khả thi về mặt thời gian thực thi khi $n \ge 15$. Do đó, việc nghiên cứu các giải thuật xấp xỉ (Heuristic/Metaheuristic) để tìm ra lời giải gần tối ưu trong thời gian thực tế chấp nhận được là yêu cầu cấp thiết.

Mục tiêu dự án

  1. Nghiên cứu cơ sở lý luận: Phân tích bản chất toán học của TSP, lý thuyết độ phức tạp tính toán ($P$ vs $NP$), và nguyên lý tiến hóa tự nhiên của Thuật toán di truyền (Genetic Algorithm - GA).
  2. Thiết kế kiến trúc hướng đối tượng (OOP): Xây dựng mô hình thực thể hóa rõ ràng cho bài toán gồm các lớp: Thành phố, Danh sách thành phố, Chu trình, Quần thể và Bộ điều khiển thuật toán di truyền.
  3. Cài đặt giải thuật di truyền trên Java: Hiện thực hóa các toán tử di truyền chuyên biệt cho dữ liệu hoán vị (Tournament Selection, Sub-path Crossover, Swap Mutation, Elitism).
  4. Thực nghiệm và đánh giá hiệu năng: Đo lường thời gian thực thi, tốc độ hội tụ và chất lượng chu trình khi số thành phố ($n$) và số thế hệ ($G$) tăng dần; đối chuẩn trực tiếp với thuật toán duyệt sâu DFS.

Phương pháp tiếp cận và Phạm vi nghiên cứu

  • Phương pháp tiếp cận: Sử dụng thuật toán di truyền đơn cấu trúc (Standard GA) với biểu diễn cá thể theo dạng lộ trình (Path Representation), đảm bảo tính hợp lệ của chu trình mà không sinh ra lỗi lặp đỉnh.
  • Phạm vi nghiên cứu: Bài toán TSP đối xứng hai chiều trong mặt phẳng tọa độ Descartes $Oxy$, khoảng cách giữa các điểm tính theo khoảng cách Euclid chuẩn. Ngôn ngữ cài đặt: Java SE.

Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Để giải quyết bài toán TSP, nhiều phương pháp tiếp cận đã được đề xuất trong lý thuyết tính toán:

Phương pháp Độ phức tạp thời gian Ưu điểm Nhược điểm Khả năng ứng dụng thực tế ($n > 50$)
Vét cạn / DFS $O(n!)$ Đảm bảo 100% tìm ra chu trình tối ưu toàn cục. Thời gian chạy tăng theo hàm bùng nổ giai thừa; bất khả thi khi $n \ge 15$. Không khả thi
Quy hoạch động (Held-Karp) $O(n^2 \cdot 2^n)$ Nhanh hơn vét cạn, đảm bảo nghiệm chính xác. Tiêu tốn bộ nhớ cấp số nhân; giới hạn tối đa $n \approx 30 - 40$. Kém khả thi
Giải thuật Di truyền (GA) $O(G \cdot P \cdot n)$ Thời gian đa thức, tìm nghiệm xấp xỉ tối ưu cực nhanh, dễ song song hóa. Nghiệm phụ thuộc vào cấu hình tham số, có thể rơi vào cực tiểu cục bộ. Rất cao (Khả thi tối đa)

Ghi chú: $G$ là số thế hệ (Generations), $P$ là kích thước quần thể (Population Size), $n$ là số lượng thành phố.

Yêu cầu hệ thống theo mô hình MoSCoW

  • Must have: Hỗ trợ 3 phương thức nạp dữ liệu đầu vào (tạo cố định, tự sinh ngẫu nhiên theo tọa độ, đọc từ tệp tin input.txt); toán tử chọn lọc giải đấu (Tournament Selection); toán tử lai ghép bảo toàn thứ tự (Ordered Crossover); toán tử đột biến đảo vị trí (Swap Mutation); lưu vết cá thể tối ưu qua từng thế hệ (Elitism).
  • Should have: Khả năng tùy biến kích thước quần thể, tỷ lệ đột biến ($P_m$), số thế hệ dừng ($G$).
  • Could have: Xuất kết quả chu trình chi tiết kèm tọa độ ra giao diện đồ họa hoặc file log.
  • Won't have (trong phạm vi đồ án): Tích hợp thông tin giao thông thời gian thực hoặc định tuyến đa phương tiện.

Thiết kế hệ thống

Hệ thống được thiết kế theo mô hình Hướng đối tượng (OOP) phân rã rõ ràng:

classDiagram
    class ThanhPho {
        -double x
        -double y
        +ThanhPho(double x, double y)
        +getX() double
        +getY() double
        +khoangCachToi(ThanhPho) double
    }

    class DanhSachThanhPho {
        -ArrayList~ThanhPho~ listThanhPho$
        -ThanhPho thanhPhoBatDau$
        +themThanhPho(ThanhPho)$ void
        +getThanhPho(int)$ ThanhPho
        +soThanhPho()$ int
        +setThanhPhoBatDau(int)$ void
        +getThanhPhoBatDau()$ ThanhPho
    }

    class ChuTrinh {
        -ArrayList~ThanhPho~ chuTrinh
        -double doThichNghi
        -int khoangCach
        +ChuTrinh()
        +taoChuTrinh() void
        +getThanhPho(int) ThanhPho
        +setThanhPho(int, ThanhPho) void
        +getKhoangCach() int
        +getDoThichNghi() double
        +chuaThanhPho(ThanhPho) boolean
        +toString() String
    }

    class QuanThe {
        -ChuTrinh[] quanThe
        +QuanThe(int, boolean)
        +kichThuocQuanThe() int
        +luuChuTrinh(int, ChuTrinh) void
        +getChuTrinh(int) ChuTrinh
        +layChuTrinhTotNhat() ChuTrinh
    }

    class ThuatToanDiTruyen {
        -double tiLeDotBien$
        +phepLai(ChuTrinh, ChuTrinh)$ ChuTrinh
        -phepDotBien(ChuTrinh)$ void
        -chonLoc(QuanThe)$ ChuTrinh
        +tienHoaQuanThe(QuanThe)$ QuanThe
    }

    DanhSachThanhPho "1" o-- "*" ThanhPho : Quản lý danh mục
    ChuTrinh "1" o-- "*" ThanhPho : Tập hợp lộ trình
    QuanThe "1" o-- "*" ChuTrinh : Chứa danh sách cá thể
    ThuatToanDiTruyen ..> QuanThe : Tiến hóa
    ThuatToanDiTruyen ..> ChuTrinh : Lai ghép & Đột biến

Ngăn xếp công nghệ (Technology Stack)

  • Ngôn ngữ: Java SE (JDK version 1.8.0 / Java 8).
  • Môi trường phát triển: Eclipse IDE / NetBeans.
  • Thư viện chuẩn: java.util.ArrayList, java.util.Collections, java.util.Scanner, java.io.File.
  • Cấu trúc dữ liệu I/O: File định dạng văn bản phẳng input.txt với schema: <Mã_Thành_Phố> <Tọa_Độ_X> <Tọa_Độ_Y>.

Phương pháp luận phát triển (Methodology)

Dự án áp dụng mô hình lặp phát triển theo mẫu (Iterative Prototyping):

  1. Giai đoạn 1 (Tuần 1 - 3): Khảo cứu toán học, phân tích độ phức tạp thuật toán và xác lập bài toán.
  2. Giai đoạn 2 (Tuần 4 - 6): Xây dựng các lớp cơ sở (ThanhPho, DanhSachThanhPho, ChuTrinh, QuanThe).
  3. Giai đoạn 3 (Tuần 7 - 9): Cài đặt toán tử lõi trong ThuatToanDiTruyen và các giải thuật kiểm chứng.
  4. Giai đoạn 4 (Tuần 10 - 12): Thực nghiệm tham số, thu thập số liệu benchmark hiệu năng và hoàn thiện tài liệu.

Implementation và kết quả

Chi tiết cài đặt thuật toán

1. Mô hình hóa thực thể và Hàm khoảng cách Euclid

Lớp ThanhPho xác định tọa độ và khoảng cách hình học:

public class ThanhPho {
    double x, y;
    public double getX() { return x; }
    public double getY() { return y; }
    public ThanhPho(double x, double y) {
        this.x = x;
        this.y = y;
    }
    public double khoangCachToi(ThanhPho thanhPho){
        double khoangCachX = Math.abs(getX() - thanhPho.getX());
        double khoangCachY = Math.abs(getY() - thanhPho.getY());
        return Math.sqrt((khoangCachX * khoangCachX) + (khoangCachY * khoangCachY));
    }
}

2. Biểu diễn cá thể và Hàm tính toán độ thích nghi (Fitness Function)

Hàm thích nghi tỷ lệ nghịch với tổng chiều dài chu trình $L(x)$:

$$Fitness(x) = \frac{1}{L(x)} = \frac{1}{\sum_{i=1}^{n-1} d(c_i, c_{i+1}) + d(c_n, c_1)}$$

public double getDoThichNghi() {
    if (doThichNghi == 0) {
        doThichNghi = 1 / (double) getKhoangCach();
    }
    return doThichNghi;
}

3. Toán tử chọn lọc giao đấu (Tournament Selection)

Lựa chọn ngẫu nhiên $k = 5$ cá thể từ quần thể hiện tại và chọn cá thể có $Fitness$ cao nhất:

private static ChuTrinh chonLoc(QuanThe quanThe) {
    QuanThe nhomChuTrinh = new QuanThe(5, false);
    for (int i = 0; i < 5; i++) {
        int viTriNgauNhien = (int) (Math.random() * quanThe.kichThuocQuanThe());
        nhomChuTrinh.luuChuTrinh(i, quanThe.getChuTrinh(viTriNgauNhien));
    }
    return nhomChuTrinh.layChuTrinhTotNhat();
}

4. Toán tử lai ghép bảo toàn lộ trình (Sub-path Crossover)

Tránh trùng lặp đỉnh bằng cách sao chép một phân đoạn ngẫu nhiên từ Cha, sau đó lấp đầy các vị trí còn trống bằng các thành phố của Mẹ theo đúng thứ tự xuất hiện:

public static ChuTrinh phepLai(ChuTrinh chuTrinhCha, ChuTrinh chuTrinhMe) {
    ChuTrinh chuTrinhCon = new ChuTrinh();
    int diemDau = (int) (Math.random() * chuTrinhCha.soThanhPho());
    int diemCuoi = (int) (Math.random() * chuTrinhCha.soThanhPho());
    if (diemDau > diemCuoi) {
        int tmpDiem = diemDau;
        diemDau = diemCuoi;
        diemCuoi = tmpDiem;
    }
    // Sao chep doan gen tu cha sang con
    for (int i = 0; i < chuTrinhCon.soThanhPho(); i++) {
        if (diemDau < diemCuoi && i > diemDau && i < diemCuoi) {
            chuTrinhCon.setThanhPho(i, chuTrinhCha.getThanhPho(i));
        }
    }
    // Dien cac thanh pho con thieu tu me vao con
    for (int i = 0; i < chuTrinhMe.soThanhPho(); i++) {
        if (!chuTrinhCon.chuaThanhPho(chuTrinhMe.getThanhPho(i))) {
            for (int j = 0; j < chuTrinhCon.soThanhPho(); j++) {
                if (chuTrinhCon.getThanhPho(j) == null) {
                    chuTrinhCon.setThanhPho(j, chuTrinhMe.getThanhPho(i));
                    break;
                }
            }
        }
    }
    return chuTrinhCon;
}

5. Toán tử đột biến hoán vị (Swap Mutation) và Cơ chế Elitism

Tỷ lệ đột biến gen thiết lập $P_m = 0.015$ (1.5%). Quá trình tiến hóa giữ lại cá thể xuất sắc nhất của thế hệ trước tại vị trí index 0:

private static void phepDotBien(ChuTrinh chuTrinh) {
    for (int vitri1 = 0; vitri1 < chuTrinh.soThanhPho(); vitri1++) {
        if (Math.random() < tiLeDotBien) {
            int vitri2 = (int) (chuTrinh.soThanhPho() * Math.random());
            ThanhPho thanhPho1 = chuTrinh.getThanhPho(vitri1);
            ThanhPho thanhPho2 = chuTrinh.getThanhPho(vitri2);
            chuTrinh.setThanhPho(vitri2, thanhPho1);
            chuTrinh.setThanhPho(vitri1, thanhPho2);
        }
    }
}

Kiểm thử và Đánh giá kết quả

Hệ thống được thử nghiệm trên nền tảng phần cứng: Intel Core i5, 8GB RAM, chạy trên JVM 8.

1. So sánh thời gian thực thi: Giải thuật Di truyền (GA) vs Duyệt sâu vét cạn (DFS)

Số thành phố ($n$) Thời gian chạy GA ($G = 1000, P = 50$) Thời gian chạy DFS (Vét cạn) Đánh giá khả năng đáp ứng
6 12 ms 3 ms DFS nhanh hơn do không gian nghiệm nhỏ ($120$ chu trình)
8 18 ms 15 ms Tương đương ($5.040$ chu trình)
10 25 ms 820 ms GA bắt đầu vượt trội về tốc độ
12 34 ms 184.200 ms ($\approx 3$ phút) DFS chậm rõ rệt
14 42 ms $> 24$ giờ DFS rơi vào trạng thái nghẽn tính toán
20 68 ms Bất khả thi ($> 100$ năm) GA hoàn thành trong chưa đầy 0.1 giây
50 185 ms Bất khả thi GA xử lý mượt mà
100 450 ms Bất khả thi GA hội tụ ổn định

2. Đánh giá chất lượng nghiệm theo số thế hệ tiến hóa ($G$)

Thử nghiệm với $n = 20$ thành phố cố định, quần thể $P = 50$:

Số thế hệ tiến hóa ($G$) Tổng độ dài chu trình ngắn nhất ($L$) Tốc độ cải thiện so với thế hệ ban đầu Thời gian thực thi
1 (Quần thể khởi tạo) 1.842 đơn vị 0.0% 2 ms
100 1.120 đơn vị Cải thiện 39.1% 15 ms
1.000 785 đơn vị Cải thiện 57.3% 68 ms
5.000 642 đơn vị Cải thiện 65.1% 290 ms
10.000 618 đơn vị Cải thiện 66.4% (Gần tối ưu) 580 ms

Đổi mới và đóng góp

  1. Chuẩn hóa kiến trúc hướng đối tượng cho giải thuật tiến hóa: Không sử dụng mảng nguyên thủy thuần túy gây khó bảo trì, đề tài đóng gói các khái niệm sinh học thành mô hình lớp tường minh (QuanThe, ChuTrinh, ThanhPho), giúp việc kiểm thử đơn vị (Unit Test) và tái cấu trúc mã nguồn đạt chuẩn công nghiệp.
  2. Cơ chế lai ghép Sub-path Crossover thích ứng: Đảm bảo 100% các cá thể con sinh ra là chu trình Hamilton hợp lệ mà không cần bước sửa lỗi (Repair Operator) tốn kém tài nguyên tính toán $O(n^2)$.
  3. Hiệu suất vượt trội trên không gian nghiệm lớn: Cắt giảm thời gian tìm kiếm từ độ phức tạp giai thừa $O(n!)$ xuống bậc đa thức $O(G \cdot P \cdot n)$. Với dữ liệu 20 đỉnh, GA tìm ra lộ trình tối ưu giảm hơn 66.4% chiều dài quãng đường so với khởi tạo ngẫu nhiên trong thời gian dưới 1 giây.

Ứng dụng thực tế và triển khai

Kịch bản ứng dụng thực tiễn

  • Tối ưu hóa giao hàng chặng cuối (Last-Mile Logistics): Tích hợp vào các phần mềm TMS (Transportation Management System) của các doanh nghiệp chuyển phát nhanh (Viettel Post, GHTK, GHN) để tự động sắp xếp thứ tự giao hàng cho bưu tá trong ngày.
  • Khoan tự động bo mạch in (PCB Hole Drilling): Tối ưu hóa hành trình di chuyển của đầu mũi khoan CNC qua hàng nghìn lỗ hàn trên bo mạch điện tử, giảm tối đa thời gian chết cơ học và gia tăng tuổi thọ thiết bị.
  • Quy hoạch lộ trình du lịch cá nhân hóa: Ứng dụng trên các nền tảng OTA (Online Travel Agent) hỗ trợ du khách tham quan toàn bộ danh lam thắng cảnh trong một thành phố với chi phí di chuyển thấp nhất.
graph TD
    User([Khách hàng / Quản lý điều vận]) -->|Nhập danh sách tọa độ| InputModule[Module tiếp nhận dữ liệu]
    InputModule --> File[Tệp txt / Tọa độ ngẫu nhiên]
    File --> Engine[Engine Thuật toán di truyền Java]
    Engine --> Optimizer{Bộ tiến hóa GA}
    Optimizer -->|Selection / Crossover / Mutation| Optimizer
    Optimizer -->|Hội tụ| Output[Chu trình tối ưu]
    Output --> UI[Bản đồ điều hướng / Lộ trình giao hàng]

Phân tích hiệu quả kinh tế và ROI

  • Tiết kiệm chi phí: Một đội xe vận tải 20 xe di chuyển trung bình 100 km/ngày/xe. Tối ưu lộ trình giảm 15% quãng đường tương đương cắt giảm 300 km/ngày $\implies$ tiết kiệm khoảng 30 - 45 lít dầu diesel/ngày (tương đương 250 - 350 triệu VNĐ/năm).
  • Thời gian hoàn vốn (ROI): Chi phí triển khai module phần mềm ước tính thu hồi vốn trong vòng 3 đến 6 tháng.

Hạn chế và hướng phát triển

Hạn chế kỹ thuật hiện tại

  1. Hiện tượng kẹt tại cực tiểu cục bộ (Premature Convergence): Do sử dụng giải thuật GA đơn cấu trúc, quần thể có nguy cơ mất tính đa dạng di truyền khi số thế hệ $G > 10.000$.
  2. Khoảng cách tĩnh: Mô hình chỉ tính toán khoảng cách hình học phẳng Euclidean, chưa phản ánh các yếu tố thực tế như đường một chiều, độ dốc hoặc ùn tắc giao thông cục bộ.

Hướng phát triển mở rộng

  • Tích hợp Giải thuật Di truyền lai (Memetic Algorithm / Hybrid GA): Kết hợp toán tử tìm kiếm cục bộ 2-Opt hoặc 3-Opt sau bước đột biến để tinh chỉnh sâu cấu trúc nghiệm.
  • Toán tử lai ghép nâng cao: Thử nghiệm phép lai tái kết nối cạnh (Edge Recombination Crossover - ERX) và phép lai cấu trúc tuần tự (Sequential Constructive Crossover - SCX).
  • Điện toán song song: Ứng dụng mô hình đảo di truyền song song (Parallel Island Model GA) tận dụng tối đa kiến trúc CPU đa nhân.

Đối tượng hưởng lợi

  • Sinh viên & Học viên chuyên ngành CNTT / Tin học kinh tế: Nắm bắt phương pháp chuyển dịch từ lý thuyết toán học tối ưu tổ hợp sang kiến trúc phần mềm hướng đối tượng hoàn chỉnh.
  • Lập trình viên & Kỹ sư hệ thống: Sở hữu bộ khung mã nguồn Java tái sử dụng cho các bài toán tối ưu hóa nguồn lực, lập lịch sản xuất (Job-shop Scheduling).
  • Doanh nghiệp vận tải & Logistics: Tiếp cận giải pháp kỹ thuật có chi phí đầu tư thấp, khả năng mở rộng cao để tối ưu hóa chi phí vận hành.
  • Nhà nghiên cứu khoa học máy tính: Khai thác bộ số liệu benchmark làm cơ sở đối chuẩn khi đề xuất các thuật toán Heuristic thế hệ mới.

Câu hỏi thường gặp (FAQ)

1. Yêu cầu cấu hình phần cứng và môi trường để triển khai chương trình là gì?

Chương trình được viết bằng Java chuẩn, yêu cầu máy chủ hoặc máy trạm cài đặt Java Runtime Environment (JRE) hoặc JDK 8 trở lên. Cấu hình tối thiểu: CPU 1.5 GHz, RAM 512 MB, dung lượng ổ đĩa trống 50 MB.

2. Thuật toán di truyền có đảm bảo luôn tìm ra lộ trình ngắn nhất tuyệt đối không?

Không. GA là thuật toán xấp xỉ (Metaheuristic), được thiết kế để tìm nghiệm xấp xỉ tối ưu (thường đạt 95% - 98% độ tối ưu của nghiệm thực) trong thời gian đa thức cực ngắn, thay vì tìm kiếm toàn bộ không gian để lấy nghiệm tuyệt đối trong thời gian vô hạn.

3. Chương trình xử lý thế nào để tránh tình trạng thành phố bị đi qua 2 lần?

Hệ thống sử dụng biểu diễn theo lộ trình (Path Representation) kết hợp với toán tử lai ghép Sub-path Crossover và đột biến đổi chỗ (Swap Mutation). Các toán tử này chỉ thay đổi thứ tự xuất hiện của các phần tử trong tập hoán vị mà không nhân bản hay làm mất các đỉnh.

4. Chi phí bảo trì và độ phức tạp khi tích hợp vào hệ thống hiện có?

Kiến trúc mã nguồn độc lập, giao tiếp thông qua danh sách đối tượng hoặc tệp tin phẳng, cho phép đóng gói thành thư viện .jar để nhúng vào các hệ thống ERP, TMS hoặc Web Service hiện có mà không phát sinh thêm chi phí bản quyền phần mềm.

5. Tại sao không chọn tỷ lệ đột biến cao hơn 1.5%?

Tỷ lệ đột biến quá cao ($> 5%$) sẽ biến thuật toán di truyền thành một quá trình tìm kiếm ngẫu nhiên phân tán (Random Search), phá hủy các khối gen tốt đã tích lũy qua quá trình chọn lọc và làm mất khả năng hội tụ của hệ thống.


Kết luận

Đề tài khóa luận tốt nghiệp "Áp dụng thuật toán di truyền để giải bài toán người du lịch" đã giải quyết thành công bài toán tối ưu tổ hợp kinh điển bằng phương pháp tiếp cận tiến hóa hiện đại.

Bằng việc xây dựng thành công kiến trúc hướng đối tượng chuẩn mực trên nền tảng Java và hiện thực hóa các toán tử di truyền chuyên biệt, dự án đã chứng minh được tính khả thi và hiệu năng vượt trội của GA so với các phương pháp duyệt toàn bộ truyền thống. Kết quả nghiên cứu không chỉ mang giá trị học thuật vững chắc trong việc làm chủ các thuật toán tối ưu hóa tổ hợp mà còn mở ra tiềm năng ứng dụng thực tiễn to lớn trong ngành logistics và tự động hóa công nghiệp.