Bỏ qua

Giải pháp bài toán định tuyến phương tiện (VRP) giúp tối ưu hóa lộ trình và hoạt động logistics. Nó tính toán lộ trình hiệu quả nhất cho đội xe, cân nhắc các ràng buộc như cửa sổ thời gian, sức chứa phương tiện và thứ tự ưu tiên giao nhận. API này phù hợp với doanh nghiệp muốn tối ưu hóa hoạt động, giảm chi phí và cải thiện hiệu suất giao hàng bằng cách tối thiểu hóa thời gian và quãng đường di chuyển, đồng thời duy trì chất lượng dịch vụ.

Ghi chú: - thứ tự tọa độ trong mảng là [kinh độ, vĩ độ] - mọi thời gian tính bằng giây - mọi khoảng cách tính bằng mét - đối tượng time_window có dạng [bắt đầu, kết thúc] - các khóa lỗi thời sẽ bị gạch ngang - giá trị cost trong đầu ra là chi phí tối ưu hóa nội bộ - "nhiệm vụ" có thể là công việc, điểm lấy hàng hoặc giao hàng

Endpoint

https://maps.track-asia.com/api/v1/vrp

Đầu vào

Khóa Giá trị Mô tả Ví dụ
key Chuỗi (bắt buộc) Khóa API public_key

Mô tả bài toán được đọc từ đầu vào chuẩn hoặc file (sử dụng -i) và phải có định dạng json như sau:

Khóa Mô tả
jobs mảng các đối tượng job mô tả địa điểm cần ghé thăm
shipments mảng các đối tượng shipment mô tả nhiệm vụ lấy/giao hàng
vehicles mảng các đối tượng vehicle mô tả phương tiện có sẵn
[matrices] mô tả tùy chọn các ma trận tùy chỉnh theo hồ sơ phương tiện

Jobs

Đối tượng job có các thuộc tính:

Khóa Mô tả
id số nguyên
[description] mô tả công việc bằng chuỗi
[location] mảng tọa độ
[location_index] chỉ số hàng/cột trong ma trận tùy chỉnh
[setup] thời gian chuẩn bị công việc (mặc định 0)
[service] thời gian phục vụ công việc (mặc định 0)
[delivery] mảng số nguyên mô tả số lượng giao hàng nhiều chiều
[pickup] mảng số nguyên mô tả số lượng lấy hàng nhiều chiều
[skills] mảng số nguyên xác định kỹ năng bắt buộc
[priority] số nguyên trong khoảng [0, 100] mô tả mức độ ưu tiên (mặc định 0)
[time_windows] mảng các đối tượng time_window mô tả khung giờ phục vụ hợp lệ

Sẽ báo lỗi nếu hai đối tượng job có cùng id.

Shipments

Đối tượng shipment có các thuộc tính:

Khóa Mô tả
pickup đối tượng shipment_step mô tả điểm lấy hàng
delivery đối tượng shipment_step mô tả điểm giao hàng
[amount] mảng số nguyên mô tả số lượng nhiều chiều
[skills] mảng số nguyên xác định kỹ năng bắt buộc
[priority] số nguyên trong khoảng [0, 100] mô tả mức độ ưu tiên (mặc định 0)

shipment_step tương tự đối tượng job (trừ các khóa chung đã có trong shipment):

Khóa Mô tả
id số nguyên
[description] mô tả bước bằng chuỗi
[location] mảng tọa độ
[location_index] chỉ số hàng/cột trong ma trận tùy chỉnh
[setup] thời gian chuẩn bị nhiệm vụ (mặc định 0)
[service] thời gian phục vụ nhiệm vụ (mặc định 0)
[time_windows] mảng các đối tượng time_window mô tả khung giờ phục vụ hợp lệ

Sẽ báo lỗi nếu hai đối tượng delivery (hoặc pickup) có cùng id.

Vehicles

Đối tượng vehicle có các thuộc tính:

