Mô hình hoá logic nghiệp vụ bằng các thuộc tính chuyển đổi

Hướng dẫn này trình bày các cách sử dụng có thể có của thuộc tính chuyển đổi. Hướng dẫn này sẽ dạy bạn cách mô hình hoá các tình huống thực tế thông qua 2 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 đều kết thúc bằng một lượt ghé thăm 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ễ theo từng mô hình vào một số chuyển đổi nhất định trong các tuyến đường được tối ưu hoá. Những chi phí và độ trễ này được cộng 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 thông số của xe được sử dụng.

Chuyển đổi là đoạn đường 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.
  • Một điểm dừng nơi bạn đến lấy hàng hoặc giao hàng.
  • Điểm kết thúc của tuyến đường.

Bạn xác định tất cả cá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ử trong danh sách xác định một nhóm thuộc tính chuyển đổi và được so khớp với các hiệu ứng chuyển đổi trong các tuyến đường bằng cách sử dụng thẻ trên vị trí bắt đầu và vị trí kết thúc của hiệu ứng 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 cho TransitionAttributes.

Mô hình hoá các tình huống thực tế

Phần này trình bày 2 ví dụ nhỏ về cách triển khai các ràng buộc kinh doanh trong thế giới thực 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 chỗ đỗ xe cho cả hai lần ghé thăm. Nếu lái xe đến B ngay sau khi đến A, họ sẽ tiết kiệm thời gian vì không cần rời khỏi chỗ đỗ 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 vị trí đỗ xe sang vị trí khác.

Khi lập mô hình thời gian đỗ xe riêng biệt với thời lượng của lượt ghé thăm, bạn sẽ tạo ra những tuyến đường mà các lượt ghé thăm sử dụng cùng một chỗ đỗ xe được nhóm lại với nhau và mất ít thời gian hơn. Bạn làm cho mô hình chính xác hơn và bạn cũng làm cho trình tối ưu hoá ưu tiên các tuyến đường mà các lượt ghé thăm đượ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 Route Optimization API:

  1. Chỉ sử dụng VisitRequest.duration trong thời gian cần thiết để thực hiện chuyến tham quan. Ví dụ: để giao gói hàng và thu thập chữ ký của khách hàng.

  2. Đối với mỗi vị trí đỗ xe riêng biệt được 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 đích nào khác trong mô hình, ví dụ: PARKING_123.

  3. Thêm thẻ này vào những nội dung sau:

    1. VisitRequest.tags trong tất cả các yêu cầu ghé thăm sử dụng vị trí đỗ xe này.

    2. Vehicle.start_tags nếu xe bắt đầu hành trình tại điểm đỗ xe này.

    3. Vehicle.end_tags nếu xe bắt đầu và kết thúc tuyến đường tại chỗ đỗ xe này.

  4. Đố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ễ cho việc đỗ xe khi đến từ một điểm đỗ xe khác bằng cách làm như sau:

    1. Đặt TransitionAttributes.excluded_src_tagTransitionAttributes.dst_tag thành PARKING_123.

    2. Đặ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 sau vào ShipmentModel.transition_attributes:

    {
      "excluded_src_tag": "PARKING_123",
      "dst_tag": "PARKING_123",
      "delay": "150s"
    }
    

Bắt buộc phải vệ sinh khi kết thúc tuyến đường

