Hướng dẫn này cho thấy các cách sử dụng có thể có của thuộc tính chuyển đổi. Bài viết này sẽ hướng dẫn bạn cách mô hình hoá các tình huống thực tế trên hai ví dụ: kết hợp thời gian đỗ xe vào các tuyến đường được tối ưu hoá và đảm bảo rằng mỗi tuyến đường kết thúc bằng một lượt truy cập vào một vị trí cụ thể.
Trước khi bắt đầu
Bạn sử dụng thuộc tính chuyển đổi để thêm chi phí và độ trễ dành riêng cho mô hình vào một số chuyển đổi nhất định trong các tuyến được tối ưu hoá. Các chi phí và độ trễ này được thêm vào thời lượng chuyển đổi và chi phí được tính toán từ dữ liệu bản đồ dựa trên các tham số của xe được sử dụng.
Chuyển đổi là đoạn của tuyến kết nối một vị trí với vị trí tiếp theo.
Vị trí đề cập đến bất kỳ điểm nào sau đây trong tuyến đường của xe:
- Điểm bắt đầu của tuyến đường.
- Điểm dừng để lấy hàng hoặc giao hàng.
- Điểm cuối của tuyến đường.
Bạn xác định tất cả thuộc tính chuyển đổi cho mô hình bằng cách thêm các thuộc tính đó vào danh sách ShipmentModel.transition_attributes
.
Mỗi phần tử của danh sách xác định một nhóm thuộc tính chuyển đổi và nhóm này được so khớp với các chuyển đổi trong tuyến bằng cách sử dụng thẻ ở vị trí bắt đầu và vị trí kết thúc của chuyển đổi. Để tìm hiểu thêm về các thuộc tính chuyển đổi, hãy xem tài liệu tham khảo về TransitionAttributes
.
Mô hình hoá các tình huống thực tế
Phần này trình bày hai ví dụ nhỏ về cách triển khai các quy tắc ràng buộc kinh doanh thực tế bằng cách sử dụng các thuộc tính chuyển đổi.
Đặt trước thời gian đỗ xe
Trong trường hợp này, người lái xe cần đỗ xe trước khi có thể đến vị trí A. Vị trí B ở gần đó và người lái xe có thể sử dụng cùng một điểm đỗ xe cho cả hai lần ghé thăm. Nếu người lái xe ghé thăm B ngay sau A, họ sẽ tiết kiệm được thời gian vì không cần rời khỏi điểm đỗ xe và đỗ xe lại. Trong Route Optimization API, bạn có thể sử dụng các thuộc tính chuyển đổi để thêm thời gian đỗ xe chỉ khi người lái xe di chuyển từ một điểm đỗ xe sang điểm đỗ xe khác.
Khi mô hình hoá thời gian đỗ xe tách biệt với thời lượng truy cập, bạn sẽ tạo các tuyến đường mà các lượt truy cập sử dụng cùng một bãi đỗ xe được nhóm lại với nhau và mất ít thời gian hơn. Bạn giúp mô hình chính xác hơn và cũng giúp trình tối ưu hoá ưu tiên các tuyến có lượt truy cập được nhóm lại.
Hãy làm theo các bước sau để thực hiện việc này trong yêu cầu API Tối ưu hoá tuyến đường:
Chỉ sử dụng
VisitRequest.duration
trong khoảng thời gian cần thiết để thực hiện lượt truy cập. Ví dụ: để giao gói hàng và thu thập chữ ký của khách hàng.Đối với mỗi điểm đỗ xe riêng biệt được sử dụng trong mô hình, hãy sử dụng một thẻ mới không được dùng cho bất kỳ mục nào khác trong mô hình, ví dụ:
PARKING_123
.Thêm thẻ này vào phần sau:
VisitRequest.tags
trong tất cả các yêu cầu truy cập sử dụng điểm đỗ xe này.Vehicle.start_tags
nếu xe bắt đầu tuyến tại điểm đỗ xe này.Vehicle.end_tags
nếu xe bắt đầu kết thúc tuyến tại điểm đỗ xe này.
Đối với mỗi thẻ đỗ xe mới, hãy thêm một mục vào
ShipmentModel.transition_attributes
để thêm độ trễ khi đỗ xe khi đến từ một điểm đỗ xe khác bằng cách làm như sau:Đặt
TransitionAttributes.excluded_src_tag
vàTransitionAttributes.dst_tag
thànhPARKING_123
.Đặt
TransitionAttributes.delay
thành thời gian cần thiết để đỗ xe.
Ví dụ: khi thẻ của một vị trí là
PARKING_123
và mất 150 giây để đỗ xe, bạn sẽ thêm mục nhập sau vàoShipmentModel.transition_attributes
:{ "excluded_src_tag": "PARKING_123", "dst_tag": "PARKING_123", "delay": "150s" }
Bắt buộc phải vệ sinh xe khi kết thúc tuyến
Trong trường hợp này, xe cần được vệ sinh khi kết thúc tuyến đường, với các điều kiện ràng buộc bổ sung sau:
- Việc vệ sinh được thực hiện tại một cơ sở vệ sinh chuyên biệt trước khi trở lại kho xe. Tuyến đường được tối ưu hoá sử dụng cơ sở vệ sinh tốt nhất dựa trên vị trí của cơ sở đó và vị trí của các điểm đến lấy hàng và giao hàng của xe.
- Sau khi vệ sinh, xe không được thực hiện thêm bất kỳ lượt lấy hàng hoặc giao hàng nào.
- Thời gian lái xe đến đó và vệ sinh xe được tính vào giờ làm việc của người lái xe và phải phù hợp với thời lượng tối đa của tuyến đường.
Bạn mô hình hoá yêu cầu này bằng cách chỉ cho phép các tuyến trống hoặc có lượt truy cập gần đây nhất là đến một cơ sở vệ sinh. Trong API Tối ưu hoá tuyến đường, bạn thực hiện việc này bằng cách cấm chuyển đổi đến điểm cuối của tuyến đường từ bất kỳ vị trí nào ngoại trừ cơ sở vệ sinh hoặc từ điểm bắt đầu của tuyến đường:
- Chọn hai thẻ mới không được sử dụng ở bất kỳ đâu trong mô hình, ví dụ:
CLEANED
vàROUTE_END
. Vị trí đầu tiên là vị trí xe đang hoặc đã sạch, còn vị trí thứ hai là vị trí kết thúc tuyến. - Đối với mỗi xe, hãy thêm một lô hàng chỉ giao hàng mới đại diện cho lượt ghé thăm một cơ sở vệ sinh với các thuộc tính sau:
- Mỗi vị trí của cơ sở vệ sinh phải được biểu thị dưới dạng một yêu cầu đến giao hàng của lô hàng này.
- Thêm
CLEANED
vàoVisitRequest.tags
của từng yêu cầu đến thăm của lô hàng thiết bị vệ sinh. Điều này cho biết rằng xe rời khỏi vị trí này đã được làm sạch. Các yêu cầu thăm viếng khác trong mô hình không được sử dụng thẻ này để xe được coi là "không sạch" khi rời khỏi các yêu cầu đó. - Cho phép trình tối ưu hoá bỏ qua lô hàng này khi xe không được sử dụng bằng cách đặt
penalty_cost
thành một con số nhỏ.
Đối với mỗi xe, hãy thêm
CLEANED
vàoVehicle.start_tags
. Thuộc tính này dùng để đánh dấu xe là sạch trước khi xe thực hiện bất kỳ lượt lấy hàng hoặc giao hàng nào, giả sử xe đã được dọn dẹp vào cuối ngày làm việc trước đó và cho phép xe đi từ điểm trung gian bắt đầu đến điểm trung gian kết thúc. Ngay cả khi các tuyến đường như vậy không xảy ra trong thực tế, việc cho phép trường hợp này sẽ giúp trình tối ưu hoá tìm kiếm các tuyến đường được tối ưu hoá một cách hiệu quả hơn.Đối với mỗi xe, hãy thêm
ROUTE_END
vàoVehicle.end_tags
.Thêm một mục mới vào
ShipmentModel.transition_attributes
để cấm xe đến điểm cuối của xe khi xe không sạch, với các thuộc tính sau:Đặt
TransitionAttributes.excluded_src_tag
thànhCLEANED
.Đặt
TransitionAttributes.dst_tag
thànhROUTE_END
.Đặt
TransitionAttributes.delay
thành một giá trị lớn. Khi bạn đặt độ trễ dài hơn thời lượng tuyến đường tối đa, bạn sẽ ngăn trình tối ưu hoá sử dụng quá trình chuyển đổi này trong một tuyến đường một cách hiệu quả.
Ví dụ: khi quy mô thời gian của mô hình là một ngày làm việc, bạn có thể sử dụng độ trễ 24 giờ (86400 giây) để cấm chuyển đổi đến cuối tuyến từ bất kỳ vị trí nào ngoại trừ cơ sở vệ sinh và điểm bắt đầu tuyến:
{ "excluded_src_tag": "CLEANED", "dst_tag": "ROUTE_END", "delay": "86400s" }
Cách chọn giữa độ trễ và chi phí
Việc lựa chọn giữa độ trễ và chi phí phụ thuộc vào bản chất của logic nghiệp vụ và các quy tắc ràng buộc đã triển khai. Bạn nên đặt TransitionAttributes.delay
để triển khai các quy tắc ràng buộc cứng hoặc để thể hiện sự đánh đổi về thời gian.
TransitionAttributes.cost
phù hợp hơn khi triển khai các lựa chọn ưu tiên mềm hoặc sự đánh đổi được thể hiện dưới dạng chi phí bổ sung. Bạn có thể kết hợp độ trễ và chi phí một cách tuỳ ý khi quan tâm đến cả thời gian và chi phí.
Ví dụ về việc rửa xe sử dụng độ trễ rất dài, vì việc rửa xe ở cuối tuyến là một yêu cầu bắt buộc và độ trễ dài khiến trình tối ưu hoá không thể bỏ qua yêu cầu này. Nếu bạn chỉ đặt chi phí, thì trình tối ưu hoá có thể chọn bỏ qua việc vệ sinh nếu tìm được cách bù đắp chi phí ở nơi khác, chẳng hạn như bằng cách giao thêm nhiều lô hàng trong thời gian "tiết kiệm được" do không vệ sinh xe.
Ví dụ về việc đỗ xe sử dụng độ trễ ngắn tương ứng với thời gian bổ sung cần thiết để đỗ xe. Bạn cũng có thể sử dụng chi phí kết hợp với độ trễ, nếu người lái xe dừng tại bãi đỗ xe có tính phí.
Cách thêm thuộc tính chuyển đổi khớp với tất cả yêu cầu truy cập
Các ví dụ ở trên sử dụng các thuộc tính chuyển đổi khớp với các vị trí có một thẻ nhất định hoặc các vị trí không có thẻ. Nhưng nếu bạn cần thêm các thuộc tính chuyển đổi áp dụng cho tất cả các chuyển đổi thì sao?
Bạn không thể bỏ qua các thẻ này vì mỗi thông báo TransitionAttributes
phải có một trong các thẻ TransitionAttributes.src_tag
và TransitionAttributes.excluded_src_tag
, cũng như một trong các thẻ TransitionAttributes.dst_tag
và TransitionAttributes.excluded_dst_tag
.
Tuy nhiên, bạn có thể so khớp tất cả thẻ bằng cách đặt
TransitionAttributes.excluded_src_tag
hoặc
TransitionAttributes.excluded_dst_tag
thành một thẻ không được sử dụng ở bất kỳ đâu trong mô hình. Thao tác này sẽ khớp với tất cả các vị trí không có thẻ này, nhưng vì bạn đã chọn một thẻ không được vị trí nào sử dụng, nên các thuộc tính chuyển đổi này sẽ khớp với tất cả các vị trí.