Perform continuous optimization

Continuous optimization is a process that repeatedly performs re-optimization to get a continuously updated plan used for route planning. For example, when executing a Fleet Routing plan, some real-world situations might result in the plan being infeasible such as a vehicle breaking down or new (previously unplanned) orders being received. Continuous optimization is used to generate new plans that capture these updates to help planners and drivers deal with the changes.

The current states of shipments and vehicles when executing routes are key for a successful re-optimization. For each visit, a route can be in one of three states:

  • Completed: A visit is done. In a re-optimization, completed visits aren't considered.
  • Committed: The driver plans to execute these visits. In a re-optimization, the visit sequence of committed visits isn't changed, but the time window of their visit time can be updated.
  • Non-committed: The driver hasn't committed to these visits. In a re-optimization, non-committed visits might be re-ordered or even assigned to other vehicles.

The Data-Driven Optimization API uses the RouteCommitments field within a vehicle to record the information.

Continuous optimization example

Step 1: Create resources

This example describes the steps to perform a basic workflow of a continuous operation. You begin with creating resources such as workspaces, shipments, and vehicles to prepare the initial optimization. In the following example, we create a workspace with one vehicle and three shipments.

Create a workspace.

REST

Before using any of the request data, make the following replacements:

  • PROJECT_NUMBER: your project number.

HTTP method and URL:

POST https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces

Request JSON body:

{
  "displayName": "workspace-1"
}

To send your request, choose one of these options:

curl

Save the request body in a file named request.json, and execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces"

PowerShell

Save the request body in a file named request.json, and execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces" | Select-Object -Expand Content

You should receive a successful status code (2xx) and an empty response.

Python

Before trying this sample, follow the setup instructions for this language on the Client Libraries page.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import optimization_v1


def sample_create_workspace():
    # Create a client
    client = optimization_v1.StatefulFleetRoutingClient()

    # Initialize request argument(s)
    request = optimization_v1.CreateWorkspaceRequest(
        parent="parent_value",
    )

    # Make the request
    response = client.create_workspace(request=request)

    # Handle the response
    print(response)

    

Create a vehicle.

REST

Before using any of the request data, make the following replacements:

  • PROJECT_NUMBER: your project number.

HTTP method and URL:

POST https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/vehicles

Request JSON body:

{
  "displayName": "vehicle_1",
  "startLocation": {
    "latitude": 37.405268056557034,
    "longitude": -122.02057849549489
  },
  "endLocation": {
    "latitude": 37.405268056557034,
    "longitude": -122.02057849549489
  },
  "loadLimits": {
    "weight": {
      "maxLoad": "100"
    }
  }
}

To send your request, choose one of these options:

curl

Save the request body in a file named request.json, and execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/vehicles"

PowerShell

Save the request body in a file named request.json, and execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/vehicles" | Select-Object -Expand Content

You should receive a successful status code (2xx) and an empty response.

Python

Before trying this sample, follow the setup instructions for this language on the Client Libraries page.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import optimization_v1


def sample_create_vehicle():
    # Create a client
    client = optimization_v1.StatefulFleetRoutingClient()

    # Initialize request argument(s)
    request = optimization_v1.CreateVehicleRequest(
        parent="parent_value",
    )

    # Make the request
    response = client.create_vehicle(request=request)

    # Handle the response
    print(response)

    

Create three shipments that must be picked up and delivered. Show the sample code for creating one shipment, and the other two shipments are created with similar code but different payloads.

REST

Before using any of the request data, make the following replacements:

  • PROJECT_NUMBER: your project number.

HTTP method and URL:

POST https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/shipments

Request JSON body:

{
  "displayName": "shipment_1",
  "pickups": [
    {
      "arrivalLocation": {
        "latitude": 37.42376807113943,
        "longitude": -122.08044232493486
      },
      "timeWindows": [
        {
          "startTime": "2022-08-02T08:00:00Z",
          "endTime": "2022-08-02T08:30:00Z"
        }
      ],
      "duration": "300s"
    }
  ],
  "deliveries": [
    {
      "arrivalLocation": {
        "latitude": 37.51635149414521,
        "longitude": -122.03173566402883
      },
      "timeWindows": [
        {
          "startTime": "2022-08-02T13:30:00Z",
          "endTime": "2022-08-02T15:00:00Z"
        }
      ],
      "duration": "300s"
    }
  ],
  "loadDemands": {
    "weight": {
      "amount": "20"
    }
  }
}

To send your request, choose one of these options:

curl

Save the request body in a file named request.json, and execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/shipments"

PowerShell

Save the request body in a file named request.json, and execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/shipments" | Select-Object -Expand Content

You should receive a successful status code (2xx) and an empty response.

Python

Before trying this sample, follow the setup instructions for this language on the Client Libraries page.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import optimization_v1


def sample_create_shipment():
    # Create a client
    client = optimization_v1.StatefulFleetRoutingClient()

    # Initialize request argument(s)
    request = optimization_v1.CreateShipmentRequest(
        parent="parent_value",
    )

    # Make the request
    response = client.create_shipment(request=request)

    # Handle the response
    print(response)

    

