diff --git a/examples/notebook/algorithms/knapsack.ipynb b/examples/notebook/algorithms/knapsack.ipynb index 9d430ded3b..c0d34c4ad7 100644 --- a/examples/notebook/algorithms/knapsack.ipynb +++ b/examples/notebook/algorithms/knapsack.ipynb @@ -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 } diff --git a/examples/notebook/algorithms/set_cover.ipynb b/examples/notebook/algorithms/set_cover.ipynb new file mode 100644 index 0000000000..a27022b6c1 --- /dev/null +++ b/examples/notebook/algorithms/set_cover.ipynb @@ -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": [ + "\n", + "\n", + "\n", + "
\n", + "Run in Google Colab\n", + "\n", + "View source on GitHub\n", + "
" + ] + }, + { + "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 +} diff --git a/examples/notebook/algorithms/simple_knapsack_program.ipynb b/examples/notebook/algorithms/simple_knapsack_program.ipynb index 2db82375a3..820c62baa0 100644 --- a/examples/notebook/algorithms/simple_knapsack_program.ipynb +++ b/examples/notebook/algorithms/simple_knapsack_program.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/cp_is_fun_cp.ipynb b/examples/notebook/constraint_solver/cp_is_fun_cp.ipynb index bbddc10de8..3fd6844c07 100644 --- a/examples/notebook/constraint_solver/cp_is_fun_cp.ipynb +++ b/examples/notebook/constraint_solver/cp_is_fun_cp.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/cvrp_reload.ipynb b/examples/notebook/constraint_solver/cvrp_reload.ipynb index f90b37dbd9..2e70d31c2e 100644 --- a/examples/notebook/constraint_solver/cvrp_reload.ipynb +++ b/examples/notebook/constraint_solver/cvrp_reload.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/cvrptw_break.ipynb b/examples/notebook/constraint_solver/cvrptw_break.ipynb index f4b6ecef83..ad4a747083 100644 --- a/examples/notebook/constraint_solver/cvrptw_break.ipynb +++ b/examples/notebook/constraint_solver/cvrptw_break.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/nqueens_cp.ipynb b/examples/notebook/constraint_solver/nqueens_cp.ipynb index 52e67137ae..4132703e38 100644 --- a/examples/notebook/constraint_solver/nqueens_cp.ipynb +++ b/examples/notebook/constraint_solver/nqueens_cp.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/simple_cp_program.ipynb b/examples/notebook/constraint_solver/simple_cp_program.ipynb index e57f62343f..97e3a5148a 100644 --- a/examples/notebook/constraint_solver/simple_cp_program.ipynb +++ b/examples/notebook/constraint_solver/simple_cp_program.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/simple_routing_program.ipynb b/examples/notebook/constraint_solver/simple_routing_program.ipynb index 57ebd7a1e8..57d54942cd 100644 --- a/examples/notebook/constraint_solver/simple_routing_program.ipynb +++ b/examples/notebook/constraint_solver/simple_routing_program.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/tsp.ipynb b/examples/notebook/constraint_solver/tsp.ipynb index 326c9f83a9..6021ea54fe 100644 --- a/examples/notebook/constraint_solver/tsp.ipynb +++ b/examples/notebook/constraint_solver/tsp.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/tsp_circuit_board.ipynb b/examples/notebook/constraint_solver/tsp_circuit_board.ipynb index 76e86f1d79..7cadec642c 100644 --- a/examples/notebook/constraint_solver/tsp_circuit_board.ipynb +++ b/examples/notebook/constraint_solver/tsp_circuit_board.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/tsp_cities.ipynb b/examples/notebook/constraint_solver/tsp_cities.ipynb index c759d138b8..1f05f96944 100644 --- a/examples/notebook/constraint_solver/tsp_cities.ipynb +++ b/examples/notebook/constraint_solver/tsp_cities.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/tsp_distance_matrix.ipynb b/examples/notebook/constraint_solver/tsp_distance_matrix.ipynb index 0a32bfc5f8..da4b7f4e19 100644 --- a/examples/notebook/constraint_solver/tsp_distance_matrix.ipynb +++ b/examples/notebook/constraint_solver/tsp_distance_matrix.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp.ipynb b/examples/notebook/constraint_solver/vrp.ipynb index 6512432a1d..8f3808c22a 100644 --- a/examples/notebook/constraint_solver/vrp.ipynb +++ b/examples/notebook/constraint_solver/vrp.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_breaks.ipynb b/examples/notebook/constraint_solver/vrp_breaks.ipynb index ae15252c87..607fd6aaae 100644 --- a/examples/notebook/constraint_solver/vrp_breaks.ipynb +++ b/examples/notebook/constraint_solver/vrp_breaks.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_breaks_from_start.ipynb b/examples/notebook/constraint_solver/vrp_breaks_from_start.ipynb index 855235963a..354ee332d2 100644 --- a/examples/notebook/constraint_solver/vrp_breaks_from_start.ipynb +++ b/examples/notebook/constraint_solver/vrp_breaks_from_start.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_capacity.ipynb b/examples/notebook/constraint_solver/vrp_capacity.ipynb index 2e4465fa3d..66bfc3158b 100644 --- a/examples/notebook/constraint_solver/vrp_capacity.ipynb +++ b/examples/notebook/constraint_solver/vrp_capacity.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_drop_nodes.ipynb b/examples/notebook/constraint_solver/vrp_drop_nodes.ipynb index 459e2fed81..19f5d019b5 100644 --- a/examples/notebook/constraint_solver/vrp_drop_nodes.ipynb +++ b/examples/notebook/constraint_solver/vrp_drop_nodes.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_global_span.ipynb b/examples/notebook/constraint_solver/vrp_global_span.ipynb index b9278678ec..a652e64d26 100644 --- a/examples/notebook/constraint_solver/vrp_global_span.ipynb +++ b/examples/notebook/constraint_solver/vrp_global_span.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_initial_routes.ipynb b/examples/notebook/constraint_solver/vrp_initial_routes.ipynb index bfe860c563..1a81fc8246 100644 --- a/examples/notebook/constraint_solver/vrp_initial_routes.ipynb +++ b/examples/notebook/constraint_solver/vrp_initial_routes.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_items_to_deliver.ipynb b/examples/notebook/constraint_solver/vrp_items_to_deliver.ipynb index e860236575..a75bf94893 100644 --- a/examples/notebook/constraint_solver/vrp_items_to_deliver.ipynb +++ b/examples/notebook/constraint_solver/vrp_items_to_deliver.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_node_max.ipynb b/examples/notebook/constraint_solver/vrp_node_max.ipynb index bcd9e8c958..c5f2e9b453 100644 --- a/examples/notebook/constraint_solver/vrp_node_max.ipynb +++ b/examples/notebook/constraint_solver/vrp_node_max.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_nodes_indices.ipynb b/examples/notebook/constraint_solver/vrp_nodes_indices.ipynb index 9e93d6ea8c..a795ca98bb 100644 --- a/examples/notebook/constraint_solver/vrp_nodes_indices.ipynb +++ b/examples/notebook/constraint_solver/vrp_nodes_indices.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_pickup_delivery.ipynb b/examples/notebook/constraint_solver/vrp_pickup_delivery.ipynb index 1f6aa3be6c..8bf90a41ab 100644 --- a/examples/notebook/constraint_solver/vrp_pickup_delivery.ipynb +++ b/examples/notebook/constraint_solver/vrp_pickup_delivery.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_pickup_delivery_fifo.ipynb b/examples/notebook/constraint_solver/vrp_pickup_delivery_fifo.ipynb index 6a4154e113..e783169c6b 100644 --- a/examples/notebook/constraint_solver/vrp_pickup_delivery_fifo.ipynb +++ b/examples/notebook/constraint_solver/vrp_pickup_delivery_fifo.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_pickup_delivery_lifo.ipynb b/examples/notebook/constraint_solver/vrp_pickup_delivery_lifo.ipynb index 369b896a12..7ec8bfee39 100644 --- a/examples/notebook/constraint_solver/vrp_pickup_delivery_lifo.ipynb +++ b/examples/notebook/constraint_solver/vrp_pickup_delivery_lifo.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_resources.ipynb b/examples/notebook/constraint_solver/vrp_resources.ipynb index 026cc370da..c861e6a3a8 100644 --- a/examples/notebook/constraint_solver/vrp_resources.ipynb +++ b/examples/notebook/constraint_solver/vrp_resources.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_solution_callback.ipynb b/examples/notebook/constraint_solver/vrp_solution_callback.ipynb index 571575c57f..b66d471977 100644 --- a/examples/notebook/constraint_solver/vrp_solution_callback.ipynb +++ b/examples/notebook/constraint_solver/vrp_solution_callback.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_starts_ends.ipynb b/examples/notebook/constraint_solver/vrp_starts_ends.ipynb index de86e7addd..1f3a3f3e0d 100644 --- a/examples/notebook/constraint_solver/vrp_starts_ends.ipynb +++ b/examples/notebook/constraint_solver/vrp_starts_ends.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_time_windows.ipynb b/examples/notebook/constraint_solver/vrp_time_windows.ipynb index 1796e779b8..516707633b 100644 --- a/examples/notebook/constraint_solver/vrp_time_windows.ipynb +++ b/examples/notebook/constraint_solver/vrp_time_windows.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_time_windows_per_vehicles.ipynb b/examples/notebook/constraint_solver/vrp_time_windows_per_vehicles.ipynb index f0326c598b..205d5d7b19 100644 --- a/examples/notebook/constraint_solver/vrp_time_windows_per_vehicles.ipynb +++ b/examples/notebook/constraint_solver/vrp_time_windows_per_vehicles.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_tokens.ipynb b/examples/notebook/constraint_solver/vrp_tokens.ipynb index 773461b26e..cea5aa12cf 100644 --- a/examples/notebook/constraint_solver/vrp_tokens.ipynb +++ b/examples/notebook/constraint_solver/vrp_tokens.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrp_with_time_limit.ipynb b/examples/notebook/constraint_solver/vrp_with_time_limit.ipynb index 870e8efc7a..cbafba12e8 100644 --- a/examples/notebook/constraint_solver/vrp_with_time_limit.ipynb +++ b/examples/notebook/constraint_solver/vrp_with_time_limit.ipynb @@ -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 } diff --git a/examples/notebook/constraint_solver/vrptw_store_solution_data.ipynb b/examples/notebook/constraint_solver/vrptw_store_solution_data.ipynb index 41e60a55a1..558847e5fc 100644 --- a/examples/notebook/constraint_solver/vrptw_store_solution_data.ipynb +++ b/examples/notebook/constraint_solver/vrptw_store_solution_data.ipynb @@ -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 } diff --git a/examples/notebook/contrib/3_jugs_mip.ipynb b/examples/notebook/contrib/3_jugs_mip.ipynb index bc0c4ce243..8ee166b1dc 100644 --- a/examples/notebook/contrib/3_jugs_mip.ipynb +++ b/examples/notebook/contrib/3_jugs_mip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/3_jugs_regular.ipynb b/examples/notebook/contrib/3_jugs_regular.ipynb index 4b5cdeeba0..5b498c33cc 100644 --- a/examples/notebook/contrib/3_jugs_regular.ipynb +++ b/examples/notebook/contrib/3_jugs_regular.ipynb @@ -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 } diff --git a/examples/notebook/contrib/a_round_of_golf.ipynb b/examples/notebook/contrib/a_round_of_golf.ipynb index 53e4401a64..db9bd85110 100644 --- a/examples/notebook/contrib/a_round_of_golf.ipynb +++ b/examples/notebook/contrib/a_round_of_golf.ipynb @@ -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 } diff --git a/examples/notebook/contrib/all_interval.ipynb b/examples/notebook/contrib/all_interval.ipynb index 54070f3662..86e58fbc5c 100644 --- a/examples/notebook/contrib/all_interval.ipynb +++ b/examples/notebook/contrib/all_interval.ipynb @@ -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 } diff --git a/examples/notebook/contrib/alldifferent_except_0.ipynb b/examples/notebook/contrib/alldifferent_except_0.ipynb index a4b7f0ef4f..1fb5304cc7 100644 --- a/examples/notebook/contrib/alldifferent_except_0.ipynb +++ b/examples/notebook/contrib/alldifferent_except_0.ipynb @@ -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 } diff --git a/examples/notebook/contrib/alphametic.ipynb b/examples/notebook/contrib/alphametic.ipynb index da69bc36e7..c59c6b6323 100644 --- a/examples/notebook/contrib/alphametic.ipynb +++ b/examples/notebook/contrib/alphametic.ipynb @@ -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 } diff --git a/examples/notebook/contrib/assignment.ipynb b/examples/notebook/contrib/assignment.ipynb index 5c6c316bf7..8d1186bc6b 100644 --- a/examples/notebook/contrib/assignment.ipynb +++ b/examples/notebook/contrib/assignment.ipynb @@ -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 } diff --git a/examples/notebook/contrib/assignment6_mip.ipynb b/examples/notebook/contrib/assignment6_mip.ipynb index 81b7a831cf..092c2b1187 100644 --- a/examples/notebook/contrib/assignment6_mip.ipynb +++ b/examples/notebook/contrib/assignment6_mip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/bacp.ipynb b/examples/notebook/contrib/bacp.ipynb index f7e01f2a3d..cb19d70b3e 100644 --- a/examples/notebook/contrib/bacp.ipynb +++ b/examples/notebook/contrib/bacp.ipynb @@ -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 } diff --git a/examples/notebook/contrib/blending.ipynb b/examples/notebook/contrib/blending.ipynb index 8f999b1e98..a9bacf3e23 100644 --- a/examples/notebook/contrib/blending.ipynb +++ b/examples/notebook/contrib/blending.ipynb @@ -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 } diff --git a/examples/notebook/contrib/broken_weights.ipynb b/examples/notebook/contrib/broken_weights.ipynb index 641f2dbbac..045b69eab3 100644 --- a/examples/notebook/contrib/broken_weights.ipynb +++ b/examples/notebook/contrib/broken_weights.ipynb @@ -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 } diff --git a/examples/notebook/contrib/bus_schedule.ipynb b/examples/notebook/contrib/bus_schedule.ipynb index d10280c607..0e946deb52 100644 --- a/examples/notebook/contrib/bus_schedule.ipynb +++ b/examples/notebook/contrib/bus_schedule.ipynb @@ -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 } diff --git a/examples/notebook/contrib/car.ipynb b/examples/notebook/contrib/car.ipynb index f2582c5aaf..a9e80d9d92 100644 --- a/examples/notebook/contrib/car.ipynb +++ b/examples/notebook/contrib/car.ipynb @@ -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 } diff --git a/examples/notebook/contrib/check_dependencies.ipynb b/examples/notebook/contrib/check_dependencies.ipynb index e7460d693f..c6b9e8e674 100644 --- a/examples/notebook/contrib/check_dependencies.ipynb +++ b/examples/notebook/contrib/check_dependencies.ipynb @@ -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 } diff --git a/examples/notebook/contrib/circuit.ipynb b/examples/notebook/contrib/circuit.ipynb index 5c0d3b996d..f768755b09 100644 --- a/examples/notebook/contrib/circuit.ipynb +++ b/examples/notebook/contrib/circuit.ipynb @@ -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 } diff --git a/examples/notebook/contrib/coins3.ipynb b/examples/notebook/contrib/coins3.ipynb index 2acc61bf25..89b9208d60 100644 --- a/examples/notebook/contrib/coins3.ipynb +++ b/examples/notebook/contrib/coins3.ipynb @@ -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 } diff --git a/examples/notebook/contrib/coins_grid.ipynb b/examples/notebook/contrib/coins_grid.ipynb index 25ac1f2ef8..2825f9be4b 100644 --- a/examples/notebook/contrib/coins_grid.ipynb +++ b/examples/notebook/contrib/coins_grid.ipynb @@ -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 } diff --git a/examples/notebook/contrib/coins_grid_mip.ipynb b/examples/notebook/contrib/coins_grid_mip.ipynb index 89be73fe5f..9173550e4b 100644 --- a/examples/notebook/contrib/coins_grid_mip.ipynb +++ b/examples/notebook/contrib/coins_grid_mip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/coloring_ip.ipynb b/examples/notebook/contrib/coloring_ip.ipynb index 0c4733271b..aac569dcd6 100644 --- a/examples/notebook/contrib/coloring_ip.ipynb +++ b/examples/notebook/contrib/coloring_ip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/combinatorial_auction2.ipynb b/examples/notebook/contrib/combinatorial_auction2.ipynb index fde253c500..73b69e658b 100644 --- a/examples/notebook/contrib/combinatorial_auction2.ipynb +++ b/examples/notebook/contrib/combinatorial_auction2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/contiguity_regular.ipynb b/examples/notebook/contrib/contiguity_regular.ipynb index 33011747c6..7714b5a6c6 100644 --- a/examples/notebook/contrib/contiguity_regular.ipynb +++ b/examples/notebook/contrib/contiguity_regular.ipynb @@ -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 } diff --git a/examples/notebook/contrib/costas_array.ipynb b/examples/notebook/contrib/costas_array.ipynb index a14993b9c9..3d09c51b4f 100644 --- a/examples/notebook/contrib/costas_array.ipynb +++ b/examples/notebook/contrib/costas_array.ipynb @@ -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 } diff --git a/examples/notebook/contrib/covering_opl.ipynb b/examples/notebook/contrib/covering_opl.ipynb index 45024be9d3..fe61a4625c 100644 --- a/examples/notebook/contrib/covering_opl.ipynb +++ b/examples/notebook/contrib/covering_opl.ipynb @@ -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 } diff --git a/examples/notebook/contrib/crew.ipynb b/examples/notebook/contrib/crew.ipynb index cff12bc40e..347a55981e 100644 --- a/examples/notebook/contrib/crew.ipynb +++ b/examples/notebook/contrib/crew.ipynb @@ -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 } diff --git a/examples/notebook/contrib/crossword2.ipynb b/examples/notebook/contrib/crossword2.ipynb index 3bced776ea..6d3e5164d9 100644 --- a/examples/notebook/contrib/crossword2.ipynb +++ b/examples/notebook/contrib/crossword2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/crypta.ipynb b/examples/notebook/contrib/crypta.ipynb index 7c659f09bd..415b6af766 100644 --- a/examples/notebook/contrib/crypta.ipynb +++ b/examples/notebook/contrib/crypta.ipynb @@ -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 } diff --git a/examples/notebook/contrib/crypto.ipynb b/examples/notebook/contrib/crypto.ipynb index 8a4c505b75..f3e32bfb22 100644 --- a/examples/notebook/contrib/crypto.ipynb +++ b/examples/notebook/contrib/crypto.ipynb @@ -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 } diff --git a/examples/notebook/contrib/curious_set_of_integers.ipynb b/examples/notebook/contrib/curious_set_of_integers.ipynb index 882151fc2e..33382ef452 100644 --- a/examples/notebook/contrib/curious_set_of_integers.ipynb +++ b/examples/notebook/contrib/curious_set_of_integers.ipynb @@ -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 } diff --git a/examples/notebook/contrib/debruijn_binary.ipynb b/examples/notebook/contrib/debruijn_binary.ipynb index 820c777dba..1249337839 100644 --- a/examples/notebook/contrib/debruijn_binary.ipynb +++ b/examples/notebook/contrib/debruijn_binary.ipynb @@ -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 } diff --git a/examples/notebook/contrib/diet1.ipynb b/examples/notebook/contrib/diet1.ipynb index 948da29917..89e16684b3 100644 --- a/examples/notebook/contrib/diet1.ipynb +++ b/examples/notebook/contrib/diet1.ipynb @@ -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 } diff --git a/examples/notebook/contrib/diet1_b.ipynb b/examples/notebook/contrib/diet1_b.ipynb index b0c692160b..01391e80d7 100644 --- a/examples/notebook/contrib/diet1_b.ipynb +++ b/examples/notebook/contrib/diet1_b.ipynb @@ -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 } diff --git a/examples/notebook/contrib/diet1_mip.ipynb b/examples/notebook/contrib/diet1_mip.ipynb index ba426559fd..0644f36076 100644 --- a/examples/notebook/contrib/diet1_mip.ipynb +++ b/examples/notebook/contrib/diet1_mip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/discrete_tomography.ipynb b/examples/notebook/contrib/discrete_tomography.ipynb index 551757a260..9d24bcd13f 100644 --- a/examples/notebook/contrib/discrete_tomography.ipynb +++ b/examples/notebook/contrib/discrete_tomography.ipynb @@ -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 } diff --git a/examples/notebook/contrib/divisible_by_9_through_1.ipynb b/examples/notebook/contrib/divisible_by_9_through_1.ipynb index e4df8c6810..bd6655c2f0 100644 --- a/examples/notebook/contrib/divisible_by_9_through_1.ipynb +++ b/examples/notebook/contrib/divisible_by_9_through_1.ipynb @@ -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 } diff --git a/examples/notebook/contrib/dudeney.ipynb b/examples/notebook/contrib/dudeney.ipynb index 841542197d..9b01d003a3 100644 --- a/examples/notebook/contrib/dudeney.ipynb +++ b/examples/notebook/contrib/dudeney.ipynb @@ -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 } diff --git a/examples/notebook/contrib/einav_puzzle.ipynb b/examples/notebook/contrib/einav_puzzle.ipynb index fb10e72c6f..d743e44fff 100644 --- a/examples/notebook/contrib/einav_puzzle.ipynb +++ b/examples/notebook/contrib/einav_puzzle.ipynb @@ -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 } diff --git a/examples/notebook/contrib/einav_puzzle2.ipynb b/examples/notebook/contrib/einav_puzzle2.ipynb index 1c14453eb2..7e9e8facd3 100644 --- a/examples/notebook/contrib/einav_puzzle2.ipynb +++ b/examples/notebook/contrib/einav_puzzle2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/eq10.ipynb b/examples/notebook/contrib/eq10.ipynb index 59bab8f057..c5fc94d283 100644 --- a/examples/notebook/contrib/eq10.ipynb +++ b/examples/notebook/contrib/eq10.ipynb @@ -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 } diff --git a/examples/notebook/contrib/eq20.ipynb b/examples/notebook/contrib/eq20.ipynb index c9fc2dabd6..664a35773f 100644 --- a/examples/notebook/contrib/eq20.ipynb +++ b/examples/notebook/contrib/eq20.ipynb @@ -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 } diff --git a/examples/notebook/contrib/fill_a_pix.ipynb b/examples/notebook/contrib/fill_a_pix.ipynb index 88f31c747b..4057b74f53 100644 --- a/examples/notebook/contrib/fill_a_pix.ipynb +++ b/examples/notebook/contrib/fill_a_pix.ipynb @@ -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 } diff --git a/examples/notebook/contrib/furniture_moving.ipynb b/examples/notebook/contrib/furniture_moving.ipynb index eb3b35036e..31cbd0ff08 100644 --- a/examples/notebook/contrib/furniture_moving.ipynb +++ b/examples/notebook/contrib/furniture_moving.ipynb @@ -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 } diff --git a/examples/notebook/contrib/futoshiki.ipynb b/examples/notebook/contrib/futoshiki.ipynb index 9789b29bee..66c96e7b44 100644 --- a/examples/notebook/contrib/futoshiki.ipynb +++ b/examples/notebook/contrib/futoshiki.ipynb @@ -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 } diff --git a/examples/notebook/contrib/game_theory_taha.ipynb b/examples/notebook/contrib/game_theory_taha.ipynb index 3de60774aa..7b2a6bfbf0 100644 --- a/examples/notebook/contrib/game_theory_taha.ipynb +++ b/examples/notebook/contrib/game_theory_taha.ipynb @@ -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 } diff --git a/examples/notebook/contrib/grocery.ipynb b/examples/notebook/contrib/grocery.ipynb index 2fdfbb61d1..0898e5efcd 100644 --- a/examples/notebook/contrib/grocery.ipynb +++ b/examples/notebook/contrib/grocery.ipynb @@ -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 } diff --git a/examples/notebook/contrib/hidato.ipynb b/examples/notebook/contrib/hidato.ipynb index 942aa78428..dc73df01c9 100644 --- a/examples/notebook/contrib/hidato.ipynb +++ b/examples/notebook/contrib/hidato.ipynb @@ -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 } diff --git a/examples/notebook/contrib/just_forgotten.ipynb b/examples/notebook/contrib/just_forgotten.ipynb index 888f3163f2..101f83468b 100644 --- a/examples/notebook/contrib/just_forgotten.ipynb +++ b/examples/notebook/contrib/just_forgotten.ipynb @@ -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 } diff --git a/examples/notebook/contrib/kakuro.ipynb b/examples/notebook/contrib/kakuro.ipynb index fa524843b3..8b2d03a995 100644 --- a/examples/notebook/contrib/kakuro.ipynb +++ b/examples/notebook/contrib/kakuro.ipynb @@ -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 } diff --git a/examples/notebook/contrib/kenken2.ipynb b/examples/notebook/contrib/kenken2.ipynb index eace922e2e..eff86dd87e 100644 --- a/examples/notebook/contrib/kenken2.ipynb +++ b/examples/notebook/contrib/kenken2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/killer_sudoku.ipynb b/examples/notebook/contrib/killer_sudoku.ipynb index 7b8e84e06d..609f4401e0 100644 --- a/examples/notebook/contrib/killer_sudoku.ipynb +++ b/examples/notebook/contrib/killer_sudoku.ipynb @@ -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 } diff --git a/examples/notebook/contrib/knapsack_cp.ipynb b/examples/notebook/contrib/knapsack_cp.ipynb index f4c10df6c2..6bf650f0e5 100644 --- a/examples/notebook/contrib/knapsack_cp.ipynb +++ b/examples/notebook/contrib/knapsack_cp.ipynb @@ -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 } diff --git a/examples/notebook/contrib/knapsack_mip.ipynb b/examples/notebook/contrib/knapsack_mip.ipynb index 7e3531fb97..a01f160869 100644 --- a/examples/notebook/contrib/knapsack_mip.ipynb +++ b/examples/notebook/contrib/knapsack_mip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/labeled_dice.ipynb b/examples/notebook/contrib/labeled_dice.ipynb index b1c3345a49..b390965e45 100644 --- a/examples/notebook/contrib/labeled_dice.ipynb +++ b/examples/notebook/contrib/labeled_dice.ipynb @@ -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 } diff --git a/examples/notebook/contrib/langford.ipynb b/examples/notebook/contrib/langford.ipynb index 1ce419ecd2..4c250b1350 100644 --- a/examples/notebook/contrib/langford.ipynb +++ b/examples/notebook/contrib/langford.ipynb @@ -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 } diff --git a/examples/notebook/contrib/least_diff.ipynb b/examples/notebook/contrib/least_diff.ipynb index 34ac0ff016..020f5fe0de 100644 --- a/examples/notebook/contrib/least_diff.ipynb +++ b/examples/notebook/contrib/least_diff.ipynb @@ -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 } diff --git a/examples/notebook/contrib/least_square.ipynb b/examples/notebook/contrib/least_square.ipynb index 469d07772d..e9b8574250 100644 --- a/examples/notebook/contrib/least_square.ipynb +++ b/examples/notebook/contrib/least_square.ipynb @@ -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 } diff --git a/examples/notebook/contrib/lectures.ipynb b/examples/notebook/contrib/lectures.ipynb index dc7c4c4354..2c405b6e38 100644 --- a/examples/notebook/contrib/lectures.ipynb +++ b/examples/notebook/contrib/lectures.ipynb @@ -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 } diff --git a/examples/notebook/contrib/magic_sequence_sat.ipynb b/examples/notebook/contrib/magic_sequence_sat.ipynb index 1093abee03..7492406d32 100644 --- a/examples/notebook/contrib/magic_sequence_sat.ipynb +++ b/examples/notebook/contrib/magic_sequence_sat.ipynb @@ -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 } diff --git a/examples/notebook/contrib/magic_square.ipynb b/examples/notebook/contrib/magic_square.ipynb index e33cf54121..2670f80dc1 100644 --- a/examples/notebook/contrib/magic_square.ipynb +++ b/examples/notebook/contrib/magic_square.ipynb @@ -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 } diff --git a/examples/notebook/contrib/magic_square_and_cards.ipynb b/examples/notebook/contrib/magic_square_and_cards.ipynb index feb9bee0df..0c7d5bf67c 100644 --- a/examples/notebook/contrib/magic_square_and_cards.ipynb +++ b/examples/notebook/contrib/magic_square_and_cards.ipynb @@ -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 } diff --git a/examples/notebook/contrib/magic_square_mip.ipynb b/examples/notebook/contrib/magic_square_mip.ipynb index 7dd7edd998..caafc9c88c 100644 --- a/examples/notebook/contrib/magic_square_mip.ipynb +++ b/examples/notebook/contrib/magic_square_mip.ipynb @@ -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 } diff --git a/examples/notebook/contrib/map.ipynb b/examples/notebook/contrib/map.ipynb index 6f383791cf..6dcddaa718 100644 --- a/examples/notebook/contrib/map.ipynb +++ b/examples/notebook/contrib/map.ipynb @@ -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 } diff --git a/examples/notebook/contrib/marathon2.ipynb b/examples/notebook/contrib/marathon2.ipynb index d3581cd2f9..5a23c782cc 100644 --- a/examples/notebook/contrib/marathon2.ipynb +++ b/examples/notebook/contrib/marathon2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/max_flow_taha.ipynb b/examples/notebook/contrib/max_flow_taha.ipynb index 7913958490..307fdbbf74 100644 --- a/examples/notebook/contrib/max_flow_taha.ipynb +++ b/examples/notebook/contrib/max_flow_taha.ipynb @@ -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 } diff --git a/examples/notebook/contrib/max_flow_winston1.ipynb b/examples/notebook/contrib/max_flow_winston1.ipynb index 462d0999f3..dca2aa81c4 100644 --- a/examples/notebook/contrib/max_flow_winston1.ipynb +++ b/examples/notebook/contrib/max_flow_winston1.ipynb @@ -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 } diff --git a/examples/notebook/contrib/minesweeper.ipynb b/examples/notebook/contrib/minesweeper.ipynb index 236b8cbc8c..8ff3cd95ae 100644 --- a/examples/notebook/contrib/minesweeper.ipynb +++ b/examples/notebook/contrib/minesweeper.ipynb @@ -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 } diff --git a/examples/notebook/contrib/mr_smith.ipynb b/examples/notebook/contrib/mr_smith.ipynb index 0767bedb00..58d1ba16a9 100644 --- a/examples/notebook/contrib/mr_smith.ipynb +++ b/examples/notebook/contrib/mr_smith.ipynb @@ -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 } diff --git a/examples/notebook/contrib/nonogram_default_search.ipynb b/examples/notebook/contrib/nonogram_default_search.ipynb index 17665e777a..38b6ac1e46 100644 --- a/examples/notebook/contrib/nonogram_default_search.ipynb +++ b/examples/notebook/contrib/nonogram_default_search.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -270,7 +270,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nonogram_regular.ipynb b/examples/notebook/contrib/nonogram_regular.ipynb index 01edff0a1e..eecbef6cc9 100644 --- a/examples/notebook/contrib/nonogram_regular.ipynb +++ b/examples/notebook/contrib/nonogram_regular.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -396,7 +396,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nonogram_table.ipynb b/examples/notebook/contrib/nonogram_table.ipynb index 0de937699c..51a48b3de1 100644 --- a/examples/notebook/contrib/nonogram_table.ipynb +++ b/examples/notebook/contrib/nonogram_table.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -392,7 +392,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nonogram_table2.ipynb b/examples/notebook/contrib/nonogram_table2.ipynb index d7dfa8fb54..0729de6e41 100644 --- a/examples/notebook/contrib/nonogram_table2.ipynb +++ b/examples/notebook/contrib/nonogram_table2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -292,7 +292,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nontransitive_dice.ipynb b/examples/notebook/contrib/nontransitive_dice.ipynb index da3cd48537..2b13c0e629 100644 --- a/examples/notebook/contrib/nontransitive_dice.ipynb +++ b/examples/notebook/contrib/nontransitive_dice.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -282,7 +282,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nqueens.ipynb b/examples/notebook/contrib/nqueens.ipynb index 437a3de407..1a7bb32f71 100644 --- a/examples/notebook/contrib/nqueens.ipynb +++ b/examples/notebook/contrib/nqueens.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -166,7 +166,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nqueens2.ipynb b/examples/notebook/contrib/nqueens2.ipynb index 492c898c8c..aeaff0adcc 100644 --- a/examples/notebook/contrib/nqueens2.ipynb +++ b/examples/notebook/contrib/nqueens2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/nqueens3.ipynb b/examples/notebook/contrib/nqueens3.ipynb index d5b310fc08..f674206b33 100644 --- a/examples/notebook/contrib/nqueens3.ipynb +++ b/examples/notebook/contrib/nqueens3.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -178,7 +178,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nurse_rostering.ipynb b/examples/notebook/contrib/nurse_rostering.ipynb index ca1f438aff..9ec46cc94b 100644 --- a/examples/notebook/contrib/nurse_rostering.ipynb +++ b/examples/notebook/contrib/nurse_rostering.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -336,7 +336,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/nurses_cp.ipynb b/examples/notebook/contrib/nurses_cp.ipynb index 4247c3b9b3..4a6c432f1d 100644 --- a/examples/notebook/contrib/nurses_cp.ipynb +++ b/examples/notebook/contrib/nurses_cp.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -255,7 +255,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/olympic.ipynb b/examples/notebook/contrib/olympic.ipynb index 4c7675c3f1..e1a002de39 100644 --- a/examples/notebook/contrib/olympic.ipynb +++ b/examples/notebook/contrib/olympic.ipynb @@ -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 } diff --git a/examples/notebook/contrib/organize_day.ipynb b/examples/notebook/contrib/organize_day.ipynb index 7888444751..40562389b3 100644 --- a/examples/notebook/contrib/organize_day.ipynb +++ b/examples/notebook/contrib/organize_day.ipynb @@ -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 } diff --git a/examples/notebook/contrib/p_median.ipynb b/examples/notebook/contrib/p_median.ipynb index 937e78c03d..f6ef72726d 100644 --- a/examples/notebook/contrib/p_median.ipynb +++ b/examples/notebook/contrib/p_median.ipynb @@ -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 } diff --git a/examples/notebook/contrib/pandigital_numbers.ipynb b/examples/notebook/contrib/pandigital_numbers.ipynb index bf4746b3e5..4b497e86cf 100644 --- a/examples/notebook/contrib/pandigital_numbers.ipynb +++ b/examples/notebook/contrib/pandigital_numbers.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -235,7 +235,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/photo_problem.ipynb b/examples/notebook/contrib/photo_problem.ipynb index 9a75a3413f..a4106b1a87 100644 --- a/examples/notebook/contrib/photo_problem.ipynb +++ b/examples/notebook/contrib/photo_problem.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -224,7 +224,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/place_number_puzzle.ipynb b/examples/notebook/contrib/place_number_puzzle.ipynb index 8fc2cd1ba8..113549594a 100644 --- a/examples/notebook/contrib/place_number_puzzle.ipynb +++ b/examples/notebook/contrib/place_number_puzzle.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -169,7 +169,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/post_office_problem2.ipynb b/examples/notebook/contrib/post_office_problem2.ipynb index 7271628b0a..d46bf083b1 100644 --- a/examples/notebook/contrib/post_office_problem2.ipynb +++ b/examples/notebook/contrib/post_office_problem2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -199,7 +199,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/production.ipynb b/examples/notebook/contrib/production.ipynb index f450e58575..de4e0f34d0 100644 --- a/examples/notebook/contrib/production.ipynb +++ b/examples/notebook/contrib/production.ipynb @@ -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 } diff --git a/examples/notebook/contrib/project_scheduling_sat.ipynb b/examples/notebook/contrib/project_scheduling_sat.ipynb index 328bbdc134..11e9b7a316 100644 --- a/examples/notebook/contrib/project_scheduling_sat.ipynb +++ b/examples/notebook/contrib/project_scheduling_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -136,7 +136,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/pyls_api.ipynb b/examples/notebook/contrib/pyls_api.ipynb index f0d5503213..fdeff13a56 100644 --- a/examples/notebook/contrib/pyls_api.ipynb +++ b/examples/notebook/contrib/pyls_api.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -200,7 +200,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/quasigroup_completion.ipynb b/examples/notebook/contrib/quasigroup_completion.ipynb index 3a89729599..4764af39b5 100644 --- a/examples/notebook/contrib/quasigroup_completion.ipynb +++ b/examples/notebook/contrib/quasigroup_completion.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -277,7 +277,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/regular.ipynb b/examples/notebook/contrib/regular.ipynb index 1f53a18eb5..0726163918 100644 --- a/examples/notebook/contrib/regular.ipynb +++ b/examples/notebook/contrib/regular.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -293,7 +293,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/regular_table.ipynb b/examples/notebook/contrib/regular_table.ipynb index bad77bc5fa..8277031654 100644 --- a/examples/notebook/contrib/regular_table.ipynb +++ b/examples/notebook/contrib/regular_table.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -286,7 +286,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/regular_table2.ipynb b/examples/notebook/contrib/regular_table2.ipynb index 73b7fe76ee..06c4828a9d 100644 --- a/examples/notebook/contrib/regular_table2.ipynb +++ b/examples/notebook/contrib/regular_table2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -270,7 +270,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/rogo2.ipynb b/examples/notebook/contrib/rogo2.ipynb index 9bae765dc5..59398a286b 100644 --- a/examples/notebook/contrib/rogo2.ipynb +++ b/examples/notebook/contrib/rogo2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -259,7 +259,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/rostering_with_travel.ipynb b/examples/notebook/contrib/rostering_with_travel.ipynb index a5545bbf53..33ef91ea0e 100644 --- a/examples/notebook/contrib/rostering_with_travel.ipynb +++ b/examples/notebook/contrib/rostering_with_travel.ipynb @@ -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 } diff --git a/examples/notebook/contrib/safe_cracking.ipynb b/examples/notebook/contrib/safe_cracking.ipynb index 4baaa5c125..b77145f529 100644 --- a/examples/notebook/contrib/safe_cracking.ipynb +++ b/examples/notebook/contrib/safe_cracking.ipynb @@ -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 } diff --git a/examples/notebook/contrib/scheduling_speakers.ipynb b/examples/notebook/contrib/scheduling_speakers.ipynb index 8f3de34267..cf9d085764 100644 --- a/examples/notebook/contrib/scheduling_speakers.ipynb +++ b/examples/notebook/contrib/scheduling_speakers.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -161,7 +161,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/scheduling_with_transitions_sat.ipynb b/examples/notebook/contrib/scheduling_with_transitions_sat.ipynb index b67470ee1d..f1676beeeb 100644 --- a/examples/notebook/contrib/scheduling_with_transitions_sat.ipynb +++ b/examples/notebook/contrib/scheduling_with_transitions_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -415,7 +415,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/school_scheduling_sat.ipynb b/examples/notebook/contrib/school_scheduling_sat.ipynb index 423ff950f0..1d0443b110 100644 --- a/examples/notebook/contrib/school_scheduling_sat.ipynb +++ b/examples/notebook/contrib/school_scheduling_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -430,7 +430,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/secret_santa.ipynb b/examples/notebook/contrib/secret_santa.ipynb index 1997541e8a..ceec8cde51 100644 --- a/examples/notebook/contrib/secret_santa.ipynb +++ b/examples/notebook/contrib/secret_santa.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -186,7 +186,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/secret_santa2.ipynb b/examples/notebook/contrib/secret_santa2.ipynb index 24314c8a4d..8cd2e3a449 100644 --- a/examples/notebook/contrib/secret_santa2.ipynb +++ b/examples/notebook/contrib/secret_santa2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -289,7 +289,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/send_more_money_any_base.ipynb b/examples/notebook/contrib/send_more_money_any_base.ipynb index a3039842df..f0cb046795 100644 --- a/examples/notebook/contrib/send_more_money_any_base.ipynb +++ b/examples/notebook/contrib/send_more_money_any_base.ipynb @@ -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 } diff --git a/examples/notebook/contrib/send_most_money.ipynb b/examples/notebook/contrib/send_most_money.ipynb index 418e7dd237..6af7856465 100644 --- a/examples/notebook/contrib/send_most_money.ipynb +++ b/examples/notebook/contrib/send_most_money.ipynb @@ -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 } diff --git a/examples/notebook/contrib/seseman.ipynb b/examples/notebook/contrib/seseman.ipynb index 4b6d7a9151..51e1b5e27d 100644 --- a/examples/notebook/contrib/seseman.ipynb +++ b/examples/notebook/contrib/seseman.ipynb @@ -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 } diff --git a/examples/notebook/contrib/seseman_b.ipynb b/examples/notebook/contrib/seseman_b.ipynb index 5d91bb53f8..2cbe336f8b 100644 --- a/examples/notebook/contrib/seseman_b.ipynb +++ b/examples/notebook/contrib/seseman_b.ipynb @@ -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 } diff --git a/examples/notebook/contrib/set_covering.ipynb b/examples/notebook/contrib/set_covering.ipynb index 8881614419..2850b22ea7 100644 --- a/examples/notebook/contrib/set_covering.ipynb +++ b/examples/notebook/contrib/set_covering.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -161,7 +161,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/set_covering2.ipynb b/examples/notebook/contrib/set_covering2.ipynb index f68a156379..1676e913bd 100644 --- a/examples/notebook/contrib/set_covering2.ipynb +++ b/examples/notebook/contrib/set_covering2.ipynb @@ -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 } diff --git a/examples/notebook/contrib/set_covering3.ipynb b/examples/notebook/contrib/set_covering3.ipynb index 2464fc62f5..8a06fd47cf 100644 --- a/examples/notebook/contrib/set_covering3.ipynb +++ b/examples/notebook/contrib/set_covering3.ipynb @@ -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 } diff --git a/examples/notebook/contrib/set_covering4.ipynb b/examples/notebook/contrib/set_covering4.ipynb index 30632d5cce..15d625e025 100644 --- a/examples/notebook/contrib/set_covering4.ipynb +++ b/examples/notebook/contrib/set_covering4.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -224,7 +224,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/set_covering_deployment.ipynb b/examples/notebook/contrib/set_covering_deployment.ipynb index bd6e6fed72..a3c747c068 100644 --- a/examples/notebook/contrib/set_covering_deployment.ipynb +++ b/examples/notebook/contrib/set_covering_deployment.ipynb @@ -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 } diff --git a/examples/notebook/contrib/set_covering_skiena.ipynb b/examples/notebook/contrib/set_covering_skiena.ipynb index 0105739449..0e58165e8e 100644 --- a/examples/notebook/contrib/set_covering_skiena.ipynb +++ b/examples/notebook/contrib/set_covering_skiena.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -188,7 +188,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/set_partition.ipynb b/examples/notebook/contrib/set_partition.ipynb index d151380bc1..472a784677 100644 --- a/examples/notebook/contrib/set_partition.ipynb +++ b/examples/notebook/contrib/set_partition.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -243,7 +243,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/sicherman_dice.ipynb b/examples/notebook/contrib/sicherman_dice.ipynb index 41531e4954..046bdd851c 100644 --- a/examples/notebook/contrib/sicherman_dice.ipynb +++ b/examples/notebook/contrib/sicherman_dice.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -208,7 +208,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/ski_assignment.ipynb b/examples/notebook/contrib/ski_assignment.ipynb index cfa236c191..ce681a5d37 100644 --- a/examples/notebook/contrib/ski_assignment.ipynb +++ b/examples/notebook/contrib/ski_assignment.ipynb @@ -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 } diff --git a/examples/notebook/contrib/slitherlink.ipynb b/examples/notebook/contrib/slitherlink.ipynb index 4ce404c391..4375f86238 100644 --- a/examples/notebook/contrib/slitherlink.ipynb +++ b/examples/notebook/contrib/slitherlink.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -365,7 +365,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/sports_schedule_sat.ipynb b/examples/notebook/contrib/sports_schedule_sat.ipynb index 1425f40d41..2175259148 100644 --- a/examples/notebook/contrib/sports_schedule_sat.ipynb +++ b/examples/notebook/contrib/sports_schedule_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -636,7 +636,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/stable_marriage.ipynb b/examples/notebook/contrib/stable_marriage.ipynb index 7d9c87ddb1..4d4e848fdd 100644 --- a/examples/notebook/contrib/stable_marriage.ipynb +++ b/examples/notebook/contrib/stable_marriage.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -256,7 +256,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/stable_marriage_sat.ipynb b/examples/notebook/contrib/stable_marriage_sat.ipynb index 5cd6df5856..054c55ace5 100644 --- a/examples/notebook/contrib/stable_marriage_sat.ipynb +++ b/examples/notebook/contrib/stable_marriage_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -188,7 +188,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/steel.ipynb b/examples/notebook/contrib/steel.ipynb index 73ebdf511a..5a15460ba3 100644 --- a/examples/notebook/contrib/steel.ipynb +++ b/examples/notebook/contrib/steel.ipynb @@ -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 } diff --git a/examples/notebook/contrib/steel_lns.ipynb b/examples/notebook/contrib/steel_lns.ipynb index df75ee18df..0acee6f43a 100644 --- a/examples/notebook/contrib/steel_lns.ipynb +++ b/examples/notebook/contrib/steel_lns.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -337,7 +337,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/stigler_contrib.ipynb b/examples/notebook/contrib/stigler_contrib.ipynb index a9f73e4444..1afda96008 100644 --- a/examples/notebook/contrib/stigler_contrib.ipynb +++ b/examples/notebook/contrib/stigler_contrib.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -413,7 +413,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/strimko2.ipynb b/examples/notebook/contrib/strimko2.ipynb index 49411e6dc2..8ae73aa05b 100644 --- a/examples/notebook/contrib/strimko2.ipynb +++ b/examples/notebook/contrib/strimko2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -212,7 +212,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/subset_sum.ipynb b/examples/notebook/contrib/subset_sum.ipynb index 17f716fc71..c049a396dc 100644 --- a/examples/notebook/contrib/subset_sum.ipynb +++ b/examples/notebook/contrib/subset_sum.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -178,7 +178,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/survo_puzzle.ipynb b/examples/notebook/contrib/survo_puzzle.ipynb index 217186c4e6..4404453858 100644 --- a/examples/notebook/contrib/survo_puzzle.ipynb +++ b/examples/notebook/contrib/survo_puzzle.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -243,7 +243,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/toNum.ipynb b/examples/notebook/contrib/toNum.ipynb index 86392c650b..d755449fbb 100644 --- a/examples/notebook/contrib/toNum.ipynb +++ b/examples/notebook/contrib/toNum.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -153,7 +153,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/traffic_lights.ipynb b/examples/notebook/contrib/traffic_lights.ipynb index 9e695c55cc..527508f549 100644 --- a/examples/notebook/contrib/traffic_lights.ipynb +++ b/examples/notebook/contrib/traffic_lights.ipynb @@ -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 } diff --git a/examples/notebook/contrib/vendor_scheduling.ipynb b/examples/notebook/contrib/vendor_scheduling.ipynb index e819b7a59b..2d3bfc02ad 100644 --- a/examples/notebook/contrib/vendor_scheduling.ipynb +++ b/examples/notebook/contrib/vendor_scheduling.ipynb @@ -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 } diff --git a/examples/notebook/contrib/volsay.ipynb b/examples/notebook/contrib/volsay.ipynb index d344e95c0f..42d53c4c6e 100644 --- a/examples/notebook/contrib/volsay.ipynb +++ b/examples/notebook/contrib/volsay.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -140,7 +140,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/volsay2.ipynb b/examples/notebook/contrib/volsay2.ipynb index c8d6e89129..e82d240f32 100644 --- a/examples/notebook/contrib/volsay2.ipynb +++ b/examples/notebook/contrib/volsay2.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -148,7 +148,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/volsay3.ipynb b/examples/notebook/contrib/volsay3.ipynb index 9b64f26d0c..23bc607ebb 100644 --- a/examples/notebook/contrib/volsay3.ipynb +++ b/examples/notebook/contrib/volsay3.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -161,7 +161,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/wedding_optimal_chart.ipynb b/examples/notebook/contrib/wedding_optimal_chart.ipynb index 2d25a22f9e..f1e526ec0c 100644 --- a/examples/notebook/contrib/wedding_optimal_chart.ipynb +++ b/examples/notebook/contrib/wedding_optimal_chart.ipynb @@ -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 } diff --git a/examples/notebook/contrib/who_killed_agatha.ipynb b/examples/notebook/contrib/who_killed_agatha.ipynb index b35d1a6313..9661edde2a 100644 --- a/examples/notebook/contrib/who_killed_agatha.ipynb +++ b/examples/notebook/contrib/who_killed_agatha.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -283,7 +283,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/xkcd.ipynb b/examples/notebook/contrib/xkcd.ipynb index 87e1a351f9..edb98572b6 100644 --- a/examples/notebook/contrib/xkcd.ipynb +++ b/examples/notebook/contrib/xkcd.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -179,7 +179,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/contrib/young_tableaux.ipynb b/examples/notebook/contrib/young_tableaux.ipynb index a5aa3cbdc3..83fcf642cb 100644 --- a/examples/notebook/contrib/young_tableaux.ipynb +++ b/examples/notebook/contrib/young_tableaux.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -233,7 +233,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/appointments.ipynb b/examples/notebook/examples/appointments.ipynb index e9473305c3..f4c85fec33 100644 --- a/examples/notebook/examples/appointments.ipynb +++ b/examples/notebook/examples/appointments.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -337,7 +337,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/arc_flow_cutting_stock_sat.ipynb b/examples/notebook/examples/arc_flow_cutting_stock_sat.ipynb index 59374a1958..89c9809afc 100644 --- a/examples/notebook/examples/arc_flow_cutting_stock_sat.ipynb +++ b/examples/notebook/examples/arc_flow_cutting_stock_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -499,7 +499,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/assignment_with_constraints_sat.ipynb b/examples/notebook/examples/assignment_with_constraints_sat.ipynb index 4faf8406e8..67e1967651 100644 --- a/examples/notebook/examples/assignment_with_constraints_sat.ipynb +++ b/examples/notebook/examples/assignment_with_constraints_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -197,7 +197,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/balance_group_sat.ipynb b/examples/notebook/examples/balance_group_sat.ipynb index 2e966e0e28..aa8477b300 100644 --- a/examples/notebook/examples/balance_group_sat.ipynb +++ b/examples/notebook/examples/balance_group_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -252,7 +252,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/bus_driver_scheduling_flow_sat.ipynb b/examples/notebook/examples/bus_driver_scheduling_flow_sat.ipynb index 59a3162001..78d46811af 100644 --- a/examples/notebook/examples/bus_driver_scheduling_flow_sat.ipynb +++ b/examples/notebook/examples/bus_driver_scheduling_flow_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -1898,7 +1898,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/bus_driver_scheduling_sat.ipynb b/examples/notebook/examples/bus_driver_scheduling_sat.ipynb index bb04ad260c..896dce73ab 100644 --- a/examples/notebook/examples/bus_driver_scheduling_sat.ipynb +++ b/examples/notebook/examples/bus_driver_scheduling_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -2104,7 +2104,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/chemical_balance_lp.ipynb b/examples/notebook/examples/chemical_balance_lp.ipynb index 2e0538ecbe..abd5c8c010 100644 --- a/examples/notebook/examples/chemical_balance_lp.ipynb +++ b/examples/notebook/examples/chemical_balance_lp.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -166,7 +166,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/chemical_balance_sat.ipynb b/examples/notebook/examples/chemical_balance_sat.ipynb index 4cc19e2a37..b71b6c9197 100644 --- a/examples/notebook/examples/chemical_balance_sat.ipynb +++ b/examples/notebook/examples/chemical_balance_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -188,7 +188,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/clustering_sat.ipynb b/examples/notebook/examples/clustering_sat.ipynb index 18636b3f4f..9b527fbe87 100644 --- a/examples/notebook/examples/clustering_sat.ipynb +++ b/examples/notebook/examples/clustering_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -212,7 +212,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/cover_rectangle_sat.ipynb b/examples/notebook/examples/cover_rectangle_sat.ipynb index e98d7890b5..b734090444 100644 --- a/examples/notebook/examples/cover_rectangle_sat.ipynb +++ b/examples/notebook/examples/cover_rectangle_sat.ipynb @@ -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 } diff --git a/examples/notebook/examples/cryptarithm_sat.ipynb b/examples/notebook/examples/cryptarithm_sat.ipynb index a448898767..d04c6c890f 100644 --- a/examples/notebook/examples/cryptarithm_sat.ipynb +++ b/examples/notebook/examples/cryptarithm_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -151,7 +151,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/cvrptw_plot.ipynb b/examples/notebook/examples/cvrptw_plot.ipynb index 4c4599c99f..5f7928f82f 100644 --- a/examples/notebook/examples/cvrptw_plot.ipynb +++ b/examples/notebook/examples/cvrptw_plot.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -823,7 +823,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/flexible_job_shop_sat.ipynb b/examples/notebook/examples/flexible_job_shop_sat.ipynb index d76f41b56e..28b94c2f6a 100644 --- a/examples/notebook/examples/flexible_job_shop_sat.ipynb +++ b/examples/notebook/examples/flexible_job_shop_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -275,7 +275,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/gate_scheduling_sat.ipynb b/examples/notebook/examples/gate_scheduling_sat.ipynb index 985b8f9c6b..134683752d 100644 --- a/examples/notebook/examples/gate_scheduling_sat.ipynb +++ b/examples/notebook/examples/gate_scheduling_sat.ipynb @@ -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 } diff --git a/examples/notebook/examples/golomb8.ipynb b/examples/notebook/examples/golomb8.ipynb index 0414ee36c5..bf943ae0de 100644 --- a/examples/notebook/examples/golomb8.ipynb +++ b/examples/notebook/examples/golomb8.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -156,7 +156,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/golomb_sat.ipynb b/examples/notebook/examples/golomb_sat.ipynb index cdd120961f..410ab75878 100644 --- a/examples/notebook/examples/golomb_sat.ipynb +++ b/examples/notebook/examples/golomb_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -163,7 +163,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/hidato_sat.ipynb b/examples/notebook/examples/hidato_sat.ipynb index 49640e66c3..81d1e3b0a9 100644 --- a/examples/notebook/examples/hidato_sat.ipynb +++ b/examples/notebook/examples/hidato_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -291,7 +291,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/integer_programming.ipynb b/examples/notebook/examples/integer_programming.ipynb index 3dd97a4aae..49903af1fd 100644 --- a/examples/notebook/examples/integer_programming.ipynb +++ b/examples/notebook/examples/integer_programming.ipynb @@ -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 } diff --git a/examples/notebook/examples/jobshop_ft06_distance_sat.ipynb b/examples/notebook/examples/jobshop_ft06_distance_sat.ipynb index dc5ee45b5b..ce9a7b41c7 100644 --- a/examples/notebook/examples/jobshop_ft06_distance_sat.ipynb +++ b/examples/notebook/examples/jobshop_ft06_distance_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -218,7 +218,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/jobshop_ft06_sat.ipynb b/examples/notebook/examples/jobshop_ft06_sat.ipynb index 792fd66ff5..781b6aab6a 100644 --- a/examples/notebook/examples/jobshop_ft06_sat.ipynb +++ b/examples/notebook/examples/jobshop_ft06_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -190,7 +190,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/jobshop_with_maintenance_sat.ipynb b/examples/notebook/examples/jobshop_with_maintenance_sat.ipynb index a40167ca52..3154333f35 100644 --- a/examples/notebook/examples/jobshop_with_maintenance_sat.ipynb +++ b/examples/notebook/examples/jobshop_with_maintenance_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -231,7 +231,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/knapsack_2d_sat.ipynb b/examples/notebook/examples/knapsack_2d_sat.ipynb index 09efe31498..297bc81611 100644 --- a/examples/notebook/examples/knapsack_2d_sat.ipynb +++ b/examples/notebook/examples/knapsack_2d_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -487,7 +487,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/line_balancing_sat.ipynb b/examples/notebook/examples/line_balancing_sat.ipynb index 07c2c82ab9..a95f9c2443 100644 --- a/examples/notebook/examples/line_balancing_sat.ipynb +++ b/examples/notebook/examples/line_balancing_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -431,7 +431,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/linear_assignment_api.ipynb b/examples/notebook/examples/linear_assignment_api.ipynb index 093c87cf6f..4b02415e9d 100644 --- a/examples/notebook/examples/linear_assignment_api.ipynb +++ b/examples/notebook/examples/linear_assignment_api.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -130,7 +130,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/linear_programming.ipynb b/examples/notebook/examples/linear_programming.ipynb index ea83ff3c89..ad00573b87 100644 --- a/examples/notebook/examples/linear_programming.ipynb +++ b/examples/notebook/examples/linear_programming.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -221,7 +221,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/magic_sequence_distribute.ipynb b/examples/notebook/examples/magic_sequence_distribute.ipynb index d3ec65460f..5912ed42b0 100644 --- a/examples/notebook/examples/magic_sequence_distribute.ipynb +++ b/examples/notebook/examples/magic_sequence_distribute.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -126,7 +126,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/maximize_combinations_sat.ipynb b/examples/notebook/examples/maximize_combinations_sat.ipynb index a30e3d7166..4065103954 100644 --- a/examples/notebook/examples/maximize_combinations_sat.ipynb +++ b/examples/notebook/examples/maximize_combinations_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -143,7 +143,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/maze_escape_sat.ipynb b/examples/notebook/examples/maze_escape_sat.ipynb index 2ff03b9f05..a1be0ae6b3 100644 --- a/examples/notebook/examples/maze_escape_sat.ipynb +++ b/examples/notebook/examples/maze_escape_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -243,7 +243,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/memory_layout_and_infeasibility_sat.ipynb b/examples/notebook/examples/memory_layout_and_infeasibility_sat.ipynb index 5512d91f34..71b8e27a30 100644 --- a/examples/notebook/examples/memory_layout_and_infeasibility_sat.ipynb +++ b/examples/notebook/examples/memory_layout_and_infeasibility_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -249,7 +249,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/no_wait_baking_scheduling_sat.ipynb b/examples/notebook/examples/no_wait_baking_scheduling_sat.ipynb index e82657ba4a..93e6e8c811 100644 --- a/examples/notebook/examples/no_wait_baking_scheduling_sat.ipynb +++ b/examples/notebook/examples/no_wait_baking_scheduling_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -379,7 +379,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/nqueens_sat.ipynb b/examples/notebook/examples/nqueens_sat.ipynb index 391be2abc6..44743f5224 100644 --- a/examples/notebook/examples/nqueens_sat.ipynb +++ b/examples/notebook/examples/nqueens_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -176,7 +176,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/pell_equation_sat.ipynb b/examples/notebook/examples/pell_equation_sat.ipynb index d136340121..d7636853c1 100644 --- a/examples/notebook/examples/pell_equation_sat.ipynb +++ b/examples/notebook/examples/pell_equation_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -135,7 +135,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/pentominoes_sat.ipynb b/examples/notebook/examples/pentominoes_sat.ipynb index 8f47a9623c..da74b189c8 100644 --- a/examples/notebook/examples/pentominoes_sat.ipynb +++ b/examples/notebook/examples/pentominoes_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -274,7 +274,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/prize_collecting_tsp.ipynb b/examples/notebook/examples/prize_collecting_tsp.ipynb index c18f94325e..1f673e1e5b 100644 --- a/examples/notebook/examples/prize_collecting_tsp.ipynb +++ b/examples/notebook/examples/prize_collecting_tsp.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -235,7 +235,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/prize_collecting_tsp_sat.ipynb b/examples/notebook/examples/prize_collecting_tsp_sat.ipynb index df2d25e7c1..99240c360a 100644 --- a/examples/notebook/examples/prize_collecting_tsp_sat.ipynb +++ b/examples/notebook/examples/prize_collecting_tsp_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -255,7 +255,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/prize_collecting_vrp.ipynb b/examples/notebook/examples/prize_collecting_vrp.ipynb index 59f667c073..1d0da49a88 100644 --- a/examples/notebook/examples/prize_collecting_vrp.ipynb +++ b/examples/notebook/examples/prize_collecting_vrp.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -241,7 +241,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/prize_collecting_vrp_sat.ipynb b/examples/notebook/examples/prize_collecting_vrp_sat.ipynb index e0565da839..f95ccd07e8 100644 --- a/examples/notebook/examples/prize_collecting_vrp_sat.ipynb +++ b/examples/notebook/examples/prize_collecting_vrp_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -273,7 +273,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/proto_solve.ipynb b/examples/notebook/examples/proto_solve.ipynb index 8ef8b466e2..b0eee3dbdd 100644 --- a/examples/notebook/examples/proto_solve.ipynb +++ b/examples/notebook/examples/proto_solve.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -114,7 +114,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/pyflow_example.ipynb b/examples/notebook/examples/pyflow_example.ipynb index d90c8fc992..ef8a5b42f5 100644 --- a/examples/notebook/examples/pyflow_example.ipynb +++ b/examples/notebook/examples/pyflow_example.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -156,7 +156,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/qubo_sat.ipynb b/examples/notebook/examples/qubo_sat.ipynb index 2372041466..78f5e8c9b6 100644 --- a/examples/notebook/examples/qubo_sat.ipynb +++ b/examples/notebook/examples/qubo_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -774,7 +774,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/random_tsp.ipynb b/examples/notebook/examples/random_tsp.ipynb index 179aad7477..b07e34c39c 100644 --- a/examples/notebook/examples/random_tsp.ipynb +++ b/examples/notebook/examples/random_tsp.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -219,7 +219,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/rcpsp_sat.ipynb b/examples/notebook/examples/rcpsp_sat.ipynb index ee96bdd88b..ce576100c6 100644 --- a/examples/notebook/examples/rcpsp_sat.ipynb +++ b/examples/notebook/examples/rcpsp_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -885,7 +885,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/reallocate_sat.ipynb b/examples/notebook/examples/reallocate_sat.ipynb index 3a1aa56091..573ca14210 100644 --- a/examples/notebook/examples/reallocate_sat.ipynb +++ b/examples/notebook/examples/reallocate_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -204,7 +204,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/shift_scheduling_sat.ipynb b/examples/notebook/examples/shift_scheduling_sat.ipynb index 68ae241e11..9341c50148 100644 --- a/examples/notebook/examples/shift_scheduling_sat.ipynb +++ b/examples/notebook/examples/shift_scheduling_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -525,7 +525,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/single_machine_scheduling_with_setup_release_due_dates_sat.ipynb b/examples/notebook/examples/single_machine_scheduling_with_setup_release_due_dates_sat.ipynb index b8f6fede11..a01f93c92e 100644 --- a/examples/notebook/examples/single_machine_scheduling_with_setup_release_due_dates_sat.ipynb +++ b/examples/notebook/examples/single_machine_scheduling_with_setup_release_due_dates_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -588,7 +588,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/spread_robots_sat.ipynb b/examples/notebook/examples/spread_robots_sat.ipynb index f59067cf5d..09f31c81d4 100644 --- a/examples/notebook/examples/spread_robots_sat.ipynb +++ b/examples/notebook/examples/spread_robots_sat.ipynb @@ -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 } diff --git a/examples/notebook/examples/steel_mill_slab_sat.ipynb b/examples/notebook/examples/steel_mill_slab_sat.ipynb index effe92258d..c6124111f0 100644 --- a/examples/notebook/examples/steel_mill_slab_sat.ipynb +++ b/examples/notebook/examples/steel_mill_slab_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -644,7 +644,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/sudoku_sat.ipynb b/examples/notebook/examples/sudoku_sat.ipynb index 85bf780cb1..1757e95637 100644 --- a/examples/notebook/examples/sudoku_sat.ipynb +++ b/examples/notebook/examples/sudoku_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -150,7 +150,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/task_allocation_sat.ipynb b/examples/notebook/examples/task_allocation_sat.ipynb index ab7e77752d..8c07a8ff0c 100644 --- a/examples/notebook/examples/task_allocation_sat.ipynb +++ b/examples/notebook/examples/task_allocation_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -367,7 +367,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/tasks_and_workers_assignment_sat.ipynb b/examples/notebook/examples/tasks_and_workers_assignment_sat.ipynb index 2bfdd2250f..545c549f12 100644 --- a/examples/notebook/examples/tasks_and_workers_assignment_sat.ipynb +++ b/examples/notebook/examples/tasks_and_workers_assignment_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -202,7 +202,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/test_scheduling_sat.ipynb b/examples/notebook/examples/test_scheduling_sat.ipynb index fd94dc99cd..6d8c8394af 100644 --- a/examples/notebook/examples/test_scheduling_sat.ipynb +++ b/examples/notebook/examples/test_scheduling_sat.ipynb @@ -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 } diff --git a/examples/notebook/examples/transit_time.ipynb b/examples/notebook/examples/transit_time.ipynb index 073c4d9aa7..8f75f9028e 100644 --- a/examples/notebook/examples/transit_time.ipynb +++ b/examples/notebook/examples/transit_time.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -292,7 +292,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/tsp_sat.ipynb b/examples/notebook/examples/tsp_sat.ipynb index 8704e02160..6d96251767 100644 --- a/examples/notebook/examples/tsp_sat.ipynb +++ b/examples/notebook/examples/tsp_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -197,7 +197,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/vendor_scheduling_sat.ipynb b/examples/notebook/examples/vendor_scheduling_sat.ipynb index f23d5dc94b..bd8daacd8e 100644 --- a/examples/notebook/examples/vendor_scheduling_sat.ipynb +++ b/examples/notebook/examples/vendor_scheduling_sat.ipynb @@ -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 } diff --git a/examples/notebook/examples/wedding_optimal_chart_sat.ipynb b/examples/notebook/examples/wedding_optimal_chart_sat.ipynb index c27f1c2c78..48bc9ca31c 100644 --- a/examples/notebook/examples/wedding_optimal_chart_sat.ipynb +++ b/examples/notebook/examples/wedding_optimal_chart_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -319,7 +319,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/examples/weighted_latency_problem_sat.ipynb b/examples/notebook/examples/weighted_latency_problem_sat.ipynb index 5267fe8663..7d0bb9980a 100644 --- a/examples/notebook/examples/weighted_latency_problem_sat.ipynb +++ b/examples/notebook/examples/weighted_latency_problem_sat.ipynb @@ -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 } diff --git a/examples/notebook/examples/zebra_sat.ipynb b/examples/notebook/examples/zebra_sat.ipynb index 3b78497478..f8a1197f35 100644 --- a/examples/notebook/examples/zebra_sat.ipynb +++ b/examples/notebook/examples/zebra_sat.ipynb @@ -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 } diff --git a/examples/notebook/graph/assignment_linear_sum_assignment.ipynb b/examples/notebook/graph/assignment_linear_sum_assignment.ipynb index c0edfe8444..3692e1e9e6 100644 --- a/examples/notebook/graph/assignment_linear_sum_assignment.ipynb +++ b/examples/notebook/graph/assignment_linear_sum_assignment.ipynb @@ -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 } diff --git a/examples/notebook/graph/assignment_min_flow.ipynb b/examples/notebook/graph/assignment_min_flow.ipynb index e8a998a10d..330903a1ec 100644 --- a/examples/notebook/graph/assignment_min_flow.ipynb +++ b/examples/notebook/graph/assignment_min_flow.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -113,20 +113,19 @@ " supplies = [tasks, 0, 0, 0, 0, 0, 0, 0, 0, -tasks]\n", "\n", " # Add each arc.\n", - " for i in range(len(start_nodes)):\n", - " smcf.add_arc_with_capacity_and_unit_cost(\n", - " start_nodes[i], end_nodes[i], capacities[i], costs[i]\n", - " )\n", + " for start_node, end_node, capacity, cost in zip(\n", + " start_nodes, end_nodes, capacities, costs\n", + " ):\n", + " smcf.add_arc_with_capacity_and_unit_cost(start_node, end_node, capacity, cost)\n", " # Add node supplies.\n", - " for i in range(len(supplies)):\n", - " smcf.set_node_supply(i, supplies[i])\n", + " for idx, supply in enumerate(supplies):\n", + " smcf.set_node_supply(idx, supply)\n", "\n", " # Find the minimum cost flow between node 0 and node 10.\n", " status = smcf.solve()\n", "\n", " if status == smcf.OPTIMAL:\n", - " print(\"Total cost = \", smcf.optimal_cost())\n", - " print()\n", + " print(f\"Total cost = {smcf.optimal_cost()}\")\n", " for arc in range(smcf.num_arcs()):\n", " # Can ignore arcs leading out of source or into sink.\n", " if smcf.tail(arc) != source and smcf.head(arc) != sink:\n", @@ -135,8 +134,8 @@ " # give an assignment of worker to task.\n", " if smcf.flow(arc) > 0:\n", " print(\n", - " \"Worker %d assigned to task %d. Cost = %d\"\n", - " % (smcf.tail(arc), smcf.head(arc), smcf.unit_cost(arc))\n", + " f\"Worker {smcf.tail(arc)} assigned to task {smcf.head(arc)}. \"\n", + " f\"Cost = {smcf.unit_cost(arc)}\"\n", " )\n", " else:\n", " print(\"There was an issue with the min cost flow input.\")\n", @@ -148,7 +147,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/graph/balance_min_flow.ipynb b/examples/notebook/graph/balance_min_flow.ipynb index b1c9d3fbd9..6f25892b61 100644 --- a/examples/notebook/graph/balance_min_flow.ipynb +++ b/examples/notebook/graph/balance_min_flow.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -179,7 +179,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/graph/simple_max_flow_program.ipynb b/examples/notebook/graph/simple_max_flow_program.ipynb index 565b87b392..5e6cabde02 100644 --- a/examples/notebook/graph/simple_max_flow_program.ipynb +++ b/examples/notebook/graph/simple_max_flow_program.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -126,7 +126,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/graph/simple_min_cost_flow_program.ipynb b/examples/notebook/graph/simple_min_cost_flow_program.ipynb index 0f754965ee..8f78329717 100644 --- a/examples/notebook/graph/simple_min_cost_flow_program.ipynb +++ b/examples/notebook/graph/simple_min_cost_flow_program.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -126,7 +126,8 @@ " costs = solution_flows * unit_costs\n", " for arc, flow, cost in zip(all_arcs, solution_flows, costs):\n", " print(\n", - " f\"{smcf.tail(arc):1} -> {smcf.head(arc)} {flow:3} / {smcf.capacity(arc):3} {cost}\"\n", + " f\"{smcf.tail(arc):1} -> \"\n", + " f\"{smcf.head(arc)} {flow:3} / {smcf.capacity(arc):3} {cost}\"\n", " )\n", "\n", "\n", @@ -135,7 +136,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/assignment_groups_mip.ipynb b/examples/notebook/linear_solver/assignment_groups_mip.ipynb index e2c72d3bd5..6a1a256796 100644 --- a/examples/notebook/linear_solver/assignment_groups_mip.ipynb +++ b/examples/notebook/linear_solver/assignment_groups_mip.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/assignment_mb.ipynb b/examples/notebook/linear_solver/assignment_mb.ipynb index a6808aeacd..ad5d07ee42 100644 --- a/examples/notebook/linear_solver/assignment_mb.ipynb +++ b/examples/notebook/linear_solver/assignment_mb.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/assignment_mip.ipynb b/examples/notebook/linear_solver/assignment_mip.ipynb index f814693fa9..60119e7f4c 100644 --- a/examples/notebook/linear_solver/assignment_mip.ipynb +++ b/examples/notebook/linear_solver/assignment_mip.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -150,7 +150,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/assignment_task_sizes_mip.ipynb b/examples/notebook/linear_solver/assignment_task_sizes_mip.ipynb index 3bfb3141f4..a4c4ca6dbf 100644 --- a/examples/notebook/linear_solver/assignment_task_sizes_mip.ipynb +++ b/examples/notebook/linear_solver/assignment_task_sizes_mip.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -166,7 +166,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/assignment_teams_mip.ipynb b/examples/notebook/linear_solver/assignment_teams_mip.ipynb index 5726a5d5ef..6414ace0dd 100644 --- a/examples/notebook/linear_solver/assignment_teams_mip.ipynb +++ b/examples/notebook/linear_solver/assignment_teams_mip.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/basic_example.ipynb b/examples/notebook/linear_solver/basic_example.ipynb index 536f091e80..525689e1a4 100644 --- a/examples/notebook/linear_solver/basic_example.ipynb +++ b/examples/notebook/linear_solver/basic_example.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -148,7 +148,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/bin_packing_mb.ipynb b/examples/notebook/linear_solver/bin_packing_mb.ipynb index e848fa7fe9..205acb33e2 100644 --- a/examples/notebook/linear_solver/bin_packing_mb.ipynb +++ b/examples/notebook/linear_solver/bin_packing_mb.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/bin_packing_mip.ipynb b/examples/notebook/linear_solver/bin_packing_mip.ipynb index 58fc818c3d..53d68248b5 100644 --- a/examples/notebook/linear_solver/bin_packing_mip.ipynb +++ b/examples/notebook/linear_solver/bin_packing_mip.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -165,7 +165,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/clone_model_mb.ipynb b/examples/notebook/linear_solver/clone_model_mb.ipynb index 350ecc4c4b..f64b365cf4 100644 --- a/examples/notebook/linear_solver/clone_model_mb.ipynb +++ b/examples/notebook/linear_solver/clone_model_mb.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -146,7 +146,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/integer_programming_example.ipynb b/examples/notebook/linear_solver/integer_programming_example.ipynb index 7dd5b31fdb..49a9a840ea 100644 --- a/examples/notebook/linear_solver/integer_programming_example.ipynb +++ b/examples/notebook/linear_solver/integer_programming_example.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -151,7 +151,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/linear_programming_example.ipynb b/examples/notebook/linear_solver/linear_programming_example.ipynb index 7ee26107cd..3db71f1df0 100644 --- a/examples/notebook/linear_solver/linear_programming_example.ipynb +++ b/examples/notebook/linear_solver/linear_programming_example.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -135,7 +135,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/mip_var_array.ipynb b/examples/notebook/linear_solver/mip_var_array.ipynb index f0f8664fdd..0a1575fc96 100644 --- a/examples/notebook/linear_solver/mip_var_array.ipynb +++ b/examples/notebook/linear_solver/mip_var_array.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -155,7 +155,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/multiple_knapsack_mip.ipynb b/examples/notebook/linear_solver/multiple_knapsack_mip.ipynb index 8e8125b9af..ab752d2a99 100644 --- a/examples/notebook/linear_solver/multiple_knapsack_mip.ipynb +++ b/examples/notebook/linear_solver/multiple_knapsack_mip.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/simple_lp_program.ipynb b/examples/notebook/linear_solver/simple_lp_program.ipynb index 4775ecdfbd..8878896a77 100644 --- a/examples/notebook/linear_solver/simple_lp_program.ipynb +++ b/examples/notebook/linear_solver/simple_lp_program.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -131,7 +131,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/simple_lp_program_mb.ipynb b/examples/notebook/linear_solver/simple_lp_program_mb.ipynb index bee79cf01f..b974525215 100644 --- a/examples/notebook/linear_solver/simple_lp_program_mb.ipynb +++ b/examples/notebook/linear_solver/simple_lp_program_mb.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -135,7 +135,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/linear_solver/simple_mip_program.ipynb b/examples/notebook/linear_solver/simple_mip_program.ipynb index b3c6b8ad24..9ba26454b5 100644 --- a/examples/notebook/linear_solver/simple_mip_program.ipynb +++ b/examples/notebook/linear_solver/simple_mip_program.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/simple_mip_program_mb.ipynb b/examples/notebook/linear_solver/simple_mip_program_mb.ipynb index 9fb3f76d99..9feaf39005 100644 --- a/examples/notebook/linear_solver/simple_mip_program_mb.ipynb +++ b/examples/notebook/linear_solver/simple_mip_program_mb.ipynb @@ -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 } diff --git a/examples/notebook/linear_solver/stigler_diet.ipynb b/examples/notebook/linear_solver/stigler_diet.ipynb index d57c2dafa5..50bc390dbe 100644 --- a/examples/notebook/linear_solver/stigler_diet.ipynb +++ b/examples/notebook/linear_solver/stigler_diet.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -253,7 +253,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/pdlp/simple_pdlp_program.ipynb b/examples/notebook/pdlp/simple_pdlp_program.ipynb index 4cb305fd49..4b0ebce9d6 100644 --- a/examples/notebook/pdlp/simple_pdlp_program.ipynb +++ b/examples/notebook/pdlp/simple_pdlp_program.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -181,7 +181,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/all_different_except_zero_sample_sat.ipynb b/examples/notebook/sat/all_different_except_zero_sample_sat.ipynb index deb2a3f1bb..85cb5eb0cc 100644 --- a/examples/notebook/sat/all_different_except_zero_sample_sat.ipynb +++ b/examples/notebook/sat/all_different_except_zero_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -155,7 +155,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/assignment_groups_sat.ipynb b/examples/notebook/sat/assignment_groups_sat.ipynb index 5bebc34dcf..73eb399212 100644 --- a/examples/notebook/sat/assignment_groups_sat.ipynb +++ b/examples/notebook/sat/assignment_groups_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/assignment_sat.ipynb b/examples/notebook/sat/assignment_sat.ipynb index 012e9219af..71bd3c24bb 100644 --- a/examples/notebook/sat/assignment_sat.ipynb +++ b/examples/notebook/sat/assignment_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -157,7 +157,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/assignment_task_sizes_sat.ipynb b/examples/notebook/sat/assignment_task_sizes_sat.ipynb index aa2c528af5..72bd0de62d 100644 --- a/examples/notebook/sat/assignment_task_sizes_sat.ipynb +++ b/examples/notebook/sat/assignment_task_sizes_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -158,7 +158,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/assignment_teams_sat.ipynb b/examples/notebook/sat/assignment_teams_sat.ipynb index 5e50e35875..fce76578e7 100644 --- a/examples/notebook/sat/assignment_teams_sat.ipynb +++ b/examples/notebook/sat/assignment_teams_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -165,7 +165,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/assumptions_sample_sat.ipynb b/examples/notebook/sat/assumptions_sample_sat.ipynb index b76394e579..4f7b03e604 100644 --- a/examples/notebook/sat/assumptions_sample_sat.ipynb +++ b/examples/notebook/sat/assumptions_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -125,7 +125,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/bin_packing_sat.ipynb b/examples/notebook/sat/bin_packing_sat.ipynb index 638ea767a9..b72dc66faf 100644 --- a/examples/notebook/sat/bin_packing_sat.ipynb +++ b/examples/notebook/sat/bin_packing_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/binpacking_problem_sat.ipynb b/examples/notebook/sat/binpacking_problem_sat.ipynb index 81a5b31467..e85817cf1f 100644 --- a/examples/notebook/sat/binpacking_problem_sat.ipynb +++ b/examples/notebook/sat/binpacking_problem_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -151,7 +151,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/bool_and_int_var_product_sample_sat.ipynb b/examples/notebook/sat/bool_and_int_var_product_sample_sat.ipynb index 741e862cde..bc0bde618c 100644 --- a/examples/notebook/sat/bool_and_int_var_product_sample_sat.ipynb +++ b/examples/notebook/sat/bool_and_int_var_product_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -144,7 +144,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/bool_or_sample_sat.ipynb b/examples/notebook/sat/bool_or_sample_sat.ipynb index 004c570642..5287a2fb8a 100644 --- a/examples/notebook/sat/bool_or_sample_sat.ipynb +++ b/examples/notebook/sat/bool_or_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -104,7 +104,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/boolean_product_sample_sat.ipynb b/examples/notebook/sat/boolean_product_sample_sat.ipynb index 206189e2dc..b1c6991940 100644 --- a/examples/notebook/sat/boolean_product_sample_sat.ipynb +++ b/examples/notebook/sat/boolean_product_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -116,7 +116,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/channeling_sample_sat.ipynb b/examples/notebook/sat/channeling_sample_sat.ipynb index 87c91888ff..a70be19392 100644 --- a/examples/notebook/sat/channeling_sample_sat.ipynb +++ b/examples/notebook/sat/channeling_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -144,7 +144,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/clone_model_sample_sat.ipynb b/examples/notebook/sat/clone_model_sample_sat.ipynb index 0f07c81c5c..c614d1e610 100644 --- a/examples/notebook/sat/clone_model_sample_sat.ipynb +++ b/examples/notebook/sat/clone_model_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -128,7 +128,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/cp_is_fun_sat.ipynb b/examples/notebook/sat/cp_is_fun_sat.ipynb index d8c3facd9a..7449863b81 100644 --- a/examples/notebook/sat/cp_is_fun_sat.ipynb +++ b/examples/notebook/sat/cp_is_fun_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -165,7 +165,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/cp_sat_example.ipynb b/examples/notebook/sat/cp_sat_example.ipynb index 130032976b..e6564844a3 100644 --- a/examples/notebook/sat/cp_sat_example.ipynb +++ b/examples/notebook/sat/cp_sat_example.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -129,7 +129,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/cumulative_variable_profile_sample_sat.ipynb b/examples/notebook/sat/cumulative_variable_profile_sample_sat.ipynb index 236fdd83b4..0e1dc12686 100644 --- a/examples/notebook/sat/cumulative_variable_profile_sample_sat.ipynb +++ b/examples/notebook/sat/cumulative_variable_profile_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -313,7 +313,7 @@ "\n", " # Create the solver and solve the model.\n", " solver = cp_model.CpSolver()\n", - " solver.parameters.log_search_progress = True\n", + " # solver.parameters.log_search_progress = True # Uncomment to see the logs.\n", " solver.parameters.num_workers = 16\n", " solver.parameters.max_time_in_seconds = 30.0\n", " status = solver.solve(model)\n", @@ -351,7 +351,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/earliness_tardiness_cost_sample_sat.ipynb b/examples/notebook/sat/earliness_tardiness_cost_sample_sat.ipynb index 3f2d6595c2..d05156126e 100644 --- a/examples/notebook/sat/earliness_tardiness_cost_sample_sat.ipynb +++ b/examples/notebook/sat/earliness_tardiness_cost_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -158,7 +158,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/index_first_boolvar_true_sample_sat.ipynb b/examples/notebook/sat/index_first_boolvar_true_sample_sat.ipynb index 4c6e816d8c..b3c53dd3c0 100644 --- a/examples/notebook/sat/index_first_boolvar_true_sample_sat.ipynb +++ b/examples/notebook/sat/index_first_boolvar_true_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -144,7 +144,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/interval_relations_sample_sat.ipynb b/examples/notebook/sat/interval_relations_sample_sat.ipynb index 397249ba5e..279225719a 100644 --- a/examples/notebook/sat/interval_relations_sample_sat.ipynb +++ b/examples/notebook/sat/interval_relations_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -150,7 +150,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/interval_sample_sat.ipynb b/examples/notebook/sat/interval_sample_sat.ipynb index 493c78ace5..bddaafb099 100644 --- a/examples/notebook/sat/interval_sample_sat.ipynb +++ b/examples/notebook/sat/interval_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -117,7 +117,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/literal_sample_sat.ipynb b/examples/notebook/sat/literal_sample_sat.ipynb index be8ff9ab74..9c660cc1c7 100644 --- a/examples/notebook/sat/literal_sample_sat.ipynb +++ b/examples/notebook/sat/literal_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -100,7 +100,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/minimal_jobshop_sat.ipynb b/examples/notebook/sat/minimal_jobshop_sat.ipynb index 1fc4886873..fd936e2dc4 100644 --- a/examples/notebook/sat/minimal_jobshop_sat.ipynb +++ b/examples/notebook/sat/minimal_jobshop_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -210,7 +210,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/multiple_knapsack_sat.ipynb b/examples/notebook/sat/multiple_knapsack_sat.ipynb index 95eec40688..001495e7fc 100644 --- a/examples/notebook/sat/multiple_knapsack_sat.ipynb +++ b/examples/notebook/sat/multiple_knapsack_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -157,7 +157,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/no_overlap_sample_sat.ipynb b/examples/notebook/sat/no_overlap_sample_sat.ipynb index 2cdb3ec36c..99912d7052 100644 --- a/examples/notebook/sat/no_overlap_sample_sat.ipynb +++ b/examples/notebook/sat/no_overlap_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -140,7 +140,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/non_linear_sat.ipynb b/examples/notebook/sat/non_linear_sat.ipynb index 6a612e344b..d55e1b8e76 100644 --- a/examples/notebook/sat/non_linear_sat.ipynb +++ b/examples/notebook/sat/non_linear_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/nqueens_sat.ipynb b/examples/notebook/sat/nqueens_sat.ipynb index 019fb94777..e327111e33 100644 --- a/examples/notebook/sat/nqueens_sat.ipynb +++ b/examples/notebook/sat/nqueens_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/nurses_sat.ipynb b/examples/notebook/sat/nurses_sat.ipynb index 02cf4d5aa2..3d92555b5b 100644 --- a/examples/notebook/sat/nurses_sat.ipynb +++ b/examples/notebook/sat/nurses_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/optional_interval_sample_sat.ipynb b/examples/notebook/sat/optional_interval_sample_sat.ipynb index f356012ecf..cb903f8a7c 100644 --- a/examples/notebook/sat/optional_interval_sample_sat.ipynb +++ b/examples/notebook/sat/optional_interval_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -121,7 +121,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/overlapping_intervals_sample_sat.ipynb b/examples/notebook/sat/overlapping_intervals_sample_sat.ipynb index 0eab065320..4af8c36c77 100644 --- a/examples/notebook/sat/overlapping_intervals_sample_sat.ipynb +++ b/examples/notebook/sat/overlapping_intervals_sample_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/rabbits_and_pheasants_sat.ipynb b/examples/notebook/sat/rabbits_and_pheasants_sat.ipynb index 63dc2a60b8..100e2cf81d 100644 --- a/examples/notebook/sat/rabbits_and_pheasants_sat.ipynb +++ b/examples/notebook/sat/rabbits_and_pheasants_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -111,7 +111,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/ranking_circuit_sample_sat.ipynb b/examples/notebook/sat/ranking_circuit_sample_sat.ipynb index fb87e45064..8f7be0d794 100644 --- a/examples/notebook/sat/ranking_circuit_sample_sat.ipynb +++ b/examples/notebook/sat/ranking_circuit_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -250,7 +250,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/ranking_sample_sat.ipynb b/examples/notebook/sat/ranking_sample_sat.ipynb index 8dc5a41d81..08bc583a9b 100644 --- a/examples/notebook/sat/ranking_sample_sat.ipynb +++ b/examples/notebook/sat/ranking_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -231,7 +231,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/reified_sample_sat.ipynb b/examples/notebook/sat/reified_sample_sat.ipynb index 0ad5d78137..84af78436f 100644 --- a/examples/notebook/sat/reified_sample_sat.ipynb +++ b/examples/notebook/sat/reified_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -111,7 +111,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/schedule_requests_sat.ipynb b/examples/notebook/sat/schedule_requests_sat.ipynb index 42333d160a..0864dedff6 100644 --- a/examples/notebook/sat/schedule_requests_sat.ipynb +++ b/examples/notebook/sat/schedule_requests_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/scheduling_with_calendar_sample_sat.ipynb b/examples/notebook/sat/scheduling_with_calendar_sample_sat.ipynb index 0ddd27e1e6..c5aac301af 100644 --- a/examples/notebook/sat/scheduling_with_calendar_sample_sat.ipynb +++ b/examples/notebook/sat/scheduling_with_calendar_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -151,7 +151,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/search_for_all_solutions_sample_sat.ipynb b/examples/notebook/sat/search_for_all_solutions_sample_sat.ipynb index 90bb0d27f6..3861df6cef 100644 --- a/examples/notebook/sat/search_for_all_solutions_sample_sat.ipynb +++ b/examples/notebook/sat/search_for_all_solutions_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -136,7 +136,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/sequences_in_no_overlap_sample_sat.ipynb b/examples/notebook/sat/sequences_in_no_overlap_sample_sat.ipynb new file mode 100644 index 0000000000..0cf40020dc --- /dev/null +++ b/examples/notebook/sat/sequences_in_no_overlap_sample_sat.ipynb @@ -0,0 +1,379 @@ +{ + "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": [ + "# sequences_in_no_overlap_sample_sat" + ] + }, + { + "cell_type": "markdown", + "id": "link", + "metadata": {}, + "source": [ + "\n", + "\n", + "\n", + "
\n", + "Run in Google Colab\n", + "\n", + "View source on GitHub\n", + "
" + ] + }, + { + "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", + "Implements sequence constraints in a no_overlap constraint.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "code", + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Dict, List, Sequence, Tuple\n", + "\n", + "from ortools.sat.python import cp_model\n", + "\n", + "\n", + "def sequence_constraints_with_circuit(\n", + " model: cp_model.CpModel,\n", + " starts: Sequence[cp_model.IntVar],\n", + " durations: Sequence[int],\n", + " task_types: Sequence[str],\n", + " lengths: Sequence[cp_model.IntVar],\n", + " cumuls: Sequence[cp_model.IntVar],\n", + " sequence_length_constraints: Dict[str, Tuple[int, int]],\n", + " sequence_cumul_constraints: Dict[str, Tuple[int, int, int]],\n", + ") -> Sequence[Tuple[cp_model.IntVar, int]]:\n", + " \"\"\"This method enforces constraints on sequences of tasks of the same type.\n", + "\n", + " This method assumes that all durations are strictly positive.\n", + "\n", + " The extra node (with id 0) will be used to decide which task is first with\n", + " its only outgoing arc, and which task is last with its only incoming arc.\n", + " Each task i will be associated with id i + 1, and an arc between i + 1 and j +\n", + " 1 indicates that j is the immediate successor of i.\n", + "\n", + " The circuit constraint ensures there is at most 1 hamiltonian cycle of\n", + " length > 1. If no such path exists, then no tasks are active.\n", + " In this simplified model, all tasks must be performed.\n", + "\n", + " Args:\n", + " model: The CpModel to add the constraints to.\n", + " starts: The array of starts variables of all tasks.\n", + " durations: the durations of all tasks.\n", + " task_types: The type of all tasks.\n", + " lengths: the number of tasks of the same type in the current sequence.\n", + " cumuls: The computed cumul of the current sequence for each task.\n", + " sequence_length_constraints: the array of tuple (`task_type`, (`length_min`,\n", + " `length_max`)) that specifies the minimum and maximum length of the\n", + " sequence of tasks of type `task_type`.\n", + " sequence_cumul_constraints: the array of tuple (`task_type`, (`soft_max`,\n", + " `linear_penalty`, `hard_max`)) that specifies that if the cumul of the\n", + " sequence of tasks of type `task_type` is greater than `soft_max`, then\n", + " `linear_penalty * (cumul - soft_max)` is added to the cost\n", + "\n", + " Returns:\n", + " The list of pairs (integer variables, penalty) to be added to the objective.\n", + " \"\"\"\n", + "\n", + " num_tasks = len(starts)\n", + " all_tasks = range(num_tasks)\n", + "\n", + " arcs: List[cp_model.ArcT] = []\n", + " for i in all_tasks:\n", + " # if node i is first.\n", + " start_lit = model.new_bool_var(f\"start_{i}\")\n", + " arcs.append((0, i + 1, start_lit))\n", + " model.add(lengths[i] == 1).only_enforce_if(start_lit)\n", + " model.add(cumuls[i] == durations[i]).only_enforce_if(start_lit)\n", + "\n", + " # As there are no other constraints on the problem, we can add this\n", + " # redundant constraint. This is not valid in general.\n", + " model.add(starts[i] == 0).only_enforce_if(start_lit)\n", + "\n", + " # if node i is last.\n", + " end_lit = model.new_bool_var(f\"end_{i}\")\n", + " arcs.append((i + 1, 0, end_lit))\n", + "\n", + " # Make sure the previous length is within bounds.\n", + " type_length_min = sequence_length_constraints[task_types[i]][0]\n", + " model.add(lengths[i] >= type_length_min).only_enforce_if(end_lit)\n", + "\n", + " for j in all_tasks:\n", + " if i == j:\n", + " continue\n", + " lit = model.new_bool_var(f\"arc_{i}_to_{j}\")\n", + " arcs.append((i + 1, j + 1, lit))\n", + "\n", + " # The circuit constraint is use to enforce the consistency between the\n", + " # precedences relations and the successor arcs. This is implemented by\n", + " # adding the constraint that force the implication task j is the next of\n", + " # task i implies that start(j) is greater or equal than the end(i).\n", + " #\n", + " # In the majority of problems, the following equality must be an\n", + " # inequality. In that particular case, as there are no extra constraints,\n", + " # we can keep the equality between start(j) and end(i).\n", + " model.add(starts[j] == starts[i] + durations[i]).only_enforce_if(lit)\n", + "\n", + " # We add the constraints to incrementally maintain the length and the\n", + " # cumul variables of the sequence.\n", + " if task_types[i] == task_types[j]: # Same task type.\n", + " # Increase the length of the sequence by 1.\n", + " model.add(lengths[j] == lengths[i] + 1).only_enforce_if(lit)\n", + "\n", + " # Increase the cumul of the sequence by the duration of the task.\n", + " model.add(cumuls[j] == cumuls[i] + durations[j]).only_enforce_if(lit)\n", + "\n", + " else:\n", + " # Switching task type. task[i] is the last task of the previous\n", + " # sequence, task[j] is the first task of the new sequence.\n", + " #\n", + " # Reset the length to 1.\n", + " model.add(lengths[j] == 1).only_enforce_if(lit)\n", + "\n", + " # Make sure the previous length is within bounds.\n", + " type_length_min = sequence_length_constraints[task_types[i]][0]\n", + " model.add(lengths[i] >= type_length_min).only_enforce_if(lit)\n", + "\n", + " # Reset the cumul to the duration of the task.\n", + " model.add(cumuls[j] == durations[j]).only_enforce_if(lit)\n", + "\n", + " # Add the circuit constraint.\n", + " model.add_circuit(arcs)\n", + "\n", + " # Create the penalty terms. We can penalize each cumul locally.\n", + " penalty_terms = []\n", + " for i in all_tasks:\n", + " # Penalize the cumul of the last task w.r.t. the soft max\n", + " soft_max, linear_penalty, hard_max = sequence_cumul_constraints[task_types[i]]\n", + "\n", + " # To make it separable per task, and avoid double counting, we use the\n", + " # following trick:\n", + " # reduced_excess = min(durations[i], max(0, cumul[i] - soft_max))\n", + " if soft_max < hard_max:\n", + " excess = model.new_int_var(0, hard_max - soft_max, f\"excess+_{i}\")\n", + " model.add_max_equality(excess, [0, cumuls[i] - soft_max])\n", + " reduced_excess = model.new_int_var(0, durations[i], f\"reduced_excess_{i}\")\n", + " model.add_min_equality(reduced_excess, [durations[i], excess])\n", + " penalty_terms.append((reduced_excess, linear_penalty))\n", + "\n", + " return penalty_terms\n", + "\n", + "\n", + "def sequences_in_no_overlap_sample_sat():\n", + " \"\"\"Implement cumul and length constraints in a NoOverlap constraint.\"\"\"\n", + "\n", + " # Tasks (duration, type).\n", + " tasks = [\n", + " (5, \"A\"),\n", + " (6, \"A\"),\n", + " (7, \"A\"),\n", + " (2, \"A\"),\n", + " (3, \"A\"),\n", + " (5, \"B\"),\n", + " (2, \"B\"),\n", + " (3, \"B\"),\n", + " (1, \"B\"),\n", + " (4, \"B\"),\n", + " (3, \"B\"),\n", + " (6, \"B\"),\n", + " (2, \"B\"),\n", + " ]\n", + "\n", + " # Sequence length constraints per task_types: (hard_min, hard_max)\n", + " #\n", + " # Note that this constraint is very tight for task type B and will fail with\n", + " # an odd number of tasks of type B.\n", + " sequence_length_constraints = {\n", + " \"A\": (1, 3),\n", + " \"B\": (2, 2),\n", + " }\n", + "\n", + " # Sequence accumulated durations constraints per task_types:\n", + " # (soft_max, linear_penalty, hard_max)\n", + " sequence_cumul_constraints = {\n", + " \"A\": (6, 1, 10),\n", + " \"B\": (7, 0, 7),\n", + " }\n", + "\n", + " model: cp_model.CpModel = cp_model.CpModel()\n", + " horizon: int = sum(t[0] for t in tasks)\n", + "\n", + " num_tasks = len(tasks)\n", + " all_tasks = range(num_tasks)\n", + "\n", + " starts = []\n", + " durations = []\n", + " intervals = []\n", + " task_types = []\n", + "\n", + " # Creates intervals for each task.\n", + " for duration, task_type in tasks:\n", + " index = len(starts)\n", + " start = model.new_int_var(0, horizon - duration, f\"start[{index}]\")\n", + " interval = model.new_fixed_size_interval_var(\n", + " start, duration, f\"interval[{index}]\"\n", + " )\n", + "\n", + " starts.append(start)\n", + " durations.append(duration)\n", + " intervals.append(interval)\n", + " task_types.append(task_type)\n", + "\n", + " # Create length variables for each task.\n", + " lengths = []\n", + " for i in all_tasks:\n", + " max_hard_length = sequence_length_constraints[task_types[i]][1]\n", + " lengths.append(model.new_int_var(1, max_hard_length, f\"length_{i}\"))\n", + "\n", + " # Create cumul variables for each task.\n", + " cumuls = []\n", + " for i in all_tasks:\n", + " max_hard_cumul = sequence_cumul_constraints[task_types[i]][2]\n", + " cumuls.append(model.new_int_var(durations[i], max_hard_cumul, f\"cumul_{i}\"))\n", + "\n", + " # Adds NoOverlap constraint.\n", + " model.add_no_overlap(intervals)\n", + "\n", + " # Adds the constraints on the lengths and cumuls of maximal sequences of\n", + " # tasks of the same type.\n", + " penalty_terms = sequence_constraints_with_circuit(\n", + " model,\n", + " starts,\n", + " durations,\n", + " task_types,\n", + " lengths,\n", + " cumuls,\n", + " sequence_length_constraints,\n", + " sequence_cumul_constraints,\n", + " )\n", + "\n", + " # Minimize the sum of penalties,\n", + " model.minimize(sum(var * penalty for var, penalty in penalty_terms))\n", + "\n", + " # Solves the model model.\n", + " solver = cp_model.CpSolver()\n", + " status = solver.solve(model)\n", + "\n", + " if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:\n", + " # Prints out the makespan and the start times and lengths, cumuls at each\n", + " # step.\n", + " if status == cp_model.OPTIMAL:\n", + " print(f\"Optimal cost: {solver.objective_value}\")\n", + " else:\n", + " print(f\"Feasible cost: {solver.objective_value}\")\n", + "\n", + " to_sort = []\n", + " for t in all_tasks:\n", + " to_sort.append((solver.value(starts[t]), t))\n", + " to_sort.sort()\n", + "\n", + " sum_of_penalties = 0\n", + " for i, (start, t) in enumerate(to_sort):\n", + " # Check length constraints.\n", + " length: int = solver.value(lengths[t])\n", + " hard_min_length, hard_max_length = sequence_length_constraints[\n", + " task_types[t]\n", + " ]\n", + " assert length >= 0\n", + " assert length <= hard_max_length\n", + " if (\n", + " i + 1 == len(to_sort) or task_types[t] != task_types[to_sort[i + 1][1]]\n", + " ): # End of sequence.\n", + " assert length >= hard_min_length\n", + "\n", + " # Check cumul constraints.\n", + " cumul: int = solver.value(cumuls[t])\n", + " soft_max_cumul, penalty, hard_max_cumul = sequence_cumul_constraints[\n", + " task_types[t]\n", + " ]\n", + " assert cumul >= 0\n", + " assert cumul <= hard_max_cumul\n", + "\n", + " if cumul > soft_max_cumul:\n", + " penalty = penalty * (cumul - soft_max_cumul)\n", + " sum_of_penalties += penalty\n", + " print(\n", + " f\"Task {t} of type {task_types[t]} with\"\n", + " f\" duration={durations[t]} starts at {start}, length={length},\"\n", + " f\" cumul={cumul} penalty={penalty}\"\n", + " )\n", + " else:\n", + " print(\n", + " f\"Task {t} of type {task_types[t]} with duration\"\n", + " f\" {durations[t]} starts at {start}, length =\"\n", + " f\" {length}, cumul = {cumul} \"\n", + " )\n", + "\n", + " assert int(solver.objective_value) == sum_of_penalties\n", + " else:\n", + " print(f\"Solver exited with the following status: {status}\")\n", + "\n", + "\n", + "sequences_in_no_overlap_sample_sat()\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/notebook/sat/simple_sat_program.ipynb b/examples/notebook/sat/simple_sat_program.ipynb index fcb5827ea9..fa1200b079 100644 --- a/examples/notebook/sat/simple_sat_program.ipynb +++ b/examples/notebook/sat/simple_sat_program.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -117,7 +117,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/solution_hinting_sample_sat.ipynb b/examples/notebook/sat/solution_hinting_sample_sat.ipynb index a3a5ff8b04..c9d7ae9feb 100644 --- a/examples/notebook/sat/solution_hinting_sample_sat.ipynb +++ b/examples/notebook/sat/solution_hinting_sample_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/solve_and_print_intermediate_solutions_sample_sat.ipynb b/examples/notebook/sat/solve_and_print_intermediate_solutions_sample_sat.ipynb index f3b5e59e2e..798488d570 100644 --- a/examples/notebook/sat/solve_and_print_intermediate_solutions_sample_sat.ipynb +++ b/examples/notebook/sat/solve_and_print_intermediate_solutions_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -138,7 +138,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/solve_with_time_limit_sample_sat.ipynb b/examples/notebook/sat/solve_with_time_limit_sample_sat.ipynb index 1bd9182de2..6fecc3a3ea 100644 --- a/examples/notebook/sat/solve_with_time_limit_sample_sat.ipynb +++ b/examples/notebook/sat/solve_with_time_limit_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -117,7 +117,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/step_function_sample_sat.ipynb b/examples/notebook/sat/step_function_sample_sat.ipynb index d0acd538ee..bde79c0c36 100644 --- a/examples/notebook/sat/step_function_sample_sat.ipynb +++ b/examples/notebook/sat/step_function_sample_sat.ipynb @@ -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 } diff --git a/examples/notebook/sat/stop_after_n_solutions_sample_sat.ipynb b/examples/notebook/sat/stop_after_n_solutions_sample_sat.ipynb index 091b49d23f..7ae994e2ab 100644 --- a/examples/notebook/sat/stop_after_n_solutions_sample_sat.ipynb +++ b/examples/notebook/sat/stop_after_n_solutions_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -136,7 +136,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 } diff --git a/examples/notebook/sat/transitions_in_no_overlap_sample_sat.ipynb b/examples/notebook/sat/transitions_in_no_overlap_sample_sat.ipynb index 77b4f68c4c..05f0a4ea3e 100644 --- a/examples/notebook/sat/transitions_in_no_overlap_sample_sat.ipynb +++ b/examples/notebook/sat/transitions_in_no_overlap_sample_sat.ipynb @@ -5,7 +5,7 @@ "id": "google", "metadata": {}, "source": [ - "##### Copyright 2024 Google LLC." + "##### Copyright 2025 Google LLC." ] }, { @@ -274,7 +274,11 @@ ] } ], - "metadata": {}, + "metadata": { + "language_info": { + "name": "python" + } + }, "nbformat": 4, "nbformat_minor": 5 }