Khóa Mô tả
id số nguyên
[profile] hồ sơ định tuyến (mặc định car)
[description] mô tả phương tiện bằng chuỗi
[start] mảng tọa độ
[start_index] chỉ số hàng/cột trong ma trận tùy chỉnh
[end] mảng tọa độ
[end_index] chỉ số hàng/cột trong ma trận tùy chỉnh
[capacity] mảng số nguyên mô tả sức chứa nhiều chiều
[costs] đối tượng cost xác định chi phí cho phương tiện
[skills] mảng số nguyên xác định kỹ năng
[time_window] đối tượng time_window mô tả giờ làm việc
[breaks] mảng các đối tượng break
[speed_factor] giá trị double trong khoảng (0, 5] dùng để điều chỉnh thời gian di chuyển (mặc định 1.)
[max_tasks] số nguyên xác định số nhiệm vụ tối đa trong lộ trình
[max_travel_time] số nguyên xác định thời gian di chuyển tối đa
[max_distance] số nguyên xác định khoảng cách tối đa
[steps] mảng các đối tượng vehicle_step mô tả lộ trình tùy chỉnh

Đối tượng cost có các thuộc tính:

Khóa Mô tả
[fixed] số nguyên xác định chi phí sử dụng phương tiện (mặc định 0)
[per_hour] số nguyên xác định chi phí mỗi giờ di chuyển (mặc định 3600)
[per_km] số nguyên xác định chi phí mỗi km di chuyển (mặc định 0)

Việc sử dụng giá trị per-hour không mặc định có nghĩa là xác định chi phí di chuyển dựa trên thời gian di chuyển với hệ số nhân. Do đó, việc cung cấp ma trận chi phí tùy chỉnh cho phương tiện là không nhất quán và sẽ gây lỗi.

Đối tượng break có các thuộc tính:

Khóa Mô tả
id số nguyên
[time_windows] mảng các đối tượng time_window mô tả khung giờ hợp lệ cho nghỉ giải lao
[service] thời gian nghỉ giải lao (mặc định 0)
[description] mô tả giải lao bằng chuỗi
[max_load] mảng số nguyên mô tả tải trọng tối đa cho phép nghỉ giải lao

Sẽ báo lỗi nếu hai đối tượng break có cùng id cho cùng một phương tiện.

Đối tượng vehicle_step có các thuộc tính:

Khóa Mô tả
type chuỗi (có thể là start, job, pickup, delivery, break hoặc end)
[id] id của nhiệm vụ cần thực hiện nếu typejob, pickup, delivery hoặc break
[service_at] ràng buộc cứng về thời gian phục vụ
[service_after] ràng buộc cứng về thời gian phục vụ tối thiểu
[service_before] ràng buộc cứng về thời gian phục vụ tối đa

Ghi chú

Vị trí nhiệm vụ

Đối với job, pickupdelivery:

  • location_index là bắt buộc nếu có ma trận tùy chỉnh
  • location là tùy chọn nhưng có thể thiết lập để lấy tọa độ trong phản hồi

Nếu không có ma trận tùy chỉnh:

  • sẽ gửi truy vấn table đến hệ thống định tuyến
  • location là bắt buộc
  • location_index không có hiệu lực

Vị trí phương tiện

  • startend là tùy chọn cho vehicle, miễn là có ít nhất một trong hai được cung cấp
  • nếu thiếu end, lộ trình sẽ dừng tại nhiệm vụ cuối cùng
  • nếu thiếu start, lộ trình sẽ bắt đầu từ nhiệm vụ đầu tiên
  • để yêu cầu lộ trình khứ hồi, chỉ cần thiết lập startend cùng tọa độ
  • tùy theo việc có ma trận tùy chỉnh hay không, các trường bắt buộc sẽ theo logic tương tự như job

Ràng buộc sức chứa

Sử dụng amount (capacity cho phương tiện, deliverypickup cho công việc, amount cho shipments) để mô tả bài toán có ràng buộc sức chứa. Các mảng này có thể dùng để mô hình hóa các ràng buộc tùy chỉnh cho nhiều chỉ số cùng lúc, ví dụ: số lượng, trọng lượng, thể tích. Phương tiện chỉ được phép phục vụ tập hợp nhiệm vụ nếu tải trọng tại mỗi bước không vượt quá giá trị tương ứng trong capacity. Khi sử dụng nhiều chỉ số, nên đặt các chỉ số quan trọng nhất ở đầu.