Create an optimizer for running optimizations.

REST

Before using any of the request data, make the following replacements:

  • PROJECT_NUMBER: your project number.

HTTP method and URL:

POST https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/optimizers

Request JSON body:

{
  "displayName": "Optimizer_1",
  "modelSpec": {
    "globalStartTime": "2022-08-01T08:30:00Z",
    "globalEndTime": "2022-08-05T08:30:00Z"
  },
  "optimizeToursSpec": {
    "timeout": "20s"
  }
}

To send your request, choose one of these options:

curl

Save the request body in a file named request.json, and execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/optimizers"

PowerShell

Save the request body in a file named request.json, and execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/optimizers" | Select-Object -Expand Content

You should receive a successful status code (2xx) and an empty response.

Python

Before trying this sample, follow the setup instructions for this language on the Client Libraries page.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import optimization_v1


def sample_create_optimizer():
    # Create a client
    client = optimization_v1.StatefulFleetRoutingClient()

    # Initialize request argument(s)
    request = optimization_v1.CreateOptimizerRequest(
        parent="parent_value",
    )

    # Make the request
    response = client.create_optimizer(request=request)

    # Handle the response
    print(response)

    

Step 2: Run an optimizer to get the initial plan

Run the optimizer, and get an initial plan for picking up and delivering the shipments.

REST

Before using any of the request data, make the following replacements:

  • project-number: your project number.

HTTP method and URL:

POST https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/workspace/optimizers/optimizer:run

To send your request, choose one of these options:

curl

Execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d "" \
"https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/workspace/optimizers/optimizer:run"

PowerShell

Execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-Uri "https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/workspace/optimizers/optimizer:run" | Select-Object -Expand Content

Your output looks similar to the following with extra fields. You can use the operation ID (54321, in this case) to get the status of the task. For example, see Working with long-running operations:

{
  "name": "projects/project-number/operations/54321",
}

After the long-running operation completes you can find a response similar to the following, which contains the solution ID (12345, in this case):

{
  "name": "projects/project-number/operations/54321",
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.optimization.v1.RunOptimizerResponse",
    "solution": "projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/solutions/12345>"
  }
}

With the provided solution ID, you can retrieve solution details by calling GetSolution method. In the solution, we can find the initial planned routes. An example of the generated routes is:

"routes": [
  {
    "vehicleStartTime": "2022-08-02T07:51:00Z",
    "vehicleEndTime": "2022-08-02T14:00:34Z",
    "visits": [
      {
        "isPickup": true,
        "startTime": "2022-08-02T08:00:00Z",
        "detour": "0s",
        "loadDemands": {
          "weight": {
            "amount": "20"
          }
        },
        "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/5980780305148018689"
      },
      {
        "isPickup": true,
        "startTime": "2022-08-02T08:05:00Z",
        "detour": "300s",
        "loadDemands": {
          "weight": {
            "amount": "20"
          }
        },
        "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/1"
      },
      {
        "isPickup": true,
        "startTime": "2022-08-02T08:10:00Z",
        "detour": "600s",
        "loadDemands": {
          "weight": {
            "amount": "20"
          }
        },
        "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/-6485183463413514239"
      },
      {
        "startTime": "2022-08-02T09:30:00Z",
        "detour": "3822s",
        "loadDemands": {
          "weight": {
            "amount": "-20"
          }
        },
        "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/-6485183463413514239"
      },
      {
        "startTime": "2022-08-02T10:30:00Z",
        "detour": "7897s",
        "loadDemands": {
          "weight": {
            "amount": "-20"
          }
        },
        "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/5980780305148018689"
      },
      {
        "startTime": "2022-08-02T13:30:00Z",
        "detour": "17769s",
        "loadDemands": {
          "weight": {
            "amount": "-20"
          }
        },
        "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/1"
      }
    ],
    "transitions": [
      {
        "travelDuration": "540s",
        "travelDistanceMeters": 10040,
        "waitDuration": "0s",
        "totalDuration": "540s",
        "startTime": "2022-08-02T07:51:00Z",
        "vehicleLoads": {
          "weight": {}
        }
      },
      {
        "travelDuration": "0s",
        "waitDuration": "0s",
        "totalDuration": "0s",
        "startTime": "2022-08-02T08:05:00Z",
        "vehicleLoads": {
          "weight": {
            "amount": "20"
          }
        }
      },
      {
        "travelDuration": "0s",
        "waitDuration": "0s",
        "totalDuration": "0s",
        "startTime": "2022-08-02T08:10:00Z",
        "vehicleLoads": {
          "weight": {
            "amount": "40"
          }
        }
      },
      {
        "travelDuration": "678s",
        "travelDistanceMeters": 9211,
        "waitDuration": "3822s",
        "totalDuration": "4500s",
        "startTime": "2022-08-02T08:15:00Z",
        "vehicleLoads": {
          "weight": {
            "amount": "60"
          }
        }
      },
      {
        "travelDuration": "417s",
        "travelDistanceMeters": 1699,
        "waitDuration": "2883s",
        "totalDuration": "3300s",
        "startTime": "2022-08-02T09:35:00Z",
        "vehicleLoads": {
          "weight": {
            "amount": "40"
          }
        }
      },
      {
        "travelDuration": "1489s",
        "travelDistanceMeters": 29436,
        "waitDuration": "9011s",
        "totalDuration": "10500s",
        "startTime": "2022-08-02T10:35:00Z",
        "vehicleLoads": {
          "weight": {
            "amount": "20"
          }
        }
      },
      {
        "travelDuration": "1534s",
        "travelDistanceMeters": 29170,
        "waitDuration": "0s",
        "totalDuration": "1534s",
        "startTime": "2022-08-02T13:35:00Z",
        "vehicleLoads": {
          "weight": {}
        }
      }
    ],
    "metrics": {
      "performedShipmentCount": 3,
      "travelDuration": "4658s",
      "waitDuration": "15716s",
      "delayDuration": "0s",
      "breakDuration": "0s",
      "visitDuration": "1800s",
      "totalDuration": "22174s",
      "travelDistanceMeters": 79556,
      "maxLoads": {
        "weight": {
          "amount": "60"
        }
      }
    },
    "vehicleName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/vehicles/1"
  }
]

