Tài liệu này hướng dẫn bạn cách gửi yêu cầu đầu tiên đến Route Optimization API bằng một tình huống sử dụng thực tế.
Để đơn giản, ví dụ này sử dụng HTTP và JSON để minh hoạ API REST. Tuy nhiên, đối với môi trường thực tế, bạn nên sử dụng gRPC để đạt được hiệu suất cao. Tuy nhiên, gRPC yêu cầu một số bước cài đặt. Để biết thêm thông tin, hãy xem phần Thư viện ứng dụng Route Optimization API.
Trường hợp
Bạn điều hành một dịch vụ chăm sóc chó ban ngày từ 7 giờ sáng đến 7 giờ tối ở San Francisco. Sáng nay, bạn muốn đón ba chú chó từ các địa điểm khác nhau trong thành phố và đưa chúng đến trung tâm chăm sóc của bạn.
Chú chó núi Bernese và chú chó Chihuahua là khách hàng quen thuộc đã đặt lịch hẹn vào tuần trước. Yêu cầu về chú chó chăn cừu Đức là một yêu cầu mới, được đưa ra vào phút chót. Bạn muốn nhận chú chó chăn cừu Đức nếu có thể, nhưng không muốn ảnh hưởng đến khách hàng quen.
Bạn có một chiếc xe tải cho công việc này và bạn trả cho tài xế 27 USD một giờ. Tài xế và xe tải bắt đầu ngày làm việc tại trung tâm chăm sóc trẻ của bạn lúc 7 giờ sáng và cần quay lại sau khi đón trẻ vào buổi sáng trước 12 giờ trưa để nghỉ trưa.
Hôm nay là ngày 13 tháng 2 năm 2024. Tất cả thời gian trong trường hợp này đều là giờ địa phương của San Francisco, tức là Giờ chuẩn Thái Bình Dương (UTC-8) vào tháng 2. Trình điều khiển có các nhiệm vụ sau:
- Đón chú chó núi Bernese gần Tháp Coit. Chủ sở hữu yêu cầu khung giờ lấy hàng hẹp, từ 8:00 đến 8:20 sáng.
- Đón chú chó Chihuahua tại Công viên South Sunset Playground. Chủ cửa hàng đưa ra khung giờ lấy hàng linh hoạt hơn, từ 7:30 đến 9:30 sáng.
- Đón chú chó chăn cừu Đức ở Land's End. Chủ sở hữu cũng yêu cầu khung giờ lấy hàng hẹp, từ 8:00 đến 8:20 sáng.
- Gửi chó tại trung tâm chăm sóc thú cưng ở Công viên Mission Dolores. Nhà trẻ yêu cầu đưa trẻ đến trong khoảng từ 9:30 sáng đến 11:30 sáng.
Mỗi lần đón và trả chó mất 5 phút để đón hoặc trả chó.
Vì Land's End cách xa Coit Tower và khung giờ lấy hàng của hai địa điểm này xung đột với nhau, nên tài xế không thể thực hiện cả ba lượt lấy hàng. Trình tối ưu hoá phải chọn chú chó nào cần bỏ qua để giảm thiểu tổng chi phí (tiền lương của người lái xe và mọi hình phạt bỏ qua).
Trước khi bắt đầu
Để chạy mã trong trường hợp ví dụ này, trước tiên, bạn phải hoàn tất hướng dẫn trong phần Thiết lập Route Optimization API.
1. Chọn phương pháp tối ưu hoá tuyến đường
Route Optimization API có nhiều phương thức để bạn lựa chọn tuỳ thuộc vào mức độ phức tạp của vấn đề tối ưu hoá.
Vì tình huống dịch vụ chăm sóc chó ban ngày này là một yêu cầu nhỏ và đơn giản, nên hãy sử dụng một phương thức chặn, chẳng hạn như optimizeTours, giúp nhanh chóng cung cấp kết quả cho các yêu cầu nhỏ. Để biết thêm thông tin về các điểm cuối của Route Optimization API, hãy xem bài viết Chọn một điểm cuối.
Sử dụng URL sau để gửi yêu cầu POST HTTP đến phương thức optimizeTours:
https://routeoptimization.googleapis.com/v1/projects/PROJECT_OR_ID:optimizeTours
Bạn cũng cần đặt chế độ cài đặt thời gian chờ và thời hạn ngắn để giảm thời gian chờ không cần thiết. Đối với trường hợp dịch vụ trông giữ chó này, trình tối ưu hoá không cần nhiều thời gian để phản hồi yêu cầu của bạn, vì vậy, hãy sử dụng các chế độ cài đặt sau:
- Đặt tham số
timeoutthành 2 giây. - Giữ nguyên chế độ cài đặt thời hạn ở chế độ mặc định, tức là 60 giây cho các yêu cầu REST.
2. Tạo nội dung thư yêu cầu
Sau khi chọn phương thức chặn optimizeTours và xác định chế độ cài đặt thời gian chờ và thời hạn, bước tiếp theo là tạo nội dung của thông báo yêu cầu.
Trong trường hợp này, yêu cầu là một thông báo OptimizeToursRequest được mã hoá dưới dạng JSON trong API REST.
Để tạo thông báo yêu cầu, hãy làm theo các bước tiếp theo:
Bắt đầu bằng cấu trúc yêu cầu cơ bản như sau:
{ "timeout": ..., "model": { "shipments": [...], "vehicles": [...], "globalStartTime": "...", "globalEndTime": "..." } }Để biết thêm thông tin về cấu trúc, hãy xem hướng dẫn về khái niệm chính cho Cấu trúc cơ sở (ShipmentModel, Shipment và Vehicle).
Xác định lô hàng. Trong trường
shipments, hãy thêm thông báoShipmentcho mỗi chú chó cần được đón và trả vào buổi sáng. Đây là nơi bạn xác định từng địa điểm và thời gian đón chó mà chủ chó muốn, cũng như địa điểm và thời gian gửi chó của trung tâm chăm sóc ban ngày.Đối với mỗi chú chó, hãy tạo một
VisitRequestcho việc đón và một khác cho việc trả, trong trường hợp này, được gọi là trả tại nhà trẻ.Trong phần đón, hãy đặt
arrivalWaypointthành địa điểm đón chó (Coit Tower cho chó núi Bernese, South Sunset Playground Park cho chó Chihuahua hoặc Land's End cho chó chăn cừu Đức). ĐặttimeWindowsthành thời gian đón mà chủ sở hữu yêu cầu (8:00 đến 8:20 sáng cho chó núi Bernese và chó chăn cừu Đức, và 7:30 đến 9:30 sáng cho chó Chihuahua).Trong các lần giao hàng, hãy đặt
arrivalWaypointthành trung tâm giữ trẻ vàtimeWindowscho thời gian trả hàng bắt buộc (9:30 sáng đến 11:30 sáng).Đối với tất cả các chuyến đón và trả, hãy đặt
durationthành 5 phút (300s) để tính thời gian đón và trả chó.
Để biết thêm thông tin về khung thời gian, hãy xem bài viết Khung thời gian.
Để ưu tiên khách hàng thường xuyên, bạn đặt
penaltyCostthành1000cho chó núi Bernese và Chihuahua, còn100cho chó chăn cừu Đức. Khi đặt chi phí phạt, trình tối ưu hoá có thể bỏ qua bất kỳ chú chó nào, nhưng sẽ cân nhắc bỏ qua chú chó chăn cừu Đức (có mức phạt thấp hơn) trước nếu các quy tắc ràng buộc khiến bạn không thể thực hiện tất cả các lượt đón.Bạn có thể sử dụng trường
labelđể thêm giá trị nhận dạng cho mỗi lô hàng, chẳng hạn như "Chó núi Bernese", "Chihuahua" và "Chó chăn cừu Đức". Việc này có thể giúp bạn xác định các lô hàng trong phản hồi.
Để biết thêm thông tin về cách xác định lô hàng, hãy xem phần Lô hàng.
Xác định xe. Trong trường
vehicles, hãy thêm một thông báoVehiclecho một chiếc xe tải của bạn, trong đó có điểm xuất phát và điểm kết thúc là trung tâm giữ trẻ, chi phí tiền lương của tài xế và giờ hoạt động của xe tải.Đặt
startWaypointvàendWaypointcho xe tải thành vị trí bắt đầu và kết thúc trong ngày, tức là trung tâm giữ trẻ gần Công viên Mission Dolores.Để giảm thiểu chi phí hoạt động, bạn phải xác định các quy tắc ràng buộc về chi phí của doanh nghiệp. Đặt tham số chi phí
costPerHourthành27, tức là số tiền bạn trả cho tài xế lái xe đưa đón thú cưng. Để biết thêm thông tin về các tham số chi phí, hãy xem bài viết Mô hình chi phí.Để đảm bảo trình tối ưu hoá tạo ra một tuyến đường trong giờ hoạt động của xe tải, hãy xác định khoảng thời gian hoạt động của xe. Cửa sổ này đặt ra các quy tắc ràng buộc về thời gian bắt đầu và kết thúc cho tuyến đường. Bằng cách chỉ xác định một nửa của mỗi khoảng thời gian, bạn sẽ giúp trình tối ưu hoá linh hoạt bắt đầu tuyến đường muộn hơn hoặc kết thúc sớm hơn:
Việc đặt
startTimetrongstartTimeWindowsthành 7 giờ sáng có nghĩa là tài xế có thể bắt đầu ca làm việc sớm nhất là lúc 7 giờ sáng. Họ cũng có thể bắt đầu muộn hơn nếu không có chuyến đón khách nào vào sáng sớm.Nếu bạn đặt
endTimetrongendTimeWindowsthành buổi trưa, thì tài xế phải kết thúc ca làm việc của họ trước buổi trưa. Họ cũng có thể kết thúc ca làm việc ngay khi hoàn thành đơn giao hàng cuối cùng.
Việc bỏ qua nửa còn lại của khoảng thời gian sẽ giảm thiểu thời gian chờ đợi và đi đường vòng của tài xế. Để biết thêm thông tin về khung thời gian, hãy xem bài viết Khung thời gian.
Để biết thêm thông tin về cách xác định xe, hãy xem bài viết Xe.
Đặt khoảng thời gian chung. Khung thời gian chung thể hiện khung thời gian mà xe tải có thể đón và trả khách cho nhà trẻ của bạn trong suốt cả ngày. Trong trường hợp này, hãy đặt
globalStartTimethành 7 giờ sáng vàglobalEndTimethành 7 giờ tối cho ngày 13 tháng 2 năm 2024, tức là giờ hoạt động của dịch vụ trông giữ chó.
3. Gửi yêu cầu
Sau đây là một yêu cầu curl đơn giản dựa trên tình huống dịch vụ chăm sóc chó ban ngày và sử dụng phương thức chặn optimizeTours.
Trước khi gửi yêu cầu, hãy thay thế PROJECT_NUMBER_OR_ID trong mã mẫu bằng mã dự án Google Cloud của bạn.
curl -X POST 'https://routeoptimization.googleapis.com/v1/projects/PROJECT_NUMBER_OR_ID:optimizeTours' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
--data @- << EOM
{
"timeout": "2s",
"model": {
"shipments": [
{
"pickups": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.802395,
"longitude": -122.405822
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T08:00:00-08:00",
"endTime": "2024-02-13T08:20:00-08:00"
}
],
"duration": "300s"
}
],
"deliveries": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T09:30:00-08:00",
"endTime": "2024-02-13T11:30:00-08:00"
}
],
"duration": "300s"
}
],
"label": "Bernese mountain dog",
"penaltyCost": 1000
},
{
"pickups": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.738067,
"longitude": -122.498593
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T07:30:00-08:00",
"endTime": "2024-02-13T09:30:00-08:00"
}
],
"duration": "300s"
}
],
"deliveries": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T09:30:00-08:00",
"endTime": "2024-02-13T11:30:00-08:00"
}
],
"duration": "300s"
}
],
"label": "Chihuahua",
"penaltyCost": 1000
},
{
"pickups": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.78018,
"longitude": -122.51194
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T08:00:00-08:00",
"endTime": "2024-02-13T08:20:00-08:00"
}
],
"duration": "300s"
}
],
"deliveries": [
{
"arrivalWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"timeWindows": [
{
"startTime": "2024-02-13T09:30:00-08:00",
"endTime": "2024-02-13T11:30:00-08:00"
}
],
"duration": "300s"
}
],
"label": "German shepherd",
"penaltyCost": 100
}
],
"vehicles": [
{
"startWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"endWaypoint": {
"location": {
"latLng": {
"latitude": 37.759719,
"longitude": -122.42798
}
}
},
"costPerHour": 27,
"startTimeWindows": [
{
"startTime": "2024-02-13T07:00:00-08:00"
}
],
"endTimeWindows": [
{
"endTime": "2024-02-13T12:00:00-08:00"
}
]
}
],
"globalStartTime": "2024-02-13T07:00:00-08:00",
"globalEndTime": "2024-02-13T19:00:00-08:00"
}
}
EOM
Các tham số yêu cầu được dùng trong yêu cầu
Bảng sau đây mô tả các tham số yêu cầu được dùng trong phần nội dung yêu cầu của trường hợp ví dụ. Bạn có thể lọc nội dung theo thành phần mẹ hoặc bằng cách tìm kiếm văn bản.
| Cha mẹ | Tham số | Loại thuộc tính | Mô tả |
|---|---|---|---|
OptimizeToursRequest |
model |
đối tượng (ShipmentModel) |
Đây là nội dung cốt lõi trong yêu cầu của bạn. Đây là một đối tượng duy nhất mà bạn xác định toàn bộ vấn đề, bao gồm tất cả những chú chó bạn cần đón và trả (shipments) cũng như xe tải trong đội xe của bạn (vehicles). Hãy coi đây là bản thiết kế hoàn chỉnh cho vấn đề bạn cần tối ưu hoá. |
timeout |
Thời lượng | Tham số này chỉ định thời gian tối đa mà máy chủ xử lý một yêu cầu trước khi trả về phản hồi. Hãy sử dụng tham số này để rút ngắn thời gian chờ. Đối với các yêu cầu nhỏ và nhanh, chẳng hạn như trường hợp dịch vụ chăm sóc chó này, hãy đặt giá trị này thành 2 giây. | |
ShipmentModel |
shipments[] |
mảng đối tượng (Shipment) |
Đây là một mảng đối tượng, trong đó mỗi đối tượng đại diện cho một chú chó cần được đón hoặc trả. |
vehicles[] |
mảng đối tượng (Vehicle) |
Đây là một mảng đối tượng, trong đó mỗi đối tượng xác định một xe trong đội xe của bạn. Đây là nơi bạn mô tả tài nguyên của mình, chẳng hạn như xe tải thực hiện việc đón và trả khách. Bạn phải xác định ít nhất một phương tiện để có được tuyến đường tối ưu. | |
globalStartTime |
Dấu thời gian | Đây là thời điểm sớm nhất có thể xảy ra đối với bất kỳ sự kiện nào trong toàn bộ mô hình của bạn. Tham số này thu hẹp vấn đề tối ưu hoá theo thời gian, điều này rất quan trọng để tính toán chính xác lưu lượng truy cập và định tuyến. Đối với trường hợp dịch vụ trông giữ chó này, hãy đặt giá trị này thành thời gian sớm nhất mà tài xế có thể vận hành xe tải trong ngày, tức là 7 giờ sáng ngày 13 tháng 2 năm 2024. | |
globalEndTime |
Dấu thời gian | Đây là thời gian muộn nhất có thể xảy ra đối với bất kỳ sự kiện nào trong toàn bộ mô hình của bạn. Đối với trường hợp dịch vụ trông giữ chó này, hãy đặt giá trị này thành thời điểm xe dự kiến kết thúc hoạt động, tức là 19:00 ngày 13 tháng 2 năm 2024. | |
Shipment |
pickups[] |
mảng đối tượng (VisitRequest) |
Đây là danh sách tất cả các cách lấy hàng có thể áp dụng cho lô hàng. Trình tối ưu hoá sẽ chọn trình giải phù hợp nhất để giải quyết vấn đề của bạn. Đối với trường hợp dịch vụ chăm sóc chó ban ngày này, hãy liệt kê các địa điểm đón và khung thời gian mà mỗi chủ sở hữu cung cấp cho mỗi chú chó. |
deliveries[] |
mảng đối tượng (VisitRequest) |
Đây là danh sách tất cả các lựa chọn gửi hàng có thể có cho lô hàng. Trình tối ưu hoá sẽ chọn trình giải phù hợp nhất để giải quyết vấn đề của bạn. Đối với trường hợp dịch vụ chăm sóc chó ban ngày này, hãy liệt kê vị trí của cơ sở chăm sóc chó ban ngày và khoảng thời gian mà tài xế cần quay lại để cho mỗi chú chó ăn trưa. | |
label |
chuỗi | Đây là giá trị nhận dạng cho một lô hàng cụ thể trong yêu cầu của bạn. Bạn có thể chỉ định nhãn trong yêu cầu để dễ đọc phản hồi hơn. Đối với trường hợp dịch vụ chăm sóc chó ban ngày này, hãy sử dụng một chuỗi mô tả như "Chihuahua", "Chó núi Bernese" hoặc tên của chú chó để so khớp giải pháp với dữ liệu đầu vào khi bạn nhận được phản hồi của API. | |
penaltyCost |
gấp đôi | Đây là chi phí phạt phát sinh nếu trình tối ưu hoá bỏ qua lô hàng này. Theo mặc định, các lô hàng là bắt buộc – trình tối ưu hoá ưu tiên giảm thiểu các lô hàng bắt buộc bị bỏ qua và chỉ bỏ qua các lô hàng đó khi không còn lựa chọn nào khác. Việc đặt chi phí phạt cho phép trình tối ưu hoá bỏ qua một lô hàng nếu lô hàng đó không khả thi hoặc quá tốn kém để thực hiện, đồng thời cho phép bạn cân nhắc mức độ ưu tiên giữa các lô hàng. Trong trường hợp này, bạn đặt chi phí phạt cao hơn (1000) cho khách hàng thường xuyên (chó núi Bernese và Chihuahua) và chi phí phạt thấp hơn (100) cho yêu cầu vào phút chót của chó chăn cừu Đức. Điều này cho trình tối ưu hoá biết rằng cần ưu tiên khách hàng thường xuyên, vì vậy, trình tối ưu hoá sẽ cân nhắc bỏ qua chú chó béc-giê Đức trước tiên khi không thể thực hiện tất cả các lượt đón. |
|
VisitRequest |
arrivalWaypoint |
đối tượng (Waypoint) |
Đây là vị trí của một lượt ghé thăm cụ thể trên tuyến đường. Bạn có thể xác định vị trí này bằng toạ độ vĩ độ và kinh độ, Mã địa điểm hoặc hướng. Trong
trường hợp dịch vụ chăm sóc chó này, hãy đặt giá trị này thành vị trí do chủ sở hữu cung cấp cho
pickups
và thành địa chỉ của trung tâm chăm sóc cho
deliveries. |
timeWindows[] |
mảng đối tượng (TimeWindow) |
Đây là một mảng đối tượng xác định các quy tắc ràng buộc về thời gian cho việc đến lấy hàng hoặc giao hàng. Đối với trường hợp này, hãy sử dụng trường này để xác định khung giờ đón từng chú chó và khung giờ có thể chấp nhận để đưa chó đến trung tâm chăm sóc ban ngày. | |
duration |
Thời lượng | Tham số này chỉ định thời lượng của lượt ghé thăm (ví dụ: thời gian bốc dỡ hàng). Trong trường hợp này, bạn đặt thời gian đệm là 5 phút (300s) cho tất cả các lần đón và trả để tính đến thời gian tài xế đón và trả chó. |
|
Vehicle |
startWaypoint |
đối tượng (Waypoint) |
Đây là vị trí bắt đầu của tuyến đường của xe, được xác định bằng toạ độ vĩ độ và kinh độ hoặc mã địa điểm. Tham số này cho trình tối ưu hoá biết nơi xe phải bắt đầu tuyến đường. Nếu bạn không xác định điểm tham chiếu này, trình tối ưu hoá sẽ chọn một trong các điểm đến lấy hàng hoặc giao hàng làm vị trí xuất phát. Đối với trường hợp dịch vụ trông giữ chó này, vì tài xế bắt đầu ngày làm việc tại cơ sở trông giữ chó, hãy sử dụng toạ độ của Công viên Mission Dolores. |
endWaypoint |
đối tượng (Waypoint) |
Đây là điểm đến cuối cùng trong tuyến đường của xe, được xác định bằng toạ độ vĩ độ và kinh độ hoặc mã địa điểm. Tham số này cho trình tối ưu hoá biết nơi xe phải kết thúc tuyến đường. Nếu bạn không xác định điểm tham chiếu này, trình tối ưu hoá sẽ chọn một trong các điểm đến lấy hàng hoặc giao hàng làm điểm kết thúc của tuyến đường. Đối với trường hợp dịch vụ trông giữ chó này, vì tài xế phải kết thúc ngày tại cơ sở trông giữ chó, hãy sử dụng toạ độ cho Công viên Mission Dolores. | |
costPerHour |
số | Đây là chi phí phát sinh cho mỗi giờ sử dụng xe, bất kể xe đang di chuyển hay dừng lại. Đối với trường hợp dịch vụ trông giữ chó này, hãy sử dụng giá trị này để lập mô hình tiền lương theo giờ của tài xế. | |
startTimeWindows[] |
mảng đối tượng (TimeWindow) |
Đây là khoảng thời gian chấp nhận được mà tài xế có thể bắt đầu ca làm việc của họ. Đối với trường hợp dịch vụ chăm sóc chó ban ngày này, hãy xác định startTime là 7 giờ sáng nhưng bỏ qua endTime. Điều này cho phép trình tối ưu hoá trì hoãn thời điểm bắt đầu ca làm việc nếu chuyến đón khách đầu tiên diễn ra muộn hơn vào buổi sáng. Xin lưu ý rằng ngay cả khi bạn không cung cấp endTime cho startTimeWindows, thì thời gian bắt đầu vẫn được giới hạn ngầm định bởi endTimeWindows. Xe phải bắt đầu tuyến đường trước khi tuyến đường kết thúc. |
|
endTimeWindows[] |
mảng đối tượng (TimeWindow) |
Đây là khoảng thời gian chấp nhận được để tài xế hoàn thành tuyến đường.
Đối với trường hợp dịch vụ chăm sóc chó ban ngày này, hãy xác định endTime là buổi trưa nhưng bỏ qua startTime. Điều này cho phép tài xế quay lại trung tâm giữ trẻ ngay sau lần trả khách cuối cùng. |