Giả định rằng mọi hàng giao sẽ được tải lên từ đầu, trong khi hàng lấy sẽ được mang về cuối lộ trình.

Kỹ năng

Sử dụng skills để mô tả bài toán nơi không phải mọi nhiệm vụ đều có thể được phục vụ bởi tất cả phương tiện. Kỹ năng công việc là bắt buộc, tức là phương tiện chỉ được phục vụ công việc nếu có đầy đủ các kỹ năng yêu cầu. Nói cách khác: công việc j phù hợp phương tiện v nếu j.skills là tập con của v.skills.

Điều này ngụ ý đặc biệt rằng:

  • công việc không có kỹ năng có thể được phục vụ bởi bất kỳ phương tiện nào;
  • phương tiện không có kỹ năng chỉ có thể phục vụ công việc không yêu cầu kỹ năng.

Để đơn giản hóa bài toán không yêu cầu kỹ năng, việc không cung cấp skills sẽ mặc định là mảng rỗng.

Ưu tiên công việc

Hữu ích khi không thể phục vụ hết tất cả công việc, để kiểm soát việc ưu tiên giao hàng. Thiết lập giá trị priority cao cho công việc sẽ giúp chúng được ưu tiên trong lộ trình hơn các công việc có độ ưu tiên thấp.

Thời gian chuẩn bị

Thời gian chuẩn bị mô tả thời gian cần thiết để bắt đầu công việc tại một vị trí. Đây là khoảng thời gian không được áp dụng lại cho các công việc tiếp theo tại cùng vị trí. Tổng thời gian "hành động" cho một công việc là setup + service nếu đến vị trí mới hoặc chỉ service nếu thực hiện tại vị trí trước đó.

Cửa sổ thời gian

Người dùng có thể quyết định mô tả cửa sổ thời gian theo hai cách:

  • giá trị tương đối, ví dụ: [0, 14400] cho cửa sổ 4 giờ tính từ thời điểm bắt đầu kế hoạch. Trong trường hợp này, mọi thời gian arrival trong phản hồi đều tính tương đối từ thời điểm bắt đầu;
  • giá trị tuyệt đối, các timestamp "thực". Trong trường hợp này, mọi thời gian arrival trong phản hồi đều có thể được diễn giải là timestamp.

Việc thiếu cửa sổ thời gian trong đầu vào có nghĩa là không có ràng buộc thời gian. Cụ thể, phương tiện không có time_window có thể phục vụ bất kỳ số lượng công việc nào, và công việc không có time_windows có thể được thực hiện bất kỳ lúc nào miễn là đáp ứng các ràng buộc khác.

steps của phương tiện

Chế độ lập kế hoạch

Mảng steps mô tả chính xác thứ tự lộ trình sẽ được tạo trong phản hồi. Các khóa service_* của đối tượng vehicle_step được dùng như ràng buộc thời gian cứng.

Chế độ giải bài toán

Việc sử dụng steps trong chế độ giải bài toán mặc định là cách để bắt đầu tìm kiếm từ giải pháp do người dùng định nghĩa, nếu hợp lệ. Khác với hành vi mặc định là chạy nhiều luồng tìm kiếm song song, điều này có nghĩa là chỉ theo một lộ trình duy nhất bắt đầu từ giải pháp do người dùng cung cấp. Chất lượng kết quả do đó phụ thuộc nhiều vào điểm khởi đầu do người dùng định nghĩa.

Trong bối cảnh này: - chỉ các bước có type=job, pickup hoặc delivery được dùng để quyết định thứ tự lộ trình - các khóa service_* không được sử dụng

Sẽ báo lỗi nếu lộ trình do người dùng định nghĩa không đáp ứng các ràng buộc.

Ma trận tùy chỉnh