Trong trường hợp này, xe cần được vệ sinh vào cuối tuyến đường, với các 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 xe quay trở lại kho xe. Tuyến đường được tối ưu hoá sẽ 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 và giao hàng mà xe thực hiện.
  • Sau khi vệ sinh, xe không được thực hiện thêm bất kỳ hoạt động đón 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 nằm trong khoảng thời gian 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 đường trống hoặc có lượt ghé thăm cuối cùng là cơ sở vệ sinh. Trong Route Optimization API, bạn thực hiện việc này bằng cách cấm chuyển đổi sang điểm tham chiếu kết thúc của tuyến đường từ mọi vị trí, ngoại trừ cơ sở vệ sinh hoặc điểm bắt đầu của tuyến đường:

  1. Chọn 2 thẻ mới chưa được dùng ở bất kỳ vị trí nào trong mô hình, ví dụ: CLEANEDROUTE_END. Cái trước là dành cho những vị trí mà xe đang hoặc sẽ được sạc, còn cái sau là dành cho điểm cuối của tuyến đường.
  2. Đối với mỗi chiếc xe, hãy thêm một lô hàng mới chỉ giao hàng, thể hiện lượt ghé thăm cơ sở vệ sinh bằng các thuộc tính sau:
    1. Mỗi vị trí của cơ sở vệ sinh phải được thể hiện dưới dạng một yêu cầu ghé thăm để giao hàng của lô hàng này.
    2. Thêm CLEANED vào VisitRequest.tags của mỗi yêu cầu đến thăm lô hàng của cơ sở vệ sinh. Thông tin này cho biết rằng một chiếc xe rời khỏi vị trí này là xe sạch. Các yêu cầu khác về lượt ghé thăm 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 đó.
    3. 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 số nhỏ.
  3. Đối với mỗi chiếc xe, hãy thêm CLEANED vào Vehicle.start_tags. Thuộc tính này dùng để đánh dấu xe là sạch sẽ trước khi thực hiện bất kỳ hoạt động lấy hàng hoặc giao hàng nào, giả sử xe đã được vệ sinh vào cuối ngày làm việc trước đó và cho phép xe đi từ điểm tham chiếu bắt đầu trực tiếp đến điểm tham chiếu kết thúc. Ngay cả khi những tuyến đường như vậy không xảy ra trên 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.

  4. Đối với mỗi chiếc xe, hãy thêm ROUTE_END vào Vehicle.end_tags.

  5. Thêm một mục mới vào ShipmentModel.transition_attributes để ngăn xe đến điểm tham chiếu cuối của xe khi xe không sạch, với các thuộc tính sau:

    1. Đặt TransitionAttributes.excluded_src_tag thành CLEANED.

    2. Đặt TransitionAttributes.dst_tag thành ROUTE_END.

    3. Đặt TransitionAttributes.delay thành một giá trị lớn. Khi đặt thời gian trễ dài hơn thời lượng tối đa của tuyến đường, 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.

    Ví dụ: khi thang 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) để ngăn quá trình chuyển đổi đến cuối tuyến đường từ bất kỳ vị trí nào, ngoại trừ cơ sở vệ sinh và điểm bắt đầu của tuyến đường:

    {
      "excluded_src_tag": "CLEANED",
      "dst_tag": "ROUTE_END",
      "delay": "86400s"
    }
    

Cách lựa chọn giữa thời gian 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 ràng buộc đã triển khai. Việc đặt TransitionAttributes.delay là phù hợp nhất để triển khai các ràng buộc cứng hoặc thể hiện sự đánh đổi về thời gian đã sử dụng. TransitionAttributes.cost phù hợp hơn khi triển khai các lựa chọn ưu tiên hoặc thoả hiệp mềm được thể hiện dưới dạng chi phí bổ sung. Bạn có thể kết hợp tuỳ ý giữa độ trễ và chi phí khi quan tâm đến cả thời gian đã sử dụng và chi phí.

Ví dụ về việc vệ sinh xe sử dụng độ trễ rất dài, vì việc vệ sinh xe ở cuối tuyến đường là một yêu cầu bắt buộc và độ trễ dài ngăn trình tối ưu hoá 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 nhiều lô hàng hơn trong thời gian "tiết kiệm" được do không vệ sinh xe.

Ví dụ về đỗ xe sử dụng một độ 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 costs kết hợp với delays nếu tài xế dừng ở bãi đỗ xe có tính phí.

Cách thêm một thuộc tính chuyển đổi khớp với tất cả các yêu cầu truy cập

Các ví dụ trên sử dụng thuộc tính chuyển đổi khớp với những vị trí có một thẻ nhất định hoặc những 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 hiệu ứng chuyển đổi thì sao?

Bạn không thể chỉ bỏ qua các thẻ, vì mỗi thông báo TransitionAttributes phải có một trong các thẻ TransitionAttributes.src_tagTransitionAttributes.excluded_src_tag, cũng như một trong các thẻ TransitionAttributes.dst_tagTransitionAttributes.excluded_dst_tag.

Tuy nhiên, bạn có thể so khớp tất cả cá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 dùng ở bất kỳ vị trí nào trong mô hình. Thao tác này sẽ khớp tất cả vị trí không có thẻ này, nhưng vì bạn cố ý chọn một thẻ mà không vị trí nào sử dụng, nên các thuộc tính chuyển đổi này sẽ khớp tất cả vị trí.

Tài liệu đọc thêm