Python

Before trying this sample, follow the setup instructions for this language on the Client Libraries page.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import optimization_v1


def sample_run_optimizer():
    # Create a client
    client = optimization_v1.StatefulFleetRoutingClient()

    # Initialize request argument(s)
    request = optimization_v1.RunOptimizerRequest(
        name="name_value",
    )

    # Make the request
    operation = client.run_optimizer(request=request)

    print("Waiting for operation to complete...")

    response = operation.result()

    # Handle the response
    print(response)

    

Step 3: Update route commitments

While the vehicle is executing the plan, users might update the RouteCommitments to inform the service about the vehicle's execution states. The vehicle's executing states might include shipments that have been delivered and which have been committed. In this example, the vehicle fully commits to all the routes in the plan. Updating vehicles keeps these commitments current.

REST

Before using any of the request data, make the following replacements:

  • PROJECT_NUMBER: your project number.

HTTP method and URL:

POST https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/vehicles/VEHICLE_ID

Request JSON body:

{
  "routeCommitments": {
    "routeStartTime": "2022-08-02T07:51:00Z",
    "nextVisits": [
        {
          "isPickup": true,
          "startTime": "2022-08-02T08:00:00Z",
          "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/5980780305148018689"
        },
        {
          "isPickup": true,
          "startTime": "2022-08-02T08:05:00Z",
          "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/1"
        },
        {
          "isPickup": true,
          "startTime": "2022-08-02T08:10:00Z",
          "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/-6485183463413514239"
        },
        {
          "startTime": "2022-08-02T09:30:00Z",
          "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/-6485183463413514239"
        },
        {
          "startTime": "2022-08-02T10:30:00Z",
          "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/5980780305148018689"
        },
        {
          "startTime": "2022-08-02T13:30:00Z",
          "shipmentName": "projects/{project_number}/locations/us-central1/workspaces/2990390152574009345/shipments/1"
        }
    ] 
  }
}

To send your request, choose one of these options:

curl

Save the request body in a file named request.json, and execute the following command:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "x-goog-user-project: PROJECT_NUMBER" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/vehicles/VEHICLE_ID"

PowerShell

Save the request body in a file named request.json, and execute the following command:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred"; "x-goog-user-project" = "PROJECT_NUMBER" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://cloudoptimization.googleapis.com/v1/projects/PROJECT_NUMBER/locations/us-central1/workspaces/WORKSPACE_ID/vehicles/VEHICLE_ID" | Select-Object -Expand Content

You should receive a successful status code (2xx) and an empty response.

Python

Before trying this sample, follow the setup instructions for this language on the Client Libraries page.

# This snippet has been automatically generated and should be regarded as a
# code template only.
# It will require modifications to work:
# - It may require correct/in-range values for request initialization.
# - It may require specifying regional endpoints when creating the service
#   client as shown in:
#   https://googleapis.dev/python/google-api-core/latest/client_options.html
from google.cloud import optimization_v1


def sample_update_vehicle():
    # Create a client
    client = optimization_v1.StatefulFleetRoutingClient()

    # Initialize request argument(s)
    request = optimization_v1.UpdateVehicleRequest(
    )

    # Make the request
    response = client.update_vehicle(request=request)

    # Handle the response
    print(response)

    

Step 4: Add new shipments

You have new shipments coming. Therefore, use the CreateShipment method as demonstrated in Step 1 to add new shipments.

Step 5: Re-optimize and get an updated plan

With the commitments updated and shipments added, call RunOptimizer as demonstrated in Step 2 to re-optimize and get a new plan.

In the updated plan, the order of the committed shipments is retained, and the new shipments are added to the routes.