Đối tượng matrices cho phép nhập các ma trận tùy chỉnh cho mỗi hồ sơ phương tiện. Mỗi ma trận là mảng các mảng số nguyên không trống được phân loại theo khóa profile, sau đó là:

  • durations cho ma trận thời gian di chuyển tùy chỉnh sẽ được dùng để kiểm tra mọi ràng buộc thời gian;
  • distances cho ma trận khoảng cách tùy chỉnh;
  • costs cho ma trận chi phí tùy chỉnh sẽ được dùng trong mọi đánh giá chi phí lộ trình.

Nếu chỉ cung cấp durations, chi phí nội bộ sẽ được tính dựa trên thời gian di chuyển và các thuộc tính costs của phương tiện.

Ví dụ mô tả các ma trận khác nhau cho các hồ sơ phương tiện:

"matrices": {
    "car": {
        "durations": [[0, 14], [21, 0]]
    },
    "moto": {
        "durations": [[0, 57], [43, 0]]
    }
}

Nếu cung cấp đầy đủ ma trận cho mọi profile yêu cầu, các thuộc tính location, startend trở thành tùy chọn. Thay vào đó, các chỉ số hàng/cột được cung cấp qua *_index sẽ được dùng trong quá trình tối ưu hóa.

Đầu ra

Giải pháp được ghi dưới dạng json ra đầu ra chuẩn hoặc file (sử dụng -o), định dạng như sau:

Khóa Mô tả
code mã trạng thái
error thông báo lỗi (chỉ xuất hiện khi code khác 0)
summary đối tượng tổng hợp các chỉ số giải pháp
unassigned mảng các đối tượng mô tả nhiệm vụ không được giao với id, type, nếu có, description, locationlocation_index
routes mảng các đối tượng route

Mã trạng thái

Các giá trị có thể:

Giá trị Trạng thái
0 không có lỗi
1 lỗi nội bộ
2 lỗi đầu vào
3 lỗi định tuyến

Summary

Đối tượng summary có các thuộc tính:

Khóa Mô tả
cost tổng chi phí cho mọi lộ trình
routes số lộ trình trong giải pháp
unassigned số nhiệm vụ không được giao
setup tổng thời gian chuẩn bị
service tổng thời gian phục vụ
duration tổng thời gian di chuyển
waiting_time tổng thời gian chờ
priority tổng độ ưu tiên của mọi nhiệm vụ
violations mảng các đối tượng violation cho mọi lộ trình
[delivery] tổng lượng giao hàng
[pickup] tổng lượng lấy hàng
[distance]* tổng quãng đường di chuyển

*: chỉ xuất hiện khi dùng cờ -g hoặc cung cấp ma trận khoảng cách trong đầu vào.

Routes

Đối tượng route có các thuộc tính:

Khóa Mô tả
vehicle id phương tiện được gán
steps mảng các đối tượng step
cost chi phí cho lộ trình này
setup tổng thời gian chuẩn bị
service tổng thời gian phục vụ
duration tổng thời gian di chuyển
waiting_time tổng thời gian chờ
priority tổng độ ưu tiên của nhiệm vụ
violations mảng các đối tượng violation
[description] mô tả phương tiện, nếu có trong đầu vào
[geometry]* mã hóa polyline cho lộ trình
[distance]** tổng quãng đường lộ trình

: chỉ xuất hiện khi dùng cờ -g. *: chỉ xuất hiện khi dùng cờ -g hoặc cung cấp ma trận khoảng cách trong đầu vào.

Steps

Đối tượng step có các thuộc tính:

Khóa Mô tả
type chuỗi (có thể là start, job, pickup, delivery, break hoặc end)
arrival thời gian dự kiến đến nơi
duration tổng thời gian di chuyển tích lũy đến bước này
setup thời gian chuẩn bị tại bước này
service thời gian phục vụ tại bước này
waiting_time thời gian chờ tại bước này
violations mảng các đối tượng violation cho bước này
[description] mô tả bước, nếu có trong đầu vào
[location] mảng tọa độ cho bước này (nếu có trong đầu vào)
[location_index] chỉ số hàng/cột trong ma trận tùy chỉnh cho bước này (nếu có trong đầu vào)
[id] id nhiệm vụ được thực hiện tại bước này, chỉ có nếu typejob, pickup, delivery hoặc break
[load] tải trọng phương tiện sau khi hoàn thành bước này (với ràng buộc sức chứa)
[distance]* quãng đường di chuyển tích lũy đến bước này

