update notebooks

This commit is contained in:
Mizux Seiha
2025-02-04 18:04:03 +01:00
parent a0aab3d8a4
commit 38b08637f4
290 changed files with 3005 additions and 951 deletions

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -132,7 +132,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -0,0 +1,126 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2025 Google LLC."
]
},
{
"cell_type": "markdown",
"id": "apache",
"metadata": {},
"source": [
"Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"you may not use this file except in compliance with the License.\n",
"You may obtain a copy of the License at\n",
"\n",
" http://www.apache.org/licenses/LICENSE-2.0\n",
"\n",
"Unless required by applicable law or agreed to in writing, software\n",
"distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"See the License for the specific language governing permissions and\n",
"limitations under the License.\n"
]
},
{
"cell_type": "markdown",
"id": "basename",
"metadata": {},
"source": [
"# set_cover"
]
},
{
"cell_type": "markdown",
"id": "link",
"metadata": {},
"source": [
"<table align=\"left\">\n",
"<td>\n",
"<a href=\"https://colab.research.google.com/github/google/or-tools/blob/main/examples/notebook/algorithms/set_cover.ipynb\"><img src=\"https://raw.githubusercontent.com/google/or-tools/main/tools/colab_32px.png\"/>Run in Google Colab</a>\n",
"</td>\n",
"<td>\n",
"<a href=\"https://github.com/google/or-tools/blob/main/ortools/algorithms/samples/set_cover.py\"><img src=\"https://raw.githubusercontent.com/google/or-tools/main/tools/github_32px.png\"/>View source on GitHub</a>\n",
"</td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"id": "doc",
"metadata": {},
"source": [
"First, you must install [ortools](https://pypi.org/project/ortools/) package in this colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "install",
"metadata": {},
"outputs": [],
"source": [
"%pip install ortools"
]
},
{
"cell_type": "markdown",
"id": "description",
"metadata": {},
"source": [
"\n",
"A simple set-covering problem.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "code",
"metadata": {},
"outputs": [],
"source": [
"from ortools.algorithms.python import set_cover\n",
"\n",
"\n",
"def main():\n",
" model = set_cover.SetCoverModel()\n",
" model.add_empty_subset(2.0)\n",
" model.add_element_to_last_subset(0)\n",
" model.add_empty_subset(2.0)\n",
" model.add_element_to_last_subset(1)\n",
" model.add_empty_subset(1.0)\n",
" model.add_element_to_last_subset(0)\n",
" model.add_element_to_last_subset(1)\n",
"\n",
" inv = set_cover.SetCoverInvariant(model)\n",
" greedy = set_cover.GreedySolutionGenerator(inv)\n",
" has_found = greedy.next_solution()\n",
" if not has_found:\n",
" print(\"No solution found by the greedy heuristic.\")\n",
" return\n",
" solution = inv.export_solution_as_proto()\n",
"\n",
" print(f\"Total cost: {solution.cost}\") # == inv.cost()\n",
" print(f\"Total number of selected subsets: {solution.num_subsets}\")\n",
" print(\"Chosen subsets:\")\n",
" for subset in solution.subset:\n",
" print(f\" {subset}\")\n",
"\n",
"\n",
"main()\n",
"\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -119,7 +119,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -91,6 +91,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def main():\n",
" # Constraint programming engine\n",
" solver = pywrapcp.Solver(\"CP is fun!\")\n",
@@ -155,7 +156,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -74,31 +74,31 @@
"source": [
"Capacitated Vehicle Routing Problem (CVRP).\n",
"\n",
" This is a sample using the routing library python wrapper to solve a CVRP\n",
" problem while allowing multiple trips, i.e., vehicles can return to a depot\n",
" to reset their load (\"reload\").\n",
"This is a sample using the routing library python wrapper to solve a CVRP\n",
"problem while allowing multiple trips, i.e., vehicles can return to a depot\n",
"to reset their load (\"reload\").\n",
"\n",
" A description of the CVRP problem can be found here:\n",
" http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"A description of the CVRP problem can be found here:\n",
"http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"\n",
" Distances are in meters.\n",
"Distances are in meters.\n",
"\n",
" In order to implement multiple trips, new nodes are introduced at the same\n",
" locations of the original depots. These additional nodes can be dropped\n",
" from the schedule at 0 cost.\n",
"In order to implement multiple trips, new nodes are introduced at the same\n",
"locations of the original depots. These additional nodes can be dropped\n",
"from the schedule at 0 cost.\n",
"\n",
" The max_slack parameter associated to the capacity constraints of all nodes\n",
" can be set to be the maximum of the vehicles' capacities, rather than 0 like\n",
" in a traditional CVRP. Slack is required since before a solution is found,\n",
" it is not known how much capacity will be transferred at the new nodes. For\n",
" all the other (original) nodes, the slack is then re-set to 0.\n",
"The max_slack parameter associated to the capacity constraints of all nodes\n",
"can be set to be the maximum of the vehicles' capacities, rather than 0 like\n",
"in a traditional CVRP. Slack is required since before a solution is found,\n",
"it is not known how much capacity will be transferred at the new nodes. For\n",
"all the other (original) nodes, the slack is then re-set to 0.\n",
"\n",
" The above two considerations are implemented in `add_capacity_constraints()`.\n",
"The above two considerations are implemented in `add_capacity_constraints()`.\n",
"\n",
" Last, it is useful to set a large distance between the initial depot and the\n",
" new nodes introduced, to avoid schedules having spurious transits through\n",
" those new nodes unless it's necessary to reload. This consideration is taken\n",
" into account in `create_distance_evaluator()`.\n",
"Last, it is useful to set a large distance between the initial depot and the\n",
"new nodes introduced, to avoid schedules having spurious transits through\n",
"those new nodes unless it's necessary to reload. This consideration is taken\n",
"into account in `create_distance_evaluator()`.\n",
"\n"
]
},
@@ -145,52 +145,69 @@
" (3, 7),\n",
" (6, 7),\n",
" (0, 8),\n",
" (7, 8)\n",
" (7, 8),\n",
" ]\n",
" # Compute locations in meters using the block dimension defined as follow\n",
" # Manhattan average block: 750ft x 264ft -> 228m x 80m\n",
" # here we use: 114m x 80m city block\n",
" # src: https://nyti.ms/2GDoRIe 'NY Times: Know Your distance'\n",
" data['locations'] = [(l[0] * 114, l[1] * 80) for l in _locations]\n",
" data['num_locations'] = len(data['locations'])\n",
" data['demands'] = \\\n",
" [0, # depot\n",
" -_capacity, # unload depot_first\n",
" -_capacity, # unload depot_second\n",
" -_capacity, # unload depot_third\n",
" -_capacity, # unload depot_fourth\n",
" -_capacity, # unload depot_fifth\n",
" 3, 3, # 1, 2\n",
" 3, 4, # 3, 4\n",
" 3, 4, # 5, 6\n",
" 8, 8, # 7, 8\n",
" 3, 3, # 9,10\n",
" 3, 3, # 11,12\n",
" 4, 4, # 13, 14\n",
" 8, 8] # 15, 16\n",
" data['time_per_demand_unit'] = 5 # 5 minutes/unit\n",
" data['time_windows'] = \\\n",
" [(0, 0), # depot\n",
" (0, 1000), # unload depot_first\n",
" (0, 1000), # unload depot_second\n",
" (0, 1000), # unload depot_third\n",
" (0, 1000), # unload depot_fourth\n",
" (0, 1000), # unload depot_fifth\n",
" (75, 850), (75, 850), # 1, 2\n",
" (60, 700), (45, 550), # 3, 4\n",
" (0, 800), (50, 600), # 5, 6\n",
" (0, 1000), (10, 200), # 7, 8\n",
" (0, 1000), (75, 850), # 9, 10\n",
" (85, 950), (5, 150), # 11, 12\n",
" (15, 250), (10, 200), # 13, 14\n",
" (45, 550), (30, 400)] # 15, 16\n",
" data['num_vehicles'] = 3\n",
" data['vehicle_capacity'] = _capacity\n",
" data['vehicle_max_distance'] = 10_000\n",
" data['vehicle_max_time'] = 1_500\n",
" data[\n",
" 'vehicle_speed'] = 5 * 60 / 3.6 # Travel speed: 5km/h to convert in m/min\n",
" data['depot'] = 0\n",
" data[\"locations\"] = [(l[0] * 114, l[1] * 80) for l in _locations]\n",
" data[\"num_locations\"] = len(data[\"locations\"])\n",
" data[\"demands\"] = [\n",
" 0, # depot\n",
" -_capacity, # unload depot_first\n",
" -_capacity, # unload depot_second\n",
" -_capacity, # unload depot_third\n",
" -_capacity, # unload depot_fourth\n",
" -_capacity, # unload depot_fifth\n",
" 3,\n",
" 3, # 1, 2\n",
" 3,\n",
" 4, # 3, 4\n",
" 3,\n",
" 4, # 5, 6\n",
" 8,\n",
" 8, # 7, 8\n",
" 3,\n",
" 3, # 9,10\n",
" 3,\n",
" 3, # 11,12\n",
" 4,\n",
" 4, # 13, 14\n",
" 8,\n",
" 8,\n",
" ] # 15, 16\n",
" data[\"time_per_demand_unit\"] = 5 # 5 minutes/unit\n",
" data[\"time_windows\"] = [\n",
" (0, 0), # depot\n",
" (0, 1000), # unload depot_first\n",
" (0, 1000), # unload depot_second\n",
" (0, 1000), # unload depot_third\n",
" (0, 1000), # unload depot_fourth\n",
" (0, 1000), # unload depot_fifth\n",
" (75, 850),\n",
" (75, 850), # 1, 2\n",
" (60, 700),\n",
" (45, 550), # 3, 4\n",
" (0, 800),\n",
" (50, 600), # 5, 6\n",
" (0, 1000),\n",
" (10, 200), # 7, 8\n",
" (0, 1000),\n",
" (75, 850), # 9, 10\n",
" (85, 950),\n",
" (5, 150), # 11, 12\n",
" (15, 250),\n",
" (10, 200), # 13, 14\n",
" (45, 550),\n",
" (30, 400),\n",
" ] # 15, 16\n",
" data[\"num_vehicles\"] = 3\n",
" data[\"vehicle_capacity\"] = _capacity\n",
" data[\"vehicle_max_distance\"] = 10_000\n",
" data[\"vehicle_max_time\"] = 1_500\n",
" data[\"vehicle_speed\"] = 5 * 60 / 3.6 # Travel speed: 5km/h to convert in m/min\n",
" data[\"depot\"] = 0\n",
" return data\n",
"\n",
"\n",
@@ -199,30 +216,29 @@
"#######################\n",
"def manhattan_distance(position_1, position_2):\n",
" \"\"\"Computes the Manhattan distance between two points\"\"\"\n",
" return (abs(position_1[0] - position_2[0]) +\n",
" abs(position_1[1] - position_2[1]))\n",
" return abs(position_1[0] - position_2[0]) + abs(position_1[1] - position_2[1])\n",
"\n",
"\n",
"def create_distance_evaluator(data):\n",
" \"\"\"Creates callback to return distance between points.\"\"\"\n",
" _distances = {}\n",
" # precompute distance between location to have distance callback in O(1)\n",
" for from_node in range(data['num_locations']):\n",
" for from_node in range(data[\"num_locations\"]):\n",
" _distances[from_node] = {}\n",
" for to_node in range(data['num_locations']):\n",
" for to_node in range(data[\"num_locations\"]):\n",
" if from_node == to_node:\n",
" _distances[from_node][to_node] = 0\n",
" # Forbid start/end/reload node to be consecutive.\n",
" elif from_node in range(6) and to_node in range(6):\n",
" _distances[from_node][to_node] = data['vehicle_max_distance']\n",
" _distances[from_node][to_node] = data[\"vehicle_max_distance\"]\n",
" else:\n",
" _distances[from_node][to_node] = (manhattan_distance(\n",
" data['locations'][from_node], data['locations'][to_node]))\n",
" _distances[from_node][to_node] = manhattan_distance(\n",
" data[\"locations\"][from_node], data[\"locations\"][to_node]\n",
" )\n",
"\n",
" def distance_evaluator(manager, from_node, to_node):\n",
" \"\"\"Returns the manhattan distance between the two nodes\"\"\"\n",
" return _distances[manager.IndexToNode(from_node)][manager.IndexToNode(\n",
" to_node)]\n",
" return _distances[manager.IndexToNode(from_node)][manager.IndexToNode(to_node)]\n",
"\n",
" return distance_evaluator\n",
"\n",
@@ -230,13 +246,14 @@
"def add_distance_dimension(routing, manager, data, distance_evaluator_index):\n",
" \"\"\"Add Global Span constraint\"\"\"\n",
" del manager\n",
" distance = 'Distance'\n",
" distance = \"Distance\"\n",
" routing.AddDimension(\n",
" distance_evaluator_index,\n",
" 0, # null slack\n",
" data['vehicle_max_distance'], # maximum distance per vehicle\n",
" data[\"vehicle_max_distance\"], # maximum distance per vehicle\n",
" True, # start cumul to zero\n",
" distance)\n",
" distance,\n",
" )\n",
" distance_dimension = routing.GetDimensionOrDie(distance)\n",
" # Try to minimize the max distance among vehicles.\n",
" # /!\\ It doesn't mean the standard deviation is minimized\n",
@@ -245,7 +262,7 @@
"\n",
"def create_demand_evaluator(data):\n",
" \"\"\"Creates callback to get demands at each location.\"\"\"\n",
" _demands = data['demands']\n",
" _demands = data[\"demands\"]\n",
"\n",
" def demand_evaluator(manager, from_node):\n",
" \"\"\"Returns the demand of the current node\"\"\"\n",
@@ -256,14 +273,15 @@
"\n",
"def add_capacity_constraints(routing, manager, data, demand_evaluator_index):\n",
" \"\"\"Adds capacity constraint\"\"\"\n",
" vehicle_capacity = data['vehicle_capacity']\n",
" capacity = 'Capacity'\n",
" vehicle_capacity = data[\"vehicle_capacity\"]\n",
" capacity = \"Capacity\"\n",
" routing.AddDimension(\n",
" demand_evaluator_index,\n",
" vehicle_capacity,\n",
" vehicle_capacity,\n",
" True, # start cumul to zero\n",
" capacity)\n",
" capacity,\n",
" )\n",
"\n",
" # Add Slack for reseting to zero unload depot nodes.\n",
" # e.g. vehicle with load 10/15 arrives at node 1 (depot unload)\n",
@@ -275,7 +293,7 @@
" routing.AddDisjunction([node_index], 0)\n",
"\n",
" # Allow to drop regular node with a cost.\n",
" for node in range(6, len(data['demands'])):\n",
" for node in range(6, len(data[\"demands\"])):\n",
" node_index = manager.NodeToIndex(node)\n",
" capacity_dimension.SlackVar(node_index).SetValue(0)\n",
" routing.AddDisjunction([node_index], 100_000)\n",
@@ -286,52 +304,56 @@
"\n",
" def service_time(data, node):\n",
" \"\"\"Gets the service time for the specified location.\"\"\"\n",
" return abs(data['demands'][node]) * data['time_per_demand_unit']\n",
" return abs(data[\"demands\"][node]) * data[\"time_per_demand_unit\"]\n",
"\n",
" def travel_time(data, from_node, to_node):\n",
" \"\"\"Gets the travel times between two locations.\"\"\"\n",
" if from_node == to_node:\n",
" travel_time = 0\n",
" else:\n",
" travel_time = manhattan_distance(\n",
" data['locations'][from_node],\n",
" data['locations'][to_node]) / data['vehicle_speed']\n",
" travel_time = (\n",
" manhattan_distance(\n",
" data[\"locations\"][from_node], data[\"locations\"][to_node]\n",
" )\n",
" / data[\"vehicle_speed\"]\n",
" )\n",
" return travel_time\n",
"\n",
" _total_time = {}\n",
" # precompute total time to have time callback in O(1)\n",
" for from_node in range(data['num_locations']):\n",
" for from_node in range(data[\"num_locations\"]):\n",
" _total_time[from_node] = {}\n",
" for to_node in range(data['num_locations']):\n",
" for to_node in range(data[\"num_locations\"]):\n",
" if from_node == to_node:\n",
" _total_time[from_node][to_node] = 0\n",
" else:\n",
" _total_time[from_node][to_node] = int(\n",
" service_time(data, from_node) +\n",
" travel_time(data, from_node, to_node))\n",
" service_time(data, from_node)\n",
" + travel_time(data, from_node, to_node)\n",
" )\n",
"\n",
" def time_evaluator(manager, from_node, to_node):\n",
" \"\"\"Returns the total time between the two nodes\"\"\"\n",
" return _total_time[manager.IndexToNode(from_node)][manager.IndexToNode(\n",
" to_node)]\n",
" return _total_time[manager.IndexToNode(from_node)][manager.IndexToNode(to_node)]\n",
"\n",
" return time_evaluator\n",
"\n",
"\n",
"def add_time_window_constraints(routing, manager, data, time_evaluator):\n",
" \"\"\"Add Time windows constraint\"\"\"\n",
" time = 'Time'\n",
" max_time = data['vehicle_max_time']\n",
" time = \"Time\"\n",
" max_time = data[\"vehicle_max_time\"]\n",
" routing.AddDimension(\n",
" time_evaluator,\n",
" max_time, # allow waiting time\n",
" max_time, # maximum time per vehicle\n",
" False, # don't force start cumul to zero since we are giving TW to start nodes\n",
" time)\n",
" time,\n",
" )\n",
" time_dimension = routing.GetDimensionOrDie(time)\n",
" # Add time window constraints for each location except depot\n",
" # and 'copy' the slack var in the solution object (aka Assignment) to print it\n",
" for location_idx, time_window in enumerate(data['time_windows']):\n",
" for location_idx, time_window in enumerate(data[\"time_windows\"]):\n",
" if location_idx == 0:\n",
" continue\n",
" index = manager.NodeToIndex(location_idx)\n",
@@ -339,70 +361,80 @@
" routing.AddToAssignment(time_dimension.SlackVar(index))\n",
" # Add time window constraints for each vehicle start node\n",
" # and 'copy' the slack var in the solution object (aka Assignment) to print it\n",
" for vehicle_id in range(data['num_vehicles']):\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" index = routing.Start(vehicle_id)\n",
" time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0],\n",
" data['time_windows'][0][1])\n",
" time_dimension.CumulVar(index).SetRange(\n",
" data[\"time_windows\"][0][0], data[\"time_windows\"][0][1]\n",
" )\n",
" routing.AddToAssignment(time_dimension.SlackVar(index))\n",
" # Warning: Slack var is not defined for vehicle's end node\n",
" #routing.AddToAssignment(time_dimension.SlackVar(self.routing.End(vehicle_id)))\n",
" # routing.AddToAssignment(time_dimension.SlackVar(self.routing.End(vehicle_id)))\n",
"\n",
"\n",
"###########\n",
"# Printer #\n",
"###########\n",
"def print_solution(data, manager, routing, assignment): # pylint:disable=too-many-locals\n",
"def print_solution(\n",
" data, manager, routing, assignment\n",
"): # pylint:disable=too-many-locals\n",
" \"\"\"Prints assignment on console\"\"\"\n",
" print(f'Objective: {assignment.ObjectiveValue()}')\n",
" print(f\"Objective: {assignment.ObjectiveValue()}\")\n",
" total_distance = 0\n",
" total_load = 0\n",
" total_time = 0\n",
" capacity_dimension = routing.GetDimensionOrDie('Capacity')\n",
" time_dimension = routing.GetDimensionOrDie('Time')\n",
" capacity_dimension = routing.GetDimensionOrDie(\"Capacity\")\n",
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" distance_dimension = routing.GetDimensionOrDie(\"Distance\")\n",
" dropped = []\n",
" for order in range(6, routing.nodes()):\n",
" index = manager.NodeToIndex(order)\n",
" if assignment.Value(routing.NextVar(index)) == index:\n",
" dropped.append(order)\n",
" print(f'dropped orders: {dropped}')\n",
" print(f\"dropped orders: {dropped}\")\n",
" dropped = []\n",
" for reload in range(1, 6):\n",
" index = manager.NodeToIndex(reload)\n",
" if assignment.Value(routing.NextVar(index)) == index:\n",
" dropped.append(reload)\n",
" print(f'dropped reload stations: {dropped}')\n",
" print(f\"dropped reload stations: {dropped}\")\n",
"\n",
" for vehicle_id in range(data['num_vehicles']):\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f'Route for vehicle {vehicle_id}:\\n'\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" load_value = 0\n",
" distance = 0\n",
" while not routing.IsEnd(index):\n",
" load_var = capacity_dimension.CumulVar(index)\n",
" time_var = time_dimension.CumulVar(index)\n",
" plan_output += (\n",
" f' {manager.IndexToNode(index)} '\n",
" f'Load({assignment.Min(load_var)}) '\n",
" f'Time({assignment.Min(time_var)},{assignment.Max(time_var)}) ->'\n",
" f\" {manager.IndexToNode(index)} \"\n",
" f\"Load({assignment.Min(capacity_dimension.CumulVar(index))}) \"\n",
" f\"Time({assignment.Min(time_var)},{assignment.Max(time_var)}) ->\"\n",
" )\n",
" previous_index = index\n",
" index = assignment.Value(routing.NextVar(index))\n",
" distance += routing.GetArcCostForVehicle(previous_index, index,\n",
" vehicle_id)\n",
" load_var = capacity_dimension.CumulVar(index)\n",
" distance += distance_dimension.GetTransitValue(previous_index, index, vehicle_id)\n",
" # capacity dimension TransitVar is negative at reload stations during replenishment\n",
" # don't want to consider those values when calculating the total load of the route\n",
" # hence only considering the positive values\n",
" load_value += max(0, capacity_dimension.GetTransitValue(previous_index, index, vehicle_id))\n",
" time_var = time_dimension.CumulVar(index)\n",
" plan_output += (\n",
" f' {manager.IndexToNode(index)} '\n",
" f'Load({assignment.Min(load_var)}) '\n",
" f'Time({assignment.Min(time_var)},{assignment.Max(time_var)})\\n')\n",
" plan_output += f'Distance of the route: {distance}m\\n'\n",
" plan_output += f'Load of the route: {assignment.Min(load_var)}\\n'\n",
" plan_output += f'Time of the route: {assignment.Min(time_var)}min\\n'\n",
" f\" {manager.IndexToNode(index)} \"\n",
" f\"Load({assignment.Min(capacity_dimension.CumulVar(index))}) \"\n",
" f\"Time({assignment.Min(time_var)},{assignment.Max(time_var)})\\n\"\n",
" )\n",
" plan_output += f\"Distance of the route: {distance}m\\n\"\n",
" plan_output += f\"Load of the route: {load_value}\\n\"\n",
" plan_output += f\"Time of the route: {assignment.Min(time_var)}min\\n\"\n",
" print(plan_output)\n",
" total_distance += distance\n",
" total_load += assignment.Min(load_var)\n",
" total_load += load_value\n",
" total_time += assignment.Min(time_var)\n",
" print(f'Total Distance of all routes: {total_distance}m')\n",
" print(f'Total Load of all routes: {total_load}')\n",
" print(f'Total Time of all routes: {total_time}min')\n",
" print(f\"Total Distance of all routes: {total_distance}m\")\n",
" print(f\"Total Load of all routes: {total_load}\")\n",
" print(f\"Total Time of all routes: {total_time}min\")\n",
"\n",
"\n",
"########\n",
@@ -414,15 +446,17 @@
" data = create_data_model()\n",
"\n",
" # Create the routing index manager\n",
" manager = pywrapcp.RoutingIndexManager(data['num_locations'],\n",
" data['num_vehicles'], data['depot'])\n",
" manager = pywrapcp.RoutingIndexManager(\n",
" data[\"num_locations\"], data[\"num_vehicles\"], data[\"depot\"]\n",
" )\n",
"\n",
" # Create Routing Model\n",
" routing = pywrapcp.RoutingModel(manager)\n",
"\n",
" # Define weight of each edge\n",
" distance_evaluator_index = routing.RegisterTransitCallback(\n",
" partial(create_distance_evaluator(data), manager))\n",
" partial(create_distance_evaluator(data), manager)\n",
" )\n",
" routing.SetArcCostEvaluatorOfAllVehicles(distance_evaluator_index)\n",
"\n",
" # Add Distance constraint to minimize the longuest route\n",
@@ -430,20 +464,24 @@
"\n",
" # Add Capacity constraint\n",
" demand_evaluator_index = routing.RegisterUnaryTransitCallback(\n",
" partial(create_demand_evaluator(data), manager))\n",
" partial(create_demand_evaluator(data), manager)\n",
" )\n",
" add_capacity_constraints(routing, manager, data, demand_evaluator_index)\n",
"\n",
" # Add Time Window constraint\n",
" time_evaluator_index = routing.RegisterTransitCallback(\n",
" partial(create_time_evaluator(data), manager))\n",
" partial(create_time_evaluator(data), manager)\n",
" )\n",
" add_time_window_constraints(routing, manager, data, time_evaluator_index)\n",
"\n",
" # Setting first solution heuristic (cheapest addition).\n",
" search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n",
" search_parameters.first_solution_strategy = (\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC\n",
" ) # pylint: disable=no-member\n",
" search_parameters.local_search_metaheuristic = (\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH\n",
" )\n",
" search_parameters.time_limit.FromSeconds(3)\n",
"\n",
" # Solve the problem.\n",
@@ -459,7 +497,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -75,12 +75,12 @@
"\n",
"Capacitated Vehicle Routing Problem with Time Windows (CVRPTW).\n",
"\n",
" This is a sample using the routing library python wrapper to solve a CVRPTW\n",
" problem.\n",
" A description of the problem can be found here:\n",
" http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"This is a sample using the routing library python wrapper to solve a CVRPTW\n",
"problem.\n",
"A description of the problem can be found here:\n",
"http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"\n",
" Distances are in meters and time in minutes.\n",
"Distances are in meters and time in minutes.\n",
"\n"
]
},
@@ -96,6 +96,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -303,6 +304,8 @@
" capacity_dimension = routing.GetDimensionOrDie(\"Capacity\")\n",
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" distance = 0\n",
@@ -386,7 +389,11 @@
" vehicle_break = data[\"breaks\"][v]\n",
" break_intervals[v] = [\n",
" routing.solver().FixedDurationIntervalVar(\n",
" 15, 100, vehicle_break[0], vehicle_break[1], f\"Break for vehicle {v}\"\n",
" 15,\n",
" 100,\n",
" vehicle_break[0],\n",
" vehicle_break[1],\n",
" f\"Break for vehicle {v}\",\n",
" )\n",
" ]\n",
" time_dimension.SetBreakIntervalsOfVehicle(\n",
@@ -414,7 +421,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def main(board_size):\n",
" # Creates the solver.\n",
" solver = pywrapcp.Solver(\"n-queens\")\n",
@@ -139,7 +140,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -86,6 +86,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def main():\n",
" \"\"\"Entry point of the program.\"\"\"\n",
" # Instantiate the solver.\n",
@@ -128,7 +129,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def main():\n",
" \"\"\"Entry point of the program.\"\"\"\n",
" # Instantiate the data problem.\n",
@@ -142,7 +143,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -91,6 +91,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -195,7 +196,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -88,6 +88,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -226,7 +227,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -122,8 +123,8 @@
" index = solution.Value(routing.NextVar(index))\n",
" route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)\n",
" plan_output += f\" {manager.IndexToNode(index)}\\n\"\n",
" print(plan_output)\n",
" plan_output += f\"Route distance: {route_distance}miles\\n\"\n",
" print(plan_output)\n",
"\n",
"\n",
"def main():\n",
@@ -171,7 +172,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -177,7 +178,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -75,12 +75,12 @@
"\n",
"Simple Vehicles Routing Problem (VRP).\n",
"\n",
" This is a sample using the routing library python wrapper to solve a VRP\n",
" problem.\n",
" A description of the problem can be found here:\n",
" http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"This is a sample using the routing library python wrapper to solve a VRP\n",
"problem.\n",
"A description of the problem can be found here:\n",
"http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"\n",
" Distances are in meters.\n",
"Distances are in meters.\n",
"\n"
]
},
@@ -95,6 +95,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -128,16 +129,18 @@
" \"\"\"Prints solution on console.\"\"\"\n",
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
" total_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" for vehicle_index in range(manager.GetNumberOfVehicles()):\n",
" if not routing.IsVehicleUsed(solution, vehicle_index):\n",
" continue\n",
" index = routing.Start(vehicle_index)\n",
" plan_output = f\"Route for vehicle {vehicle_index}:\\n\"\n",
" route_distance = 0\n",
" while not routing.IsEnd(index):\n",
" plan_output += f\" {manager.IndexToNode(index)} ->\"\n",
" previous_index = index\n",
" index = solution.Value(routing.NextVar(index))\n",
" route_distance += routing.GetArcCostForVehicle(\n",
" previous_index, index, vehicle_id\n",
" previous_index, index, vehicle_index\n",
" )\n",
" plan_output += f\" {manager.IndexToNode(index)}\\n\"\n",
" plan_output += f\"Distance of the route: {route_distance}m\\n\"\n",
@@ -194,7 +197,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -95,6 +95,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -145,6 +146,8 @@
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" total_time = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" while not routing.IsEnd(index):\n",
@@ -247,7 +250,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -73,14 +73,15 @@
"metadata": {},
"source": [
"Vehicles Routing Problem (VRP) with breaks relative to the vehicle start time.\n",
" Each vehicles start at T:15min, T:30min, T:45min and T:60min respectively.\n",
"\n",
" Each vehicle must perform a break lasting 5 minutes,\n",
" starting between 25 and 45 minutes after route start.\n",
" e.g. vehicle 2 starting a T:45min must start a 5min breaks\n",
" between [45+25,45+45] i.e. in the range [70, 90].\n",
"Each vehicles start at T:15min, T:30min, T:45min and T:60min respectively.\n",
"\n",
" Durations are in minutes.\n",
"Each vehicle must perform a break lasting 5 minutes,\n",
"starting between 25 and 45 minutes after route start.\n",
"e.g. vehicle 2 starting a T:45min must start a 5min breaks\n",
"between [45+25,45+45] i.e. in the range [70, 90].\n",
"\n",
"Durations are in minutes.\n",
"\n"
]
},
@@ -95,12 +96,13 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
" data['num_vehicles'] = 4\n",
" data['depot'] = 0\n",
" data['time_matrix'] = [\n",
" data[\"num_vehicles\"] = 4\n",
" data[\"depot\"] = 0\n",
" data[\"time_matrix\"] = [\n",
" [0, 27, 38, 34, 29, 13, 25, 9, 15, 9, 26, 25, 19, 17, 23, 38, 33],\n",
" [27, 0, 34, 15, 9, 25, 36, 17, 34, 37, 54, 29, 24, 33, 50, 43, 60],\n",
" [38, 34, 0, 49, 43, 25, 13, 40, 23, 37, 20, 63, 58, 56, 39, 77, 37],\n",
@@ -120,46 +122,50 @@
" [33, 60, 37, 67, 62, 35, 24, 42, 25, 23, 17, 42, 36, 26, 9, 39, 0],\n",
" ]\n",
" # 15 min of service time\n",
" data['service_time'] = [15] * len(data['time_matrix'])\n",
" data['service_time'][data['depot']] = 0\n",
" assert len(data['time_matrix']) == len(data['service_time'])\n",
" data[\"service_time\"] = [15] * len(data[\"time_matrix\"])\n",
" data[\"service_time\"][data[\"depot\"]] = 0\n",
" assert len(data[\"time_matrix\"]) == len(data[\"service_time\"])\n",
" return data\n",
"\n",
"\n",
"def print_solution(manager, routing, solution):\n",
" \"\"\"Prints solution on console.\"\"\"\n",
" print(f'Objective: {solution.ObjectiveValue()}')\n",
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
"\n",
" print('Breaks:')\n",
" print(\"Breaks:\")\n",
" intervals = solution.IntervalVarContainer()\n",
" for i in range(intervals.Size()):\n",
" brk = intervals.Element(i)\n",
" if brk.PerformedValue() == 1:\n",
" print(f'{brk.Var().Name()}: ' +\n",
" f'Start({brk.StartValue()}) Duration({brk.DurationValue()})')\n",
" print(\n",
" f\"{brk.Var().Name()}: \"\n",
" + f\"Start({brk.StartValue()}) Duration({brk.DurationValue()})\"\n",
" )\n",
" else:\n",
" print(f'{brk.Var().Name()}: Unperformed')\n",
" print(f\"{brk.Var().Name()}: Unperformed\")\n",
"\n",
" time_dimension = routing.GetDimensionOrDie('Time')\n",
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" total_time = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f'Route for vehicle {vehicle_id}:\\n'\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" while not routing.IsEnd(index):\n",
" time_var = time_dimension.CumulVar(index)\n",
" if routing.IsStart(index):\n",
" start_time = solution.Value(time_var)\n",
" plan_output += f'{manager.IndexToNode(index)} '\n",
" plan_output += f'Time({solution.Value(time_var)}) -> '\n",
" plan_output += f\"{manager.IndexToNode(index)} \"\n",
" plan_output += f\"Time({solution.Value(time_var)}) -> \"\n",
" index = solution.Value(routing.NextVar(index))\n",
" time_var = time_dimension.CumulVar(index)\n",
" plan_output += f'{manager.IndexToNode(index)} '\n",
" plan_output += f'Time({solution.Value(time_var)})'\n",
" plan_output += f\"{manager.IndexToNode(index)} \"\n",
" plan_output += f\"Time({solution.Value(time_var)})\"\n",
" print(plan_output)\n",
" route_time = solution.Value(time_var) - start_time\n",
" print(f'Time of the route: {route_time}min\\n')\n",
" print(f\"Time of the route: {route_time}min\\n\")\n",
" total_time += route_time\n",
" print(f'Total time of all routes: {total_time}min')\n",
" print(f\"Total time of all routes: {total_time}min\")\n",
"\n",
"\n",
"def main():\n",
@@ -168,20 +174,20 @@
" data = create_data_model()\n",
"\n",
" # Create the routing index manager.\n",
" manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']),\n",
" data['num_vehicles'], data['depot'])\n",
" manager = pywrapcp.RoutingIndexManager(\n",
" len(data[\"time_matrix\"]), data[\"num_vehicles\"], data[\"depot\"]\n",
" )\n",
"\n",
" # Create Routing Model.\n",
" routing = pywrapcp.RoutingModel(manager)\n",
"\n",
"\n",
" # Create and register a transit callback.\n",
" def time_callback(from_index, to_index):\n",
" \"\"\"Returns the travel time between the two nodes.\"\"\"\n",
" # Convert from routing variable Index to time matrix NodeIndex.\n",
" from_node = manager.IndexToNode(from_index)\n",
" to_node = manager.IndexToNode(to_index)\n",
" return data['time_matrix'][from_node][to_node]\n",
" return data[\"time_matrix\"][from_node][to_node]\n",
"\n",
" transit_callback_index = routing.RegisterTransitCallback(time_callback)\n",
"\n",
@@ -189,13 +195,14 @@
" routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)\n",
"\n",
" # Add Time Windows constraint.\n",
" time = 'Time'\n",
" time = \"Time\"\n",
" routing.AddDimension(\n",
" transit_callback_index,\n",
" 10, # need optional waiting time to place break\n",
" 180, # maximum time per vehicle\n",
" False, # Don't force start cumul to zero.\n",
" time)\n",
" time,\n",
" )\n",
" time_dimension = routing.GetDimensionOrDie(time)\n",
" time_dimension.SetGlobalSpanCostCoefficient(10)\n",
"\n",
@@ -209,27 +216,30 @@
" node_visit_transit = [0] * routing.Size()\n",
" for index in range(routing.Size()):\n",
" node = manager.IndexToNode(index)\n",
" node_visit_transit[index] = data['service_time'][node]\n",
" node_visit_transit[index] = data[\"service_time\"][node]\n",
"\n",
" # Add a break lasting 5 minutes, start between 25 and 45 minutes after route start\n",
" for v in range(manager.GetNumberOfVehicles()):\n",
" start_var = time_dimension.CumulVar(routing.Start(v))\n",
" break_start = routing.solver().Sum(\n",
" [routing.solver().IntVar(25, 45), start_var])\n",
" break_start = routing.solver().Sum([routing.solver().IntVar(25, 45), start_var])\n",
"\n",
" break_intervals = [\n",
" routing.solver().FixedDurationIntervalVar(break_start, 5,\n",
" f'Break for vehicle {v}')\n",
" routing.solver().FixedDurationIntervalVar(\n",
" break_start, 5, f\"Break for vehicle {v}\"\n",
" )\n",
" ]\n",
" time_dimension.SetBreakIntervalsOfVehicle(break_intervals, v,\n",
" node_visit_transit)\n",
" time_dimension.SetBreakIntervalsOfVehicle(\n",
" break_intervals, v, node_visit_transit\n",
" )\n",
"\n",
" # Setting first solution heuristic.\n",
" search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n",
" search_parameters.first_solution_strategy = (\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC\n",
" )\n",
" search_parameters.local_search_metaheuristic = (\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH\n",
" )\n",
" # search_parameters.log_search = True\n",
" search_parameters.time_limit.FromSeconds(2)\n",
"\n",
@@ -240,7 +250,7 @@
" if solution:\n",
" print_solution(manager, routing, solution)\n",
" else:\n",
" print('No solution found !')\n",
" print(\"No solution found !\")\n",
"\n",
"\n",
"main()\n",
@@ -248,7 +258,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -124,6 +125,8 @@
" total_distance = 0\n",
" total_load = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -212,7 +215,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -133,6 +134,8 @@
" total_distance = 0\n",
" total_load = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -225,7 +228,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -75,12 +75,12 @@
"\n",
"Simple Vehicles Routing Problem (VRP).\n",
"\n",
" This is a sample using the routing library python wrapper to solve a VRP\n",
" problem.\n",
" A description of the problem can be found here:\n",
" http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"This is a sample using the routing library python wrapper to solve a VRP\n",
"problem.\n",
"A description of the problem can be found here:\n",
"http://en.wikipedia.org/wiki/Vehicle_routing_problem.\n",
"\n",
" Distances are in meters.\n",
"Distances are in meters.\n",
"\n"
]
},
@@ -95,6 +95,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -129,6 +130,8 @@
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
" max_route_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -206,7 +209,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -129,6 +130,8 @@
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
" max_route_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -220,7 +223,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -73,9 +73,9 @@
"metadata": {},
"source": [
"Vehicles Routing Problem (VRP) for delivering items from any suppliers.\n",
"Description:\n",
"Need to deliver some item X and Y at end nodes (at least 11 X and 13 Y).\n",
"Several locations provide them and even few provide both.\n",
"\n",
"Description: Need to deliver some item X and Y at end nodes (at least 11 X and\n",
"13 Y). Several locations provide them and even few provide both.\n",
"\n",
"fleet:\n",
" * vehicles: 2\n",
@@ -101,14 +101,14 @@
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
" data['num_vehicles'] = 2\n",
" data['starts'] = [0] * data['num_vehicles']\n",
" data['ends'] = [1] * data['num_vehicles']\n",
" assert len(data['starts']) == data['num_vehicles']\n",
" assert len(data['ends']) == data['num_vehicles']\n",
" data[\"num_vehicles\"] = 2\n",
" data[\"starts\"] = [0] * data[\"num_vehicles\"]\n",
" data[\"ends\"] = [1] * data[\"num_vehicles\"]\n",
" assert len(data[\"starts\"]) == data[\"num_vehicles\"]\n",
" assert len(data[\"ends\"]) == data[\"num_vehicles\"]\n",
"\n",
" # Need 11 X and 13 Y\n",
" data['providers_x'] = [\n",
" data[\"providers_x\"] = [\n",
" 0, # start\n",
" -11, # end\n",
" 2, # X supply 1\n",
@@ -127,7 +127,7 @@
" 0, # Y supply 5\n",
" 0, # Y supply 6\n",
" ]\n",
" data['providers_y'] = [\n",
" data[\"providers_y\"] = [\n",
" 0, # start\n",
" -13, # ends\n",
" 0, # X supply 1\n",
@@ -146,127 +146,384 @@
" 3, # Y supply 5\n",
" 5, # Y supply 6\n",
" ]\n",
" data['vehicle_capacities_x'] = [15] * data['num_vehicles']\n",
" data['vehicle_capacities_y'] = [15] * data['num_vehicles']\n",
" assert len(data['vehicle_capacities_x']) == data['num_vehicles']\n",
" assert len(data['vehicle_capacities_y']) == data['num_vehicles']\n",
" data['distance_matrix'] = [\n",
" data[\"vehicle_capacities_x\"] = [15] * data[\"num_vehicles\"]\n",
" data[\"vehicle_capacities_y\"] = [15] * data[\"num_vehicles\"]\n",
" assert len(data[\"vehicle_capacities_x\"]) == data[\"num_vehicles\"]\n",
" assert len(data[\"vehicle_capacities_y\"]) == data[\"num_vehicles\"]\n",
" data[\"distance_matrix\"] = [\n",
" [\n",
" 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354,\n",
" 468, 776, 662\n",
" 0,\n",
" 548,\n",
" 776,\n",
" 696,\n",
" 582,\n",
" 274,\n",
" 502,\n",
" 194,\n",
" 308,\n",
" 194,\n",
" 536,\n",
" 502,\n",
" 388,\n",
" 354,\n",
" 468,\n",
" 776,\n",
" 662,\n",
" ],\n",
" [\n",
" 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674,\n",
" 1016, 868, 1210\n",
" 548,\n",
" 0,\n",
" 684,\n",
" 308,\n",
" 194,\n",
" 502,\n",
" 730,\n",
" 354,\n",
" 696,\n",
" 742,\n",
" 1084,\n",
" 594,\n",
" 480,\n",
" 674,\n",
" 1016,\n",
" 868,\n",
" 1210,\n",
" ],\n",
" [\n",
" 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164,\n",
" 1130, 788, 1552, 754\n",
" 776,\n",
" 684,\n",
" 0,\n",
" 992,\n",
" 878,\n",
" 502,\n",
" 274,\n",
" 810,\n",
" 468,\n",
" 742,\n",
" 400,\n",
" 1278,\n",
" 1164,\n",
" 1130,\n",
" 788,\n",
" 1552,\n",
" 754,\n",
" ],\n",
" [\n",
" 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822,\n",
" 1164, 560, 1358\n",
" 696,\n",
" 308,\n",
" 992,\n",
" 0,\n",
" 114,\n",
" 650,\n",
" 878,\n",
" 502,\n",
" 844,\n",
" 890,\n",
" 1232,\n",
" 514,\n",
" 628,\n",
" 822,\n",
" 1164,\n",
" 560,\n",
" 1358,\n",
" ],\n",
" [\n",
" 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708,\n",
" 1050, 674, 1244\n",
" 582,\n",
" 194,\n",
" 878,\n",
" 114,\n",
" 0,\n",
" 536,\n",
" 764,\n",
" 388,\n",
" 730,\n",
" 776,\n",
" 1118,\n",
" 400,\n",
" 514,\n",
" 708,\n",
" 1050,\n",
" 674,\n",
" 1244,\n",
" ],\n",
" [\n",
" 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628,\n",
" 514, 1050, 708\n",
" 274,\n",
" 502,\n",
" 502,\n",
" 650,\n",
" 536,\n",
" 0,\n",
" 228,\n",
" 308,\n",
" 194,\n",
" 240,\n",
" 582,\n",
" 776,\n",
" 662,\n",
" 628,\n",
" 514,\n",
" 1050,\n",
" 708,\n",
" ],\n",
" [\n",
" 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856,\n",
" 514, 1278, 480\n",
" 502,\n",
" 730,\n",
" 274,\n",
" 878,\n",
" 764,\n",
" 228,\n",
" 0,\n",
" 536,\n",
" 194,\n",
" 468,\n",
" 354,\n",
" 1004,\n",
" 890,\n",
" 856,\n",
" 514,\n",
" 1278,\n",
" 480,\n",
" ],\n",
" [\n",
" 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320,\n",
" 662, 742, 856\n",
" 194,\n",
" 354,\n",
" 810,\n",
" 502,\n",
" 388,\n",
" 308,\n",
" 536,\n",
" 0,\n",
" 342,\n",
" 388,\n",
" 730,\n",
" 468,\n",
" 354,\n",
" 320,\n",
" 662,\n",
" 742,\n",
" 856,\n",
" ],\n",
" [\n",
" 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662,\n",
" 320, 1084, 514\n",
" 308,\n",
" 696,\n",
" 468,\n",
" 844,\n",
" 730,\n",
" 194,\n",
" 194,\n",
" 342,\n",
" 0,\n",
" 274,\n",
" 388,\n",
" 810,\n",
" 696,\n",
" 662,\n",
" 320,\n",
" 1084,\n",
" 514,\n",
" ],\n",
" [\n",
" 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388,\n",
" 274, 810, 468\n",
" 194,\n",
" 742,\n",
" 742,\n",
" 890,\n",
" 776,\n",
" 240,\n",
" 468,\n",
" 388,\n",
" 274,\n",
" 0,\n",
" 342,\n",
" 536,\n",
" 422,\n",
" 388,\n",
" 274,\n",
" 810,\n",
" 468,\n",
" ],\n",
" [\n",
" 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764,\n",
" 730, 388, 1152, 354\n",
" 536,\n",
" 1084,\n",
" 400,\n",
" 1232,\n",
" 1118,\n",
" 582,\n",
" 354,\n",
" 730,\n",
" 388,\n",
" 342,\n",
" 0,\n",
" 878,\n",
" 764,\n",
" 730,\n",
" 388,\n",
" 1152,\n",
" 354,\n",
" ],\n",
" [\n",
" 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114,\n",
" 308, 650, 274, 844\n",
" 502,\n",
" 594,\n",
" 1278,\n",
" 514,\n",
" 400,\n",
" 776,\n",
" 1004,\n",
" 468,\n",
" 810,\n",
" 536,\n",
" 878,\n",
" 0,\n",
" 114,\n",
" 308,\n",
" 650,\n",
" 274,\n",
" 844,\n",
" ],\n",
" [\n",
" 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194,\n",
" 536, 388, 730\n",
" 388,\n",
" 480,\n",
" 1164,\n",
" 628,\n",
" 514,\n",
" 662,\n",
" 890,\n",
" 354,\n",
" 696,\n",
" 422,\n",
" 764,\n",
" 114,\n",
" 0,\n",
" 194,\n",
" 536,\n",
" 388,\n",
" 730,\n",
" ],\n",
" [\n",
" 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0,\n",
" 342, 422, 536\n",
" 354,\n",
" 674,\n",
" 1130,\n",
" 822,\n",
" 708,\n",
" 628,\n",
" 856,\n",
" 320,\n",
" 662,\n",
" 388,\n",
" 730,\n",
" 308,\n",
" 194,\n",
" 0,\n",
" 342,\n",
" 422,\n",
" 536,\n",
" ],\n",
" [\n",
" 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536,\n",
" 342, 0, 764, 194\n",
" 468,\n",
" 1016,\n",
" 788,\n",
" 1164,\n",
" 1050,\n",
" 514,\n",
" 514,\n",
" 662,\n",
" 320,\n",
" 274,\n",
" 388,\n",
" 650,\n",
" 536,\n",
" 342,\n",
" 0,\n",
" 764,\n",
" 194,\n",
" ],\n",
" [\n",
" 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274,\n",
" 388, 422, 764, 0, 798\n",
" 776,\n",
" 868,\n",
" 1552,\n",
" 560,\n",
" 674,\n",
" 1050,\n",
" 1278,\n",
" 742,\n",
" 1084,\n",
" 810,\n",
" 1152,\n",
" 274,\n",
" 388,\n",
" 422,\n",
" 764,\n",
" 0,\n",
" 798,\n",
" ],\n",
" [\n",
" 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730,\n",
" 536, 194, 798, 0\n",
" 662,\n",
" 1210,\n",
" 754,\n",
" 1358,\n",
" 1244,\n",
" 708,\n",
" 480,\n",
" 856,\n",
" 514,\n",
" 468,\n",
" 354,\n",
" 844,\n",
" 730,\n",
" 536,\n",
" 194,\n",
" 798,\n",
" 0,\n",
" ],\n",
" ]\n",
" assert len(data['providers_x']) == len(data['distance_matrix'])\n",
" assert len(data['providers_y']) == len(data['distance_matrix'])\n",
" assert len(data[\"providers_x\"]) == len(data[\"distance_matrix\"])\n",
" assert len(data[\"providers_y\"]) == len(data[\"distance_matrix\"])\n",
" return data\n",
"\n",
"\n",
"def print_solution(data, manager, routing, assignment):\n",
" \"\"\"Prints assignment on console.\"\"\"\n",
" print(f'Objective: {assignment.ObjectiveValue()}')\n",
" print(f\"Objective: {assignment.ObjectiveValue()}\")\n",
" # Display dropped nodes.\n",
" dropped_nodes = 'Dropped nodes:'\n",
" dropped_nodes = \"Dropped nodes:\"\n",
" for node in range(routing.Size()):\n",
" if routing.IsStart(node) or routing.IsEnd(node):\n",
" continue\n",
" if assignment.Value(routing.NextVar(node)) == node:\n",
" dropped_nodes += f' {manager.IndexToNode(node)}'\n",
" dropped_nodes += f\" {manager.IndexToNode(node)}\"\n",
" print(dropped_nodes)\n",
" # Display routes\n",
" total_distance = 0\n",
" total_load_x = 0\n",
" total_load_y = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f'Route for vehicle {vehicle_id}:\\n'\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
" route_load_x = 0\n",
" route_load_y = 0\n",
" while not routing.IsEnd(index):\n",
" node_index = manager.IndexToNode(index)\n",
" route_load_x += data['providers_x'][node_index]\n",
" route_load_y += data['providers_y'][node_index]\n",
" plan_output += f' {node_index} Load(X:{route_load_x}, Y:{route_load_y}) -> '\n",
" route_load_x += data[\"providers_x\"][node_index]\n",
" route_load_y += data[\"providers_y\"][node_index]\n",
" plan_output += f\" {node_index} Load(X:{route_load_x}, Y:{route_load_y}) -> \"\n",
" previous_index = index\n",
" previous_node_index = node_index\n",
" index = assignment.Value(routing.NextVar(index))\n",
" node_index = manager.IndexToNode(index)\n",
" #route_distance += routing.GetArcCostForVehicle(previous_index, index, vehicle_id)\n",
" route_distance += data['distance_matrix'][previous_node_index][node_index]\n",
" # route_distance += routing.GetArcCostForVehicle(previous_index, index, vehicle_id)\n",
" route_distance += data[\"distance_matrix\"][previous_node_index][node_index]\n",
" node_index = manager.IndexToNode(index)\n",
" plan_output += f' {node_index} Load({route_load_x}, {route_load_y})\\n'\n",
" plan_output += f'Distance of the route: {route_distance}m\\n'\n",
" plan_output += f'Load of the route: X:{route_load_x}, Y:{route_load_y}\\n'\n",
" plan_output += f\" {node_index} Load({route_load_x}, {route_load_y})\\n\"\n",
" plan_output += f\"Distance of the route: {route_distance}m\\n\"\n",
" plan_output += f\"Load of the route: X:{route_load_x}, Y:{route_load_y}\\n\"\n",
" print(plan_output)\n",
" total_distance += route_distance\n",
" total_load_x += route_load_x\n",
" total_load_y += route_load_y\n",
" print(f'Total Distance of all routes: {total_distance}m')\n",
" print(f'Total load of all routes: X:{total_load_x}, Y:{total_load_y}')\n",
" print(f\"Total Distance of all routes: {total_distance}m\")\n",
" print(f\"Total load of all routes: X:{total_load_x}, Y:{total_load_y}\")\n",
"\n",
"\n",
"def main():\n",
@@ -275,9 +532,12 @@
" data = create_data_model()\n",
"\n",
" # Create the routing index manager.\n",
" manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),\n",
" data['num_vehicles'], data['starts'],\n",
" data['ends'])\n",
" manager = pywrapcp.RoutingIndexManager(\n",
" len(data[\"distance_matrix\"]),\n",
" data[\"num_vehicles\"],\n",
" data[\"starts\"],\n",
" data[\"ends\"],\n",
" )\n",
"\n",
" # Create Routing Model.\n",
" routing = pywrapcp.RoutingModel(manager)\n",
@@ -289,7 +549,7 @@
" # Convert from routing variable Index to distance matrix NodeIndex.\n",
" from_node = manager.IndexToNode(from_index)\n",
" to_node = manager.IndexToNode(to_index)\n",
" return data['distance_matrix'][from_node][to_node]\n",
" return data[\"distance_matrix\"][from_node][to_node]\n",
"\n",
" transit_callback_index = routing.RegisterTransitCallback(distance_callback)\n",
"\n",
@@ -297,13 +557,14 @@
" routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)\n",
"\n",
" # Add Distance constraint.\n",
" dimension_name = 'Distance'\n",
" dimension_name = \"Distance\"\n",
" routing.AddDimension(\n",
" transit_callback_index,\n",
" 0, # no slack\n",
" 2000, # vehicle maximum travel distance\n",
" True, # start cumul to zero\n",
" dimension_name)\n",
" dimension_name,\n",
" )\n",
" distance_dimension = routing.GetDimensionOrDie(dimension_name)\n",
" # Minimize the longest road\n",
" distance_dimension.SetGlobalSpanCostCoefficient(100)\n",
@@ -314,63 +575,67 @@
" \"\"\"Returns the demand of the node.\"\"\"\n",
" # Convert from routing variable Index to demands NodeIndex.\n",
" from_node = manager.IndexToNode(from_index)\n",
" return data['providers_x'][from_node]\n",
" return data[\"providers_x\"][from_node]\n",
"\n",
" demand_callback_x_index = routing.RegisterUnaryTransitCallback(\n",
" demand_callback_x)\n",
" demand_callback_x_index = routing.RegisterUnaryTransitCallback(demand_callback_x)\n",
" routing.AddDimensionWithVehicleCapacity(\n",
" demand_callback_x_index,\n",
" 0, # null capacity slack\n",
" data['vehicle_capacities_x'], # vehicle maximum capacities\n",
" data[\"vehicle_capacities_x\"], # vehicle maximum capacities\n",
" True, # start cumul to zero\n",
" 'Load_x')\n",
" \"Load_x\",\n",
" )\n",
"\n",
" def demand_callback_y(from_index):\n",
" \"\"\"Returns the demand of the node.\"\"\"\n",
" # Convert from routing variable Index to demands NodeIndex.\n",
" from_node = manager.IndexToNode(from_index)\n",
" return data['providers_y'][from_node]\n",
" return data[\"providers_y\"][from_node]\n",
"\n",
" demand_callback_y_index = routing.RegisterUnaryTransitCallback(\n",
" demand_callback_y)\n",
" demand_callback_y_index = routing.RegisterUnaryTransitCallback(demand_callback_y)\n",
" routing.AddDimensionWithVehicleCapacity(\n",
" demand_callback_y_index,\n",
" 0, # null capacity slack\n",
" data['vehicle_capacities_y'], # vehicle maximum capacities\n",
" data[\"vehicle_capacities_y\"], # vehicle maximum capacities\n",
" True, # start cumul to zero\n",
" 'Load_y')\n",
" \"Load_y\",\n",
" )\n",
"\n",
" # Add constraint at end\n",
" solver = routing.solver()\n",
" load_x_dim = routing.GetDimensionOrDie('Load_x')\n",
" load_y_dim = routing.GetDimensionOrDie('Load_y')\n",
" load_x_dim = routing.GetDimensionOrDie(\"Load_x\")\n",
" load_y_dim = routing.GetDimensionOrDie(\"Load_y\")\n",
" ends = []\n",
" for v in range(manager.GetNumberOfVehicles()):\n",
" ends.append(routing.End(v))\n",
"\n",
" node_end = data['ends'][0]\n",
" node_end = data[\"ends\"][0]\n",
" solver.Add(\n",
" solver.Sum([load_x_dim.CumulVar(l)\n",
" for l in ends]) >= -data['providers_x'][node_end])\n",
" solver.Sum([load_x_dim.CumulVar(l) for l in ends])\n",
" >= -data[\"providers_x\"][node_end]\n",
" )\n",
" solver.Add(\n",
" solver.Sum([load_y_dim.CumulVar(l)\n",
" for l in ends]) >= -data['providers_y'][node_end])\n",
" #solver.Add(load_y_dim.CumulVar(end) >= -data['providers_y'][node_end])\n",
" solver.Sum([load_y_dim.CumulVar(l) for l in ends])\n",
" >= -data[\"providers_y\"][node_end]\n",
" )\n",
" # solver.Add(load_y_dim.CumulVar(end) >= -data['providers_y'][node_end])\n",
"\n",
" # Allow to freely drop any nodes.\n",
" penalty = 0\n",
" for node in range(0, len(data['distance_matrix'])):\n",
" if node not in data['starts'] and node not in data['ends']:\n",
" for node in range(0, len(data[\"distance_matrix\"])):\n",
" if node not in data[\"starts\"] and node not in data[\"ends\"]:\n",
" routing.AddDisjunction([manager.NodeToIndex(node)], penalty)\n",
"\n",
" # Setting first solution heuristic.\n",
" search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n",
" search_parameters.first_solution_strategy = (\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC\n",
" )\n",
" search_parameters.local_search_metaheuristic = (\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH\n",
" )\n",
" # Sets a time limit; default is 100 milliseconds.\n",
" #search_parameters.log_search = True\n",
" # search_parameters.log_search = True\n",
" search_parameters.time_limit.FromSeconds(1)\n",
"\n",
" # Solve the problem.\n",
@@ -380,7 +645,7 @@
" if solution:\n",
" print_solution(data, manager, routing, solution)\n",
" else:\n",
" print('no solution found !')\n",
" print(\"no solution found !\")\n",
"\n",
"\n",
"main()\n",
@@ -388,7 +653,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -91,6 +91,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -149,6 +150,8 @@
" dim_two = routing.GetDimensionOrDie(\"Two\")\n",
"\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -315,7 +318,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -78,11 +78,15 @@
"the relation between nodes and indices.\n",
"\n",
"Things to notice:\n",
"* Since we have two duplicates (node 5 and node 4) solver need 2 extra indices to have an unique index for each vehicle start/stop and locations.\n",
"* Solver needs to \"create\" an index for a vehicle 1 start since solver need an unique start index per vehicle.\n",
"* Since we have two duplicates (node 5 and node 4) solver need 2 extra indices\n",
"to have an unique index for each vehicle start/stop and locations.\n",
"* Solver needs to \"create\" an index for a vehicle 1 start since solver need an\n",
"unique start index per vehicle.\n",
"* All end nodes are moved to the end of the index list aka [15, 16, 17, 18].\n",
"* routing.Size() return the number of node which are not end nodes (here 15 aka [0-14])\n",
"note: using the two properties above, we know that any index in range(routing.Size()) is not a vehicle end node.\n",
"* routing.Size() return the number of node which are not end nodes (here 15 aka\n",
"[0-14])\n",
"note: using the two properties above, we know that any index in\n",
"range(routing.Size()) is not a vehicle end node.\n",
"\n",
"* Since end nodes are moved to the end, their respective \"empty\" node index are\n",
"reused so all locations indices are \"shifted\"\n",
@@ -91,9 +95,11 @@
"e.g. start node 7 mapped to index 4\n",
"\n",
"Takeaway:\n",
"* Allways use routing.Start(), routing.End(), manager.IndexToNode() or manager.NodeToIndex().\n",
"* Allways use routing.Start(), routing.End(), manager.IndexToNode() or\n",
"manager.NodeToIndex().\n",
"* Location node is not necessarily equal to its index.\n",
"* To loop through ALL indices use manager.GetNumberOfIndices() (Python) or manager::num_indices() (C++)\n",
"* To loop through ALL indices use manager.GetNumberOfIndices() (Python) or\n",
"manager::num_indices() (C++)\n",
"\n"
]
},
@@ -119,57 +125,61 @@
" manager = pywrapcp.RoutingIndexManager(locations, vehicles, starts, ends)\n",
" routing = pywrapcp.RoutingModel(manager)\n",
"\n",
" print('Starts/Ends:')\n",
" header = '| |'\n",
" separator = '|---|'\n",
" v_starts = '| start |'\n",
" v_ends = '| end |'\n",
" print(\"Starts/Ends:\")\n",
" header = \"| |\"\n",
" separator = \"|---|\"\n",
" v_starts = \"| start |\"\n",
" v_ends = \"| end |\"\n",
" for v in range(manager.GetNumberOfVehicles()):\n",
" header += f' vehicle {v} |'\n",
" separator += '---|'\n",
" v_starts += f' {starts[v]} |'\n",
" v_ends += f' {ends[v]} |'\n",
" header += f\" vehicle {v} |\"\n",
" separator += \"---|\"\n",
" v_starts += f\" {starts[v]} |\"\n",
" v_ends += f\" {ends[v]} |\"\n",
" print(header)\n",
" print(separator)\n",
" print(v_starts)\n",
" print(v_ends)\n",
"\n",
" print('\\nNodes:')\n",
" print(\"\\nNodes:\")\n",
" print(\n",
" '| locations | manager.GetNumberOfNodes | manager.GetNumberOfIndices | routing.nodes | routing.Size |'\n",
" \"| locations | manager.GetNumberOfNodes | manager.GetNumberOfIndices |\"\n",
" \" routing.nodes | routing.Size |\"\n",
" )\n",
" print('|---|---|---|---|---|')\n",
" print(\"|---|---|---|---|---|\")\n",
" print(\n",
" f'| {locations} | {manager.GetNumberOfNodes()} | {manager.GetNumberOfIndices()} | {routing.nodes()} | {routing.Size()} |'\n",
" f\"| {locations} | {manager.GetNumberOfNodes()} |\"\n",
" f\" {manager.GetNumberOfIndices()} | {routing.nodes()} |\"\n",
" f\" {routing.Size()} |\"\n",
" )\n",
"\n",
" print('\\nLocations:')\n",
" print('| node | index | routing.IsStart | routing.IsEnd |')\n",
" print('|---|---|---|---|')\n",
" print(\"\\nLocations:\")\n",
" print(\"| node | index | routing.IsStart | routing.IsEnd |\")\n",
" print(\"|---|---|---|---|\")\n",
" for node in range(manager.GetNumberOfNodes()):\n",
" if node in starts or node in ends:\n",
" continue\n",
" index = manager.NodeToIndex(node)\n",
" print(\n",
" f'| {node} | {index} | {routing.IsStart(index)} | {routing.IsEnd(index)} |'\n",
" f\"| {node} | {index} | {routing.IsStart(index)} |\"\n",
" f\" {routing.IsEnd(index)} |\"\n",
" )\n",
"\n",
" print('\\nStart/End:')\n",
" print(\n",
" '| vehicle | Start/end | node | index | routing.IsStart | routing.IsEnd |'\n",
" )\n",
" print('|---|---|---|---|---|---|')\n",
" print(\"\\nStart/End:\")\n",
" print(\"| vehicle | Start/end | node | index | routing.IsStart | routing.IsEnd |\")\n",
" print(\"|---|---|---|---|---|---|\")\n",
" for v in range(manager.GetNumberOfVehicles()):\n",
" start_index = routing.Start(v)\n",
" start_node = manager.IndexToNode(start_index)\n",
" print(\n",
" f'| {v} | start | {start_node} | {start_index} | {routing.IsStart(start_index)} | {routing.IsEnd(start_index)} |'\n",
" f\"| {v} | start | {start_node} | {start_index} |\"\n",
" f\" {routing.IsStart(start_index)} | {routing.IsEnd(start_index)} |\"\n",
" )\n",
" for v in range(manager.GetNumberOfVehicles()):\n",
" end_index = routing.End(v)\n",
" end_node = manager.IndexToNode(end_index)\n",
" print(\n",
" f'| {v} | end | {end_node} | {end_index} | {routing.IsStart(end_index)} | {routing.IsEnd(end_index)} |'\n",
" f\"| {v} | end | {end_node} | {end_index} |\"\n",
" f\" {routing.IsStart(end_index)} | {routing.IsEnd(end_index)} |\"\n",
" )\n",
"\n",
"\n",
@@ -178,7 +188,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -131,6 +132,8 @@
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
" total_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -217,7 +220,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -131,6 +132,8 @@
" print(f\"Objective: {assignment.ObjectiveValue()}\")\n",
" total_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -220,7 +223,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -131,6 +132,8 @@
" print(f\"Objective: {assignment.ObjectiveValue()}\")\n",
" total_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -220,7 +223,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -142,6 +143,8 @@
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" total_time = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" while not routing.IsEnd(index):\n",
@@ -266,7 +269,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -75,12 +75,12 @@
"\n",
"Simple Vehicles Routing Problem (VRP).\n",
"\n",
" This is a sample using the routing library python wrapper to solve a VRP\n",
" problem.\n",
"This is a sample using the routing library python wrapper to solve a VRP\n",
"problem.\n",
"\n",
" The solver stop after improving its solution 15 times or after 5 seconds.\n",
"The solver stop after improving its solution 15 times or after 5 seconds.\n",
"\n",
" Distances are in meters.\n",
"Distances are in meters.\n",
"\n"
]
},
@@ -97,6 +97,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -135,6 +136,8 @@
" total_distance = 0\n",
" for vehicle_id in range(routing_manager.GetNumberOfVehicles()):\n",
" index = routing_model.Start(vehicle_id)\n",
" if routing_model.IsEnd(routing_model.NextVar(index).Value()):\n",
" continue\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
" while not routing_model.IsEnd(index):\n",
@@ -169,7 +172,9 @@
" self.objectives = []\n",
"\n",
" def __call__(self):\n",
" objective = int(self._routing_model_ref().CostVar().Value())\n",
" objective = int(\n",
" self._routing_model_ref().CostVar().Value()\n",
" ) # pytype: disable=attribute-error\n",
" if not self.objectives or objective < self.objectives[-1]:\n",
" self.objectives.append(objective)\n",
" print_solution(self._routing_manager_ref(), self._routing_model_ref())\n",
@@ -179,6 +184,7 @@
"\n",
"\n",
"\n",
"\n",
"def main():\n",
" \"\"\"Entry point of the program.\"\"\"\n",
" # Instantiate the data problem.\n",
@@ -247,7 +253,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -122,6 +123,8 @@
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
" max_route_distance = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -196,7 +199,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -139,6 +140,8 @@
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" total_time = 0\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" while not routing.IsEnd(index):\n",
@@ -236,7 +239,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -74,19 +74,19 @@
"source": [
"Vehicles Routing Problem (VRP) with Time Window (TW) per vehicle.\n",
"\n",
" All time are in minutes using 0am as origin\n",
" e.g. 8am = 480, 11am = 660, 1pm = 780 ...\n",
"All time are in minutes using 0am as origin\n",
"e.g. 8am = 480, 11am = 660, 1pm = 780 ...\n",
"\n",
" We have 1 depot (0) and 16 locations (1-16).\n",
" We have a fleet of 4 vehicles (0-3) whose working time is [480, 1020] (8am-5pm)\n",
" We have the distance matrix between these locations and depot.\n",
" We have a service time of 25min at each location.\n",
"We have 1 depot (0) and 16 locations (1-16).\n",
"We have a fleet of 4 vehicles (0-3) whose working time is [480, 1020] (8am-5pm)\n",
"We have the distance matrix between these locations and depot.\n",
"We have a service time of 25min at each location.\n",
"\n",
" Locations are duplicated so we can simulate a TW per vehicle.\n",
" location: [01-16] vehicle: 0 TW: [540, 660] (9am-11am)\n",
" location: [17-32] vehicle: 1 TW: [660, 780] (11am-1pm)\n",
" location: [33-48] vehicle: 2 TW: [780, 900] (1pm-3pm)\n",
" location: [49-64] vehicle: 3 TW: [900, 1020] (3pm-5pm)\n",
"Locations are duplicated so we can simulate a TW per vehicle.\n",
"location: [01-16] vehicle: 0 TW: [540, 660] (9am-11am)\n",
"location: [17-32] vehicle: 1 TW: [660, 780] (11am-1pm)\n",
"location: [33-48] vehicle: 2 TW: [780, 900] (1pm-3pm)\n",
"location: [49-64] vehicle: 3 TW: [900, 1020] (3pm-5pm)\n",
"\n"
]
},
@@ -101,10 +101,11 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
" data['time_matrix'] = [\n",
" data[\"time_matrix\"] = [\n",
" [0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7],\n",
" [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14],\n",
" [9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9],\n",
@@ -123,16 +124,16 @@
" [9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9],\n",
" [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0],\n",
" ]\n",
" data['num_vehicles'] = 4\n",
" data['depot'] = 0\n",
" data[\"num_vehicles\"] = 4\n",
" data[\"depot\"] = 0\n",
" return data\n",
"\n",
"\n",
"def print_solution(manager, routing, assignment):\n",
" \"\"\"Prints solution on console.\"\"\"\n",
" print(f'Objective: {assignment.ObjectiveValue()}')\n",
" print(f\"Objective: {assignment.ObjectiveValue()}\")\n",
" # Display dropped nodes.\n",
" dropped_nodes = 'Dropped nodes:'\n",
" dropped_nodes = \"Dropped nodes:\"\n",
" for index in range(routing.Size()):\n",
" if routing.IsStart(index) or routing.IsEnd(index):\n",
" continue\n",
@@ -142,15 +143,17 @@
" original = node\n",
" while original > 16:\n",
" original = original - 16\n",
" dropped_nodes += f' {node}({original})'\n",
" dropped_nodes += f\" {node}({original})\"\n",
" else:\n",
" dropped_nodes += f' {node}'\n",
" dropped_nodes += f\" {node}\"\n",
" print(dropped_nodes)\n",
" # Display routes\n",
" time_dimension = routing.GetDimensionOrDie('Time')\n",
" time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
" total_time = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" plan_output = f'Route for vehicle {vehicle_id}:\\n'\n",
" if not routing.IsVehicleUsed(assignment, vehicle_id):\n",
" continue\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" index = routing.Start(vehicle_id)\n",
" start_time = 0\n",
" while not routing.IsEnd(index):\n",
@@ -160,22 +163,22 @@
" original = node\n",
" while original > 16:\n",
" original = original - 16\n",
" plan_output += f'{node}({original})'\n",
" plan_output += f\"{node}({original})\"\n",
" else:\n",
" plan_output += f'{node}'\n",
" plan_output += f' Time:{assignment.Value(time_var)} -> '\n",
" plan_output += f\"{node}\"\n",
" plan_output += f\" Time:{assignment.Value(time_var)} -> \"\n",
" if start_time == 0:\n",
" start_time = assignment.Value(time_var)\n",
" index = assignment.Value(routing.NextVar(index))\n",
" time_var = time_dimension.CumulVar(index)\n",
" node = manager.IndexToNode(index)\n",
" plan_output += f'{node} Time:{assignment.Value(time_var)}\\n'\n",
" plan_output += f\"{node} Time:{assignment.Value(time_var)}\\n\"\n",
" end_time = assignment.Value(time_var)\n",
" duration = end_time - start_time\n",
" plan_output += f'Duration of the route:{duration}min\\n'\n",
" plan_output += f\"Duration of the route:{duration}min\\n\"\n",
" print(plan_output)\n",
" total_time += duration\n",
" print(f'Total duration of all routes: {total_time}min')\n",
" print(f\"Total duration of all routes: {total_time}min\")\n",
"\n",
"\n",
"def main():\n",
@@ -185,9 +188,8 @@
"\n",
" # Create the routing index manager.\n",
" manager = pywrapcp.RoutingIndexManager(\n",
" 1 + 16 * 4, # number of locations\n",
" data['num_vehicles'],\n",
" data['depot'])\n",
" 1 + 16 * 4, data[\"num_vehicles\"], data[\"depot\"] # number of locations\n",
" )\n",
"\n",
" # Create Routing Model.\n",
" routing = pywrapcp.RoutingModel(manager)\n",
@@ -207,9 +209,9 @@
" to_node = to_node - 16\n",
" # add service of 25min for each location (except depot)\n",
" service_time = 0\n",
" if from_node != data['depot']:\n",
" if from_node != data[\"depot\"]:\n",
" service_time = 25\n",
" return data['time_matrix'][from_node][to_node] + service_time\n",
" return data[\"time_matrix\"][from_node][to_node] + service_time\n",
"\n",
" transit_callback_index = routing.RegisterTransitCallback(time_callback)\n",
"\n",
@@ -217,17 +219,18 @@
" routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)\n",
"\n",
" # Add Time Windows constraint.\n",
" time = 'Time'\n",
" time = \"Time\"\n",
" routing.AddDimension(\n",
" transit_callback_index,\n",
" 0, # allow waiting time (0 min)\n",
" 1020, # maximum time per vehicle (9 hours)\n",
" False, # Don't force start cumul to zero.\n",
" time)\n",
" time,\n",
" )\n",
" time_dimension = routing.GetDimensionOrDie(time)\n",
" # Add time window constraints for each location except depot.\n",
" for location_idx in range(17):\n",
" if location_idx == data['depot']:\n",
" if location_idx == data[\"depot\"]:\n",
" continue\n",
" # Vehicle 0 location TW: [9am, 11am]\n",
" index_0 = manager.NodeToIndex(location_idx)\n",
@@ -254,30 +257,32 @@
" routing.AddDisjunction([index_0, index_1, index_2, index_3], penalty, 1)\n",
"\n",
" # Add time window constraints for each vehicle start node.\n",
" depot_idx = data['depot']\n",
" for vehicle_id in range(data['num_vehicles']):\n",
" depot_idx = data[\"depot\"]\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" index = routing.Start(vehicle_id)\n",
" time_dimension.CumulVar(index).SetRange(480, 1020) # (8am, 5pm)\n",
"\n",
" # Add time window constraints for each vehicle end node.\n",
" depot_idx = data['depot']\n",
" for vehicle_id in range(data['num_vehicles']):\n",
" depot_idx = data[\"depot\"]\n",
" for vehicle_id in range(data[\"num_vehicles\"]):\n",
" index = routing.End(vehicle_id)\n",
" time_dimension.CumulVar(index).SetRange(480, 1020) # (8am, 5pm)\n",
"\n",
" # Instantiate route start and end times to produce feasible times.\n",
" for i in range(data['num_vehicles']):\n",
" for i in range(data[\"num_vehicles\"]):\n",
" routing.AddVariableMinimizedByFinalizer(\n",
" time_dimension.CumulVar(routing.Start(i)))\n",
" routing.AddVariableMinimizedByFinalizer(\n",
" time_dimension.CumulVar(routing.End(i)))\n",
" time_dimension.CumulVar(routing.Start(i))\n",
" )\n",
" routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(i)))\n",
"\n",
" # Setting first solution heuristic.\n",
" search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n",
" search_parameters.first_solution_strategy = (\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC\n",
" )\n",
" search_parameters.local_search_metaheuristic = (\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH\n",
" )\n",
" search_parameters.time_limit.FromSeconds(1)\n",
"\n",
" # Solve the problem.\n",
@@ -295,7 +300,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -126,6 +127,8 @@
" total_distance = 0\n",
" total_token = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" index = routing.Start(vehicle_id)\n",
" total_token += solution.Value(token_dimension.CumulVar(index))\n",
@@ -242,7 +245,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,11 +87,14 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def print_solution(manager, routing, solution):\n",
" \"\"\"Prints solution on console.\"\"\"\n",
" print(f\"Objective: {solution.ObjectiveValue()}\")\n",
" max_route_distance = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" if not routing.IsVehicleUsed(solution, vehicle_id):\n",
" continue\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f\"Route for vehicle {vehicle_id}:\\n\"\n",
" route_distance = 0\n",
@@ -170,7 +173,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
@@ -139,6 +140,8 @@
" total_time = 0\n",
" route_str = \"\"\n",
" for i, route in enumerate(routes):\n",
" if len(route) <= 2:\n",
" continue\n",
" route_str += \"Route \" + str(i) + \":\\n\"\n",
" start_time = cumul_data[i][0][0]\n",
" end_time = cumul_data[i][0][1]\n",
@@ -286,7 +289,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -234,7 +234,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -333,7 +333,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -236,7 +236,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -185,7 +185,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -195,7 +195,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -232,7 +232,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -193,7 +193,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -226,7 +226,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -167,7 +167,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -216,7 +216,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -209,7 +209,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -180,7 +180,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -209,7 +209,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -191,7 +191,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -201,7 +201,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -173,7 +173,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -195,7 +195,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -168,7 +168,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -211,7 +211,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -177,7 +177,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -245,7 +245,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -238,7 +238,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -211,7 +211,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -280,7 +280,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -265,7 +265,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -184,7 +184,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -206,7 +206,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -196,7 +196,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -264,7 +264,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -170,7 +170,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -180,7 +180,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -173,7 +173,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -234,7 +234,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -247,7 +247,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -120,7 +120,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -268,7 +268,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -262,7 +262,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -174,7 +174,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -185,7 +185,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -246,7 +246,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -245,7 +245,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -230,7 +230,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -180,7 +180,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -162,7 +162,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -284,7 +284,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -183,7 +183,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -248,7 +248,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -263,7 +263,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -258,7 +258,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -160,7 +160,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -171,7 +171,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -205,7 +205,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -182,7 +182,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -184,7 +184,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -164,7 +164,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -192,7 +192,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -122,7 +122,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -184,7 +184,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -180,7 +180,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -264,7 +264,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -173,7 +173,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -203,7 +203,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -189,7 +189,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -207,7 +207,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -300,7 +300,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -5,7 +5,7 @@
"id": "google",
"metadata": {},
"source": [
"##### Copyright 2024 Google LLC."
"##### Copyright 2025 Google LLC."
]
},
{
@@ -189,7 +189,11 @@
]
}
],
"metadata": {},
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

Some files were not shown because too many files have changed in this diff Show More