Adding reload points in Google Cloud Fleet Routing API (Optimization AI)

91 views Asked by At

I'm migrating from or-tools to Google's Cloud Fleet Routing API (Optimization AI API). So far, the client libraries are not the best, nor do they have good documentation. Looking through the REST documentation (https://cloud.google.com/optimization/docs/), it's very unclear to me how I add reload points to offload capacity. If I have 5 pickups, and I specify a Delivery (assuming that's what a reload point is), the delivery shipment is skipped UNLESS the loadDemand exactly matches capacity of the vehicle at the time - which is not possible to predict. If we set loadDemand=capacity of the vehicle, it will go to the reload point ONLY when full. Does anyone know how to use this API and how to handle loadDemand to set capacity to 0 at whichever time makes sense for the vehicle? It's somewhat straightforward in or-tools.

1

There are 1 answers

0
OndraSej On

The difference between the or-tools APIs and the Cloud Fleet Routing (CFR) API is that the CFR API is primarily build around the notion of transporting items from a pickup location to a delivery location. That is also how vehicle capacities and load demands are handled, i.e. the load demands of the shipment is subtracted from the free vehicle capacity on pickup, and it is added back on delivery. Both pickup and delivery are optional in the API, but if you don't specify them, it just means that they happen implicitly at the beginning of the route (for pickups), resp. at the end of the route (for deliveries).

With this in mind, I'd model the item collection at customer site & drop-off at a reload point by making each item a shipment that has a single pickup (at the customer address), and multiple delivery alternatives (at the different reload points). This way, the load of each item will be tracked exactly for the time it is on a vehicle, and the vehicles will be able to drop the shipments whenever it is convenient at one of the delivery addresses (when they get close to one and/or they need free capacity). If the vehicle can take the items to the depot at the end of the day, the depot address should be one of the delivery locations.

The solver will put the deliveries as needed (when the vehicle is close to a full capacity) or when convenient (when passing by a reload point), but you can also add costs to make them delivered sooner rather than later - for example, by using soft time windows on the deliveries or pickup to delivery detour limits on the shipments.

An example of such a model (where the depot is not a reload point):

{
  "model": {
    "globalStartTime": "2024-03-14T08:00:00Z",
    "globalEndTime": "2024-03-14T18:00:00Z",
    "shipments": [
      {
        "pickups": {
          "arrivalLocation": {
            "latitude": 48.861259760341575,
            "longitude": 2.3348834783959296
          },
          "duration": "300s"
        },
        "deliveries": [
          {
            "arrivalLocation": {
              "latitude": 48.876500824124406,
              "longitude": 2.3237844310178786
            },
            "duration": "30s"
          },
          {
            "arrivalLocation": {
              "latitude": 48.880328892730084,
              "longitude": 2.3540664745794273
            },
            "duration": "30s"
          },
          {
            "arrivalLocation": {
              "latitude": 48.87667781897535,
              "longitude": 2.3596698683308706
            },
            "duration": "30s"
          }
        ],
        "loadDemands": {
          "packages": {
            "amount": "1"
          }
        }
      }
    ],
    "vehicles": [
      {
        "startLocation": {
          "latitude": 48.87683133258192,
          "longitude": 2.330044416972326
        },
        "endLocation": {
          "latitude": 48.87683133258192,
          "longitude": 2.330044416972326
        },
        "loadLimits": {
          "packages": {
            "maxLoad": "10"
          }
        }
      }
    ]
  },
  "searchMode": "CONSUME_ALL_AVAILABLE_TIME"
}