*: chỉ xuất hiện khi dùng cờ -g.

Violation

Đối tượng violation có các thuộc tính:

Khóa Mô tả
cause chuỗi mô tả nguyên nhân vi phạm
[duration] Thời gian sớm (hoặc trễ) nếu cause là "lead_time" hoặc "delay"

Các nguyên nhân vi phạm có thể: - "delay" nếu thời gian bắt đầu phục vụ vượt quá cửa sổ thời gian - "lead_time" nếu thời gian bắt đầu phục vụ sớm hơn cửa sổ thời gian - "load" nếu tải trọng phương tiện vượt quá sức chứa - "max_tasks" nếu số nhiệm vụ vượt quá max_tasks - "skills" nếu phương tiện không có đầy đủ kỹ năng yêu cầu - "precedence" nếu vi phạm ràng buộc shipment (giao hàng không có điểm lấy hàng tương ứng, lấy hàng không có giao hàng tương ứng) - "missing_break" nếu thiếu giải lao trong lộ trình tùy chỉnh - "max_travel_time" nếu thời gian di chuyển vượt quá max_travel_time - "max_distance" nếu quãng đường di chuyển vượt quá max_distance - "max_load" nếu tải trọng trong thời gian giải lao vượt quá max_load

Ghi chú về vi phạm: báo cáo chỉ thực sự có ý nghĩa khi dùng cờ -c để chọn lộ trình tùy chỉnh qua khóa steps của vehicle. Khi dùng chế độ tối ưu hóa thông thường, vi phạm vẫn được báo cáo để nhất quán, nhưng đảm bảo là "rỗng", tức là các mảng violations sẽ trống.

Mã ví dụ

var jobs = [];

var shipments = [

    {

        amount: [1],

        pickup: {

            id: 1,

            service: 60,

            location: [106.6984834, 10.72843945],

            description: "Đ. Số 65, Phường Tân Phong, Quận 7, Thành phố Hồ Chí Minh, Vietnam",

            time_windows: [[1725843600, 1725850800]],

        },

        delivery: {

            id: 1,

            service: 300,

            location: [106.7185714, 10.72843945],

            description: "Crescent Mall 101 Tôn Dật Tiên, Tân Phú, Quận 7, Thành phố Hồ Chí Minh 7000, Vietnam",

            time_windows: [[1725843600, 1725850800]],

        },

    },

    {

        amount: [1],

        pickup: {

            id: 2,

            service: 60,

            location: [106.7185714, 10.72843945],

            description: "Crescent Mall 101 Tôn Dật Tiên, Tân Phú, Quận 7, Thành phố Hồ Chí Minh 7000, Vietnam",

            time_windows: [[1725843600, 1725850800]],

        },

        delivery: {

            id: 2,

            service: 300,

            location: [106.723533, 10.73042726],

            description: "Capri by Fraser, Ho Chi Minh 2 Đường C - Bắc, Tân Phú, Quận 7, Thành phố Hồ Chí Minh, Vietnam",

            time_windows: [[1725843600, 1725850800]],

        },

    },

];

var vehicles = [

    {

        id: 5,

        start: [106.6984834, 10.72843945],

        end: [106.723533, 10.73042726],

        time_window: [1725879600, 1725880800],

        capacity: [1],

        skills: [1, 14],

        startDescription: "Start",

        endDescription: "End",

    },

];

var options = {

    g: true,

};



fetch("https://maps.track-asia.com/api/v1/vrp?key=public_key", {

    method: "POST",

    headers: { "content-type": "application/json" },

    body: JSON.stringify({

        jobs: jobs,

        shipments: shipments,

        vehicles: vehicles,

        options: options,

    }),

})

    .then((response) => response.json())

    .then((data) => console.log(data))

    .catch((error) => console.error("Error:", error));

Các bước tiếp theo