Update notebooks

This commit is contained in:
Mizux Seiha
2021-04-01 18:05:08 +02:00
parent 8700429613
commit 823371161c
12 changed files with 944 additions and 143 deletions

View File

@@ -85,11 +85,30 @@
"\"\"\"Capacitated Vehicle Routing Problem (CVRP).\n",
"\n",
" This is a sample using the routing library python wrapper to solve a CVRP\n",
" problem.\n",
" A description of the problem can be found here:\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",
"\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",
"\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",
"\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",
"\n",
"\n",
@@ -109,9 +128,9 @@
" # Locations in block unit\n",
" _locations = [\n",
" (4, 4), # depot\n",
" (4, 4), # unload depot_prime\n",
" (4, 4), # unload depot_first\n",
" (4, 4), # unload depot_second\n",
" (4, 4), # unload depot_fourth\n",
" (4, 4), # unload depot_third\n",
" (4, 4), # unload depot_fourth\n",
" (4, 4), # unload depot_fifth\n",
" (2, 0),\n",
@@ -139,11 +158,11 @@
" data['num_locations'] = len(data['locations'])\n",
" data['demands'] = \\\n",
" [0, # depot\n",
" -_capacity,\n",
" -_capacity,\n",
" -_capacity,\n",
" -_capacity,\n",
" -_capacity,\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",
@@ -155,11 +174,11 @@
" data['time_per_demand_unit'] = 5 # 5 minutes/unit\n",
" data['time_windows'] = \\\n",
" [(0, 0), # depot\n",
" (0, 1000),\n",
" (0, 1000),\n",
" (0, 1000),\n",
" (0, 1000),\n",
" (0, 1000),\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",
@@ -253,14 +272,14 @@
" # so we have CumulVar = 10(current load) + -15(unload) + 5(slack) = 0.\n",
" capacity_dimension = routing.GetDimensionOrDie(capacity)\n",
" # Allow to drop reloading nodes with zero cost.\n",
" for node_index in [1, 2, 3, 4, 5]:\n",
" index = manager.NodeToIndex(node_index)\n",
" for node in [1, 2, 3, 4, 5]:\n",
" node_index = manager.NodeToIndex(node)\n",
" routing.AddDisjunction([node_index], 0)\n",
"\n",
" # Allow to drop regular node with a cost.\n",
" for node_index in range(6, len(data['demands'])):\n",
" index = manager.NodeToIndex(node_index)\n",
" capacity_dimension.SlackVar(index).SetValue(0)\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",
"\n",
"\n",

View File

@@ -67,10 +67,8 @@
"metadata": {},
"outputs": [],
"source": [
"#!/usr/bin/env python\n",
"# This Python file uses the following encoding: utf-8\n",
"# Copyright 2015 Tin Arm Engineering AB\n",
"# Copyright 2018 Google LLC\n",
"#!/usr/bin/env python3\n",
"# Copyright 2010-2021 Google LLC\n",
"# 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",
@@ -82,6 +80,7 @@
"# 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",
"# [START program]\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",
@@ -92,23 +91,21 @@
" Distances are in meters and time in minutes.\n",
"\"\"\"\n",
"\n",
"\n",
"from functools import partial\n",
"\n",
"from ortools.constraint_solver import pywrapcp\n",
"# [START import]\n",
"import functools\n",
"from ortools.constraint_solver import routing_enums_pb2\n",
"from ortools.constraint_solver import pywrapcp\n",
"# [END import]\n",
"\n",
"\n",
"###########################\n",
"# Problem Data Definition #\n",
"###########################\n",
"# [START data_model]\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem\"\"\"\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
" # Locations in block unit\n",
" _locations = \\\n",
" [(4, 4), # depot\n",
" (2, 0), (8, 0), # locations to visit\n",
" locations_ = \\\n",
" [(4, 4), # depot\n",
" (2, 0), (8, 0), # locations to visit\n",
" (0, 1), (1, 1),\n",
" (5, 2), (7, 2),\n",
" (3, 3), (6, 3),\n",
@@ -120,28 +117,28 @@
" # 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['locations'] = [(l[0] * 114, l[1] * 80) for l in locations_]\n",
" data['numlocations_'] = len(data['locations'])\n",
" data['time_windows'] = \\\n",
" [(0, 0),\n",
" (75, 85), (75, 85), # 1, 2\n",
" (60, 70), (45, 55), # 3, 4\n",
" (0, 8), (50, 60), # 5, 6\n",
" (0, 10), (10, 20), # 7, 8\n",
" (0, 10), (75, 85), # 9, 10\n",
" (85, 95), (5, 15), # 11, 12\n",
" (15, 25), (10, 20), # 13, 14\n",
" (45, 55), (30, 40)] # 15, 16\n",
" (75, 85), (75, 85), # 1, 2\n",
" (60, 70), (45, 55), # 3, 4\n",
" (0, 8), (50, 60), # 5, 6\n",
" (0, 10), (10, 20), # 7, 8\n",
" (0, 10), (75, 85), # 9, 10\n",
" (85, 95), (5, 15), # 11, 12\n",
" (15, 25), (10, 20), # 13, 14\n",
" (45, 55), (30, 40)] # 15, 16\n",
" data['demands'] = \\\n",
" [0, # depot\n",
" 1, 1, # 1, 2\n",
" 2, 4, # 3, 4\n",
" 2, 4, # 5, 6\n",
" 8, 8, # 7, 8\n",
" 1, 2, # 9,10\n",
" 1, 2, # 11,12\n",
" 4, 4, # 13, 14\n",
" 8, 8] # 15, 16\n",
" [0, # depot\n",
" 1, 1, # 1, 2\n",
" 2, 4, # 3, 4\n",
" 2, 4, # 5, 6\n",
" 8, 8, # 7, 8\n",
" 1, 2, # 9,10\n",
" 1, 2, # 11,12\n",
" 4, 4, # 13, 14\n",
" 8, 8] # 15, 16\n",
" data['time_per_demand_unit'] = 5 # 5 minutes/unit\n",
" data['num_vehicles'] = 4\n",
" data['breaks'] = [(2, False), (2, False), (2, False), (2, False)]\n",
@@ -149,33 +146,31 @@
" data['vehicle_speed'] = 83 # Travel speed: 5km/h converted in m/min\n",
" data['depot'] = 0\n",
" return data\n",
" # [END data_model]\n",
"\n",
"\n",
"#######################\n",
"# Problem Constraints #\n",
"#######################\n",
"def manhattan_distance(position_1, position_2):\n",
" \"\"\"Computes the Manhattan distance between two points\"\"\"\n",
" return (\n",
" abs(position_1[0] - position_2[0]) + abs(position_1[1] - position_2[1]))\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",
"\n",
"\n",
"def create_distance_evaluator(data):\n",
" \"\"\"Creates callback to return distance between points.\"\"\"\n",
" _distances = {}\n",
" distances_ = {}\n",
" # precompute distance between location to have distance callback in O(1)\n",
" for from_node in range(data['num_locations']):\n",
" _distances[from_node] = {}\n",
" for to_node in range(data['num_locations']):\n",
" for from_node in range(data['numlocations_']):\n",
" distances_[from_node] = {}\n",
" for to_node in range(data['numlocations_']):\n",
" if from_node == to_node:\n",
" _distances[from_node][to_node] = 0\n",
" distances_[from_node][to_node] = 0\n",
" else:\n",
" _distances[from_node][to_node] = (manhattan_distance(\n",
" distances_[from_node][to_node] = (manhattan_distance(\n",
" data['locations'][from_node], data['locations'][to_node]))\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",
" \"\"\"Returns the manhattan distance between the two nodes.\"\"\"\n",
" return distances_[manager.IndexToNode(from_node)][manager.IndexToNode(\n",
" to_node)]\n",
"\n",
" return distance_evaluator\n",
@@ -183,17 +178,17 @@
"\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, node):\n",
" \"\"\"Returns the demand of the current node\"\"\"\n",
" return _demands[manager.IndexToNode(node)]\n",
" \"\"\"Returns the demand of the current node.\"\"\"\n",
" return demands_[manager.IndexToNode(node)]\n",
"\n",
" return demand_evaluator\n",
"\n",
"\n",
"def add_capacity_constraints(routing, data, demand_evaluator_index):\n",
" \"\"\"Adds capacity constraint\"\"\"\n",
" \"\"\"Adds capacity constraint.\"\"\"\n",
" capacity = 'Capacity'\n",
" routing.AddDimension(\n",
" demand_evaluator_index,\n",
@@ -215,45 +210,46 @@
" if from_node == to_node:\n",
" travel_time = 0\n",
" else:\n",
" travel_time = manhattan_distance(data['locations'][from_node], data[\n",
" 'locations'][to_node]) / data['vehicle_speed']\n",
" travel_time = manhattan_distance(\n",
" data['locations'][from_node],\n",
" data['locations'][to_node]) / data['vehicle_speed']\n",
" return travel_time\n",
"\n",
" _total_time = {}\n",
" total_time_ = {}\n",
" # precompute total time to have time callback in O(1)\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 from_node in range(data['numlocations_']):\n",
" total_time_[from_node] = {}\n",
" for to_node in range(data['numlocations_']):\n",
" if from_node == to_node:\n",
" _total_time[from_node][to_node] = 0\n",
" total_time_[from_node][to_node] = 0\n",
" else:\n",
" _total_time[from_node][to_node] = int(\n",
" service_time(data, from_node) + travel_time(\n",
" data, from_node, to_node))\n",
" total_time_[from_node][to_node] = int(\n",
" service_time(data, from_node) +\n",
" travel_time(data, from_node, to_node))\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",
" \"\"\"Returns the total time between the two nodes.\"\"\"\n",
" return total_time_[manager.IndexToNode(from_node)][manager.IndexToNode(\n",
" to_node)]\n",
"\n",
" return time_evaluator\n",
"\n",
"\n",
"def add_time_window_constraints(routing, manager, data, time_evaluator_index):\n",
" \"\"\"Add Global Span constraint\"\"\"\n",
" \"\"\"Add Global Span constraint.\"\"\"\n",
" time = 'Time'\n",
" horizon = 120\n",
" routing.AddDimension(\n",
" time_evaluator_index,\n",
" horizon, # allow waiting time\n",
" horizon, # maximum time per vehicle\n",
" False, # don't force start cumul to zero since we are giving TW to start nodes\n",
" False, # don't force start cumul to zero\n",
" time)\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",
" if location_idx == 0:\n",
" if location_idx == data['depot']:\n",
" continue\n",
" index = manager.NodeToIndex(location_idx)\n",
" time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])\n",
@@ -265,15 +261,15 @@
" time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0],\n",
" data['time_windows'][0][1])\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",
" # The time window at the end node was impliclty set in the time dimension\n",
" # definition to be [0, horizon].\n",
" # Warning: Slack var is not defined for vehicle end nodes and should not\n",
" # be added to the assignment.\n",
"\n",
"\n",
"###########\n",
"# Printer #\n",
"###########\n",
"# [START solution_printer]\n",
"def print_solution(data, manager, routing, assignment): # pylint:disable=too-many-locals\n",
" \"\"\"Prints assignment on console\"\"\"\n",
" \"\"\"Prints assignment on console.\"\"\"\n",
" print('Objective: {}'.format(assignment.ObjectiveValue()))\n",
"\n",
" print('Breaks:')\n",
@@ -281,10 +277,9 @@
" for i in range(intervals.Size()):\n",
" brk = intervals.Element(i)\n",
" if brk.PerformedValue() == 1:\n",
" print('{}: Start({}) Duration({})'.format(\n",
" brk.Var().Name(),\n",
" brk.StartValue(),\n",
" brk.DurationValue()))\n",
" print('{}: Start({}) Duration({})'.format(brk.Var().Name(),\n",
" brk.StartValue(),\n",
" brk.DurationValue()))\n",
" else:\n",
" print('{}: Unperformed'.format(brk.Var().Name()))\n",
"\n",
@@ -302,10 +297,8 @@
" time_var = time_dimension.CumulVar(index)\n",
" slack_var = time_dimension.SlackVar(index)\n",
" plan_output += ' {0} Load({1}) Time({2},{3}) Slack({4},{5}) ->'.format(\n",
" manager.IndexToNode(index),\n",
" assignment.Value(load_var),\n",
" assignment.Min(time_var),\n",
" assignment.Max(time_var),\n",
" manager.IndexToNode(index), assignment.Value(load_var),\n",
" assignment.Min(time_var), assignment.Max(time_var),\n",
" assignment.Min(slack_var), assignment.Max(slack_var))\n",
" previous_index = index\n",
" index = assignment.Value(routing.NextVar(index))\n",
@@ -313,10 +306,8 @@
" vehicle_id)\n",
" load_var = capacity_dimension.CumulVar(index)\n",
" time_var = time_dimension.CumulVar(index)\n",
" slack_var = time_dimension.SlackVar(index)\n",
" plan_output += ' {0} Load({1}) Time({2},{3})\\n'.format(\n",
" manager.IndexToNode(index),\n",
" assignment.Value(load_var),\n",
" manager.IndexToNode(index), assignment.Value(load_var),\n",
" assignment.Min(time_var), assignment.Max(time_var))\n",
" plan_output += 'Distance of the route: {0}m\\n'.format(distance)\n",
" plan_output += 'Load of the route: {}\\n'.format(\n",
@@ -330,17 +321,17 @@
" print('Total Distance of all routes: {0}m'.format(total_distance))\n",
" print('Total Load of all routes: {}'.format(total_load))\n",
" print('Total Time of all routes: {0}min'.format(total_time))\n",
" # [END solution_printer]\n",
"\n",
"\n",
"########\n",
"# Main #\n",
"########\n",
"\"\"\"Entry point of the program\"\"\"\n",
"\"\"\"Entry point of the program.\"\"\"\n",
"# Instantiate the data problem.\n",
"# [START data]\n",
"data = create_data_model()\n",
"# [END data]\n",
"\n",
"# Create the routing index manager\n",
"manager = pywrapcp.RoutingIndexManager(data['num_locations'],\n",
"manager = pywrapcp.RoutingIndexManager(data['numlocations_'],\n",
" data['num_vehicles'], data['depot'])\n",
"\n",
"# Create Routing Model\n",
@@ -348,47 +339,57 @@
"\n",
"# Define weight of each edge\n",
"distance_evaluator_index = routing.RegisterTransitCallback(\n",
" partial(create_distance_evaluator(data), manager))\n",
" functools.partial(create_distance_evaluator(data), manager))\n",
"routing.SetArcCostEvaluatorOfAllVehicles(distance_evaluator_index)\n",
"\n",
"# Add Capacity constraint\n",
"demand_evaluator_index = routing.RegisterUnaryTransitCallback(\n",
" partial(create_demand_evaluator(data), manager))\n",
" functools.partial(create_demand_evaluator(data), manager))\n",
"add_capacity_constraints(routing, data, demand_evaluator_index)\n",
"\n",
"# Add Time Window constraint\n",
"time_evaluator_index = routing.RegisterTransitCallback(\n",
" partial(create_time_evaluator(data), manager))\n",
" functools.partial(create_time_evaluator(data), manager))\n",
"add_time_window_constraints(routing, manager, data, time_evaluator_index)\n",
"\n",
"# Add breaks\n",
"time_dimension = routing.GetDimensionOrDie(\"Time\")\n",
"time_dimension = routing.GetDimensionOrDie('Time')\n",
"node_visit_transit = {}\n",
"for n in range(routing.Size()):\n",
" if n >= data['num_locations']:\n",
" node_visit_transit[n] = 0\n",
" else:\n",
" node_visit_transit[n] = int(\n",
" data['demands'][n] * data['time_per_demand_unit'])\n",
"for index in range(routing.Size()):\n",
" node = manager.IndexToNode(index)\n",
" node_visit_transit[index] = int(data['demands'][node] *\n",
" data['time_per_demand_unit'])\n",
"\n",
"break_intervals = {}\n",
"#for v in range(data['num_vehicles']):\n",
"for v in [0]:\n",
"for v in range(data['num_vehicles']):\n",
" vehicle_break = data['breaks'][v]\n",
" break_intervals[v] = [\n",
" routing.solver().FixedDurationIntervalVar(\n",
" 15, 100, vehicle_break[0], vehicle_break[1], 'Break for vehicle {}'.format(v))\n",
" ]\n",
" time_dimension.SetBreakIntervalsOfVehicle(\n",
" break_intervals[v], v, node_visit_transit)\n",
" routing.solver().FixedDurationIntervalVar(15, 100, vehicle_break[0],\n",
" vehicle_break[1],\n",
" f'Break for vehicle {v}')\n",
" ]\n",
" time_dimension.SetBreakIntervalsOfVehicle(break_intervals[v], v,\n",
" node_visit_transit.values())\n",
"\n",
"# Setting first solution heuristic (cheapest addition).\n",
"# [START parameters]\n",
"search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n",
"search_parameters.first_solution_strategy = (\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member\n",
"# [END parameters]\n",
"\n",
"# Solve the problem.\n",
"# [START solve]\n",
"assignment = routing.SolveWithParameters(search_parameters)\n",
"print_solution(data, manager, routing, assignment)\n",
"# [END solve]\n",
"\n",
"# Print solution on console.\n",
"# [START print_solution]\n",
"if assignment:\n",
" print_solution(data, manager, routing, assignment)\n",
"else:\n",
" print('No solution found!')\n",
"# [END print_solution]\n",
"\n"
]
}

View File

@@ -0,0 +1,263 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Copyright 2020 Google LLC."
]
},
{
"cell_type": "markdown",
"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",
"metadata": {},
"source": [
"# vrp_breaks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<table align=\"left\">\n",
"<td>\n",
"<a href=\"https://colab.research.google.com/github/google/or-tools/blob/master/examples/notebook/constraint_solver/vrp_breaks.ipynb\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/colab_32px.png\"/>Run in Google Colab</a>\n",
"</td>\n",
"<td>\n",
"<a href=\"https://github.com/google/or-tools/blob/master/ortools/constraint_solver/samples/vrp_breaks.py\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/github_32px.png\"/>View source on GitHub</a>\n",
"</td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, you must install [ortools](https://pypi.org/project/ortools/) package in this colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install ortools"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#!/usr/bin/env python3\n",
"# Copyright 2010-2021 Google LLC\n",
"# 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",
"# [START program]\n",
"\"\"\"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",
"\n",
" Durations are in minutes.\n",
"\"\"\"\n",
"\n",
"# [START import]\n",
"from ortools.constraint_solver import routing_enums_pb2\n",
"from ortools.constraint_solver import pywrapcp\n",
"# [END import]\n",
"\n",
"\n",
"# [START data_model]\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",
" [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",
" [34, 15, 49, 0, 5, 32, 43, 25, 42, 44, 61, 25, 31, 41, 58, 28, 67],\n",
" [29, 9, 43, 5, 0, 26, 38, 19, 36, 38, 55, 20, 25, 35, 52, 33, 62],\n",
" [13, 25, 25, 32, 26, 0, 11, 15, 9, 12, 29, 38, 33, 31, 25, 52, 35],\n",
" [25, 36, 13, 43, 38, 11, 0, 26, 9, 23, 17, 50, 44, 42, 25, 63, 24],\n",
" [9, 17, 40, 25, 19, 15, 26, 0, 17, 19, 36, 23, 17, 16, 33, 37, 42],\n",
" [15, 34, 23, 42, 36, 9, 9, 17, 0, 13, 19, 40, 34, 33, 16, 54, 25],\n",
" [9, 37, 37, 44, 38, 12, 23, 19, 13, 0, 17, 26, 21, 19, 13, 40, 23],\n",
" [26, 54, 20, 61, 55, 29, 17, 36, 19, 17, 0, 43, 38, 36, 19, 57, 17],\n",
" [25, 29, 63, 25, 20, 38, 50, 23, 40, 26, 43, 0, 5, 15, 32, 13, 42],\n",
" [19, 24, 58, 31, 25, 33, 44, 17, 34, 21, 38, 5, 0, 9, 26, 19, 36],\n",
" [17, 33, 56, 41, 35, 31, 42, 16, 33, 19, 36, 15, 9, 0, 17, 21, 26],\n",
" [23, 50, 39, 58, 52, 25, 25, 33, 16, 13, 19, 32, 26, 17, 0, 38, 9],\n",
" [38, 43, 77, 28, 33, 52, 63, 37, 54, 40, 57, 13, 19, 21, 38, 0, 39],\n",
" [33, 60, 37, 67, 62, 35, 24, 42, 25, 23, 17, 42, 36, 26, 9, 39, 0],\n",
" ]\n",
" data['service_time'] = [15] * len(data['time_matrix']) # 15 min of service time\n",
" data['service_time'][data['depot']] = 0\n",
" assert(len(data['time_matrix']) == len(data['service_time']))\n",
" return data\n",
" # [END data_model]\n",
"\n",
"\n",
"# [START solution_printer]\n",
"def print_solution(manager, routing, solution):\n",
" \"\"\"Prints solution on console.\"\"\"\n",
" print('Objective: {}'.format(solution.ObjectiveValue()))\n",
"\n",
" print('Breaks:')\n",
" intervals = solution.IntervalVarContainer()\n",
" for i in range(intervals.Size()):\n",
" brk = intervals.Element(i)\n",
" if brk.PerformedValue() == True:\n",
" print(f'{brk.Var().Name()}: Start({brk.StartValue()}) Duration({brk.DurationValue()})')\n",
" else:\n",
" print(f'{brk.Var().Name()}: Unperformed')\n",
"\n",
" time_dimension = routing.GetDimensionOrDie('Time')\n",
" total_time = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\n",
" index = routing.Start(vehicle_id)\n",
" plan_output = f'Route for vehicle {vehicle_id}:\\n'\n",
" while not routing.IsEnd(index):\n",
" time_var = time_dimension.CumulVar(index)\n",
" plan_output += f'{manager.IndexToNode(index)} 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)} Time({solution.Value(time_var)})\\n'\n",
" plan_output += f'Time of the route: {solution.Value(time_var)}min\\n'\n",
" print(plan_output)\n",
" total_time += solution.Value(time_var)\n",
" print(f'Total time of all routes: {total_time}min')\n",
" # [END solution_printer]\n",
"\n",
"\n",
"\"\"\"Solve the VRP with time windows.\"\"\"\n",
"# Instantiate the data problem.\n",
"# [START data]\n",
"data = create_data_model()\n",
"# [END data]\n",
"\n",
"# Create the routing index manager.\n",
"# [START index_manager]\n",
"manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), data['num_vehicles'], data['depot'])\n",
"# [END index_manager]\n",
"\n",
"# Create Routing Model.\n",
"# [START routing_model]\n",
"routing = pywrapcp.RoutingModel(manager)\n",
"# [END routing_model]\n",
"\n",
"# Create and register a transit callback.\n",
"# [START transit_callback]\n",
"def time_callback(from_index, to_index):\n",
" \"\"\"Returns the travel time + service 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] + data['service_time'][from_node]\n",
"\n",
"transit_callback_index = routing.RegisterTransitCallback(time_callback)\n",
"# [END transit_callback]\n",
"\n",
"# Define cost of each arc.\n",
"# [START arc_cost]\n",
"routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)\n",
"# [END arc_cost]\n",
"\n",
"# Add Time Windows constraint.\n",
"time = 'Time'\n",
"routing.AddDimension(\n",
" transit_callback_index,\n",
" 10, # needed optional waiting time to place break\n",
" 180, # maximum time per vehicle\n",
" True, # Force start cumul to zero.\n",
" time)\n",
"time_dimension = routing.GetDimensionOrDie(time)\n",
"time_dimension.SetGlobalSpanCostCoefficient(10)\n",
"\n",
"# Breaks\n",
"# [START break_constraint]\n",
"# warning: Need a pre-travel array using the solver's index order.\n",
"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",
"\n",
"break_intervals = {}\n",
"for v in range(data['num_vehicles']):\n",
" break_intervals[v] = [\n",
" routing.solver().FixedDurationIntervalVar(\n",
" 50, # start min\n",
" 60, # start max\n",
" 10, # duration: 10 min\n",
" False, # optional: no\n",
" f'Break for vehicle {v}')\n",
" ]\n",
" time_dimension.SetBreakIntervalsOfVehicle(\n",
" break_intervals[v], # breaks\n",
" v, # vehicle index\n",
" node_visit_transit)\n",
"# [END break_constraint]\n",
"\n",
"\n",
"# Setting first solution heuristic.\n",
"# [START parameters]\n",
"search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n",
"search_parameters.first_solution_strategy = (\n",
" routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)\n",
"search_parameters.local_search_metaheuristic = (\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n",
"#search_parameters.log_search = True\n",
"search_parameters.time_limit.FromSeconds(2)\n",
"# [END parameters]\n",
"\n",
"# Solve the problem.\n",
"# [START solve]\n",
"solution = routing.SolveWithParameters(search_parameters)\n",
"# [END solve]\n",
"\n",
"# Print solution on console.\n",
"# [START print_solution]\n",
"if solution:\n",
" print_solution(manager, routing, solution)\n",
"else:\n",
" print('No solution found !')\n",
"# [END print_solution]\n",
"\n"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -67,6 +67,7 @@
"metadata": {},
"outputs": [],
"source": [
"#!/usr/bin/env python3\n",
"# Copyright 2010-2018 Google LLC\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",

View File

@@ -67,6 +67,7 @@
"metadata": {},
"outputs": [],
"source": [
"#!/usr/bin/env python3\n",
"# Copyright 2010-2018 Google LLC\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
@@ -209,15 +210,17 @@
"time_dimension = routing.GetDimensionOrDie(time)\n",
"# Add time window constraints for each location except depot.\n",
"for location_idx, time_window in enumerate(data['time_windows']):\n",
" if location_idx == 0:\n",
" if location_idx == data['depot']:\n",
" continue\n",
" index = manager.NodeToIndex(location_idx)\n",
" time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])\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",
" 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'][depot_idx][0],\n",
" data['time_windows'][depot_idx][1])\n",
"# [END time_windows_constraint]\n",
"\n",
"# Instantiate route start and end times to produce feasible times.\n",

View File

@@ -0,0 +1,232 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Copyright 2020 Google LLC."
]
},
{
"cell_type": "markdown",
"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",
"metadata": {},
"source": [
"# vrp_tokens"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<table align=\"left\">\n",
"<td>\n",
"<a href=\"https://colab.research.google.com/github/google/or-tools/blob/master/examples/notebook/constraint_solver/vrp_tokens.ipynb\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/colab_32px.png\"/>Run in Google Colab</a>\n",
"</td>\n",
"<td>\n",
"<a href=\"https://github.com/google/or-tools/blob/master/ortools/constraint_solver/samples/vrp_tokens.py\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/github_32px.png\"/>View source on GitHub</a>\n",
"</td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, you must install [ortools](https://pypi.org/project/ortools/) package in this colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install ortools"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#!/usr/bin/env python3\n",
"# Copyright 2020 Google LLC\n",
"# 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",
"\"\"\"\n",
"Simple VRP with special locations which need to be visited at end of the route.\n",
"\"\"\"\n",
"\n",
"from ortools.constraint_solver import routing_enums_pb2\n",
"from ortools.constraint_solver import pywrapcp\n",
"\n",
"def create_data_model():\n",
" \"\"\"Stores the data for the problem.\"\"\"\n",
" data = {}\n",
" # Special location don't consume token, while regular one consume one\n",
" data['tokens'] = [\n",
" 0, # 0 depot\n",
" 0, # 1 special node\n",
" 0, # 2 special node\n",
" 0, # 3 special node\n",
" 0, # 4 special node\n",
" 0, # 5 special node\n",
" -1, # 6\n",
" -1, # 7\n",
" -1, # 8\n",
" -1, # 9\n",
" -1, # 10\n",
" -1, # 11\n",
" -1, # 12\n",
" -1, # 13\n",
" -1, # 14\n",
" -1, # 15\n",
" -1, # 16\n",
" -1, # 17\n",
" -1, # 18\n",
" ]\n",
" # just need to be big enough, not a limiting factor\n",
" data['vehicle_tokens'] = [20, 20, 20, 20]\n",
" data['num_vehicles'] = 4\n",
" data['depot'] = 0\n",
" return data\n",
"\n",
"\n",
"def print_solution(manager, routing, solution):\n",
" \"\"\"Prints solution on console.\"\"\"\n",
" token_dimension = routing.GetDimensionOrDie('Token')\n",
" total_distance = 0\n",
" total_token = 0\n",
" for vehicle_id in range(manager.GetNumberOfVehicles()):\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",
" route_distance = 0\n",
" route_token = 0\n",
" while not routing.IsEnd(index):\n",
" node_index = manager.IndexToNode(index)\n",
" token_var = token_dimension.CumulVar(index)\n",
" route_token = solution.Value(token_var)\n",
" plan_output += f' {node_index} Token({route_token}) -> '\n",
" previous_index = index\n",
" index = solution.Value(routing.NextVar(index))\n",
" route_distance += routing.GetArcCostForVehicle(\n",
" previous_index, index, vehicle_id)\n",
" node_index = manager.IndexToNode(index)\n",
" token_var = token_dimension.CumulVar(index)\n",
" route_token = solution.Value(token_var)\n",
" plan_output += f' {node_index} Token({route_token})\\n'\n",
" plan_output += f'Distance of the route: {route_distance}m\\n'\n",
" total_distance += route_distance\n",
" print(plan_output)\n",
" print('Total distance of all routes: {}m'.format(total_distance))\n",
" print('Total token of all routes: {}'.format(total_token))\n",
"\n",
"\n",
"\"\"\"Solve the CVRP problem.\"\"\"\n",
"# Instantiate the data problem.\n",
"data = create_data_model()\n",
"\n",
"# Create the routing index manager.\n",
"manager = pywrapcp.RoutingIndexManager(\n",
" len(data['tokens']),\n",
" data['num_vehicles'],\n",
" data['depot'])\n",
"\n",
"# Create Routing Model.\n",
"routing = pywrapcp.RoutingModel(manager)\n",
"\n",
"# Create and register a transit callback.\n",
"def distance_callback(from_index, to_index):\n",
" \"\"\"Returns the distance between the two nodes.\"\"\"\n",
" # 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 10\n",
"\n",
"transit_callback_index = routing.RegisterTransitCallback(distance_callback)\n",
"\n",
"routing.AddDimension(\n",
" transit_callback_index,\n",
" 0, # null slack\n",
" 3000, # maximum distance per vehicle\n",
" True, # start cumul to zero\n",
" \"distance\")\n",
"distance_dimension = routing.GetDimensionOrDie(\"distance\")\n",
"distance_dimension.SetGlobalSpanCostCoefficient(100)\n",
"\n",
"# Define cost of each arc.\n",
"routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)\n",
"\n",
"# Add Token constraint.\n",
"def token_callback(from_index):\n",
" \"\"\"Returns the number of token consumed by the node.\"\"\"\n",
" # Convert from routing variable Index to tokens NodeIndex.\n",
" from_node = manager.IndexToNode(from_index)\n",
" return data['tokens'][from_node]\n",
"\n",
"token_callback_index = routing.RegisterUnaryTransitCallback(token_callback)\n",
"routing.AddDimensionWithVehicleCapacity(\n",
" token_callback_index,\n",
" 0, # null capacity slack\n",
" data['vehicle_tokens'], # vehicle maximum tokens\n",
" False, # start cumul to zero\n",
" 'Token')\n",
"# Add constraint: special node can only be visited if token remaining is zero\n",
"token_dimension = routing.GetDimensionOrDie('Token')\n",
"for node in range(1, 6):\n",
" index = manager.NodeToIndex(node)\n",
" routing.solver().Add(token_dimension.CumulVar(index) == 0)\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",
"search_parameters.local_search_metaheuristic = (\n",
" routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n",
"search_parameters.time_limit.FromSeconds(1)\n",
"\n",
"# Solve the problem.\n",
"solution = routing.SolveWithParameters(search_parameters)\n",
"\n",
"# Print solution on console.\n",
"if solution:\n",
" print_solution(manager, routing, solution)\n",
"else:\n",
" print(\"No solution found !\")\n",
"\n"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -87,6 +87,7 @@
"from ortools.constraint_solver import pywrapcp\n",
"# [END import]\n",
"\n",
"\n",
"# [START solution_printer]\n",
"def print_solution(manager, routing, solution):\n",
" \"\"\"Prints solution on console.\"\"\"\n",
@@ -106,21 +107,20 @@
" print(plan_output)\n",
" max_route_distance = max(route_distance, max_route_distance)\n",
" print('Maximum of the route distances: {}m'.format(max_route_distance))\n",
"# [END solution_printer]\n",
" # [END solution_printer]\n",
"\n",
"\n",
"\"\"\"Solve the CVRP problem.\"\"\"\n",
"# Instantiate the data problem.\n",
"# [START data]\n",
"num_locations = 20;\n",
"num_vehicles = 5;\n",
"depot = 0;\n",
"num_locations = 20\n",
"num_vehicles = 5\n",
"depot = 0\n",
"# [END data]\n",
"\n",
"# Create the routing index manager.\n",
"# [START index_manager]\n",
"manager = pywrapcp.RoutingIndexManager(\n",
" num_locations, num_vehicles, depot)\n",
"manager = pywrapcp.RoutingIndexManager(num_locations, num_vehicles, depot)\n",
"# [END index_manager]\n",
"\n",
"# Create Routing Model.\n",
@@ -132,10 +132,8 @@
"# Create and register a transit callback.\n",
"# [START transit_callback]\n",
"def distance_callback(from_index, to_index):\n",
" # pylint: disable=unused-argument\n",
" \"\"\"Returns the distance between the two nodes.\"\"\"\n",
" # 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 1\n",
"\n",
"transit_callback_index = routing.RegisterTransitCallback(distance_callback)\n",

View File

@@ -82,6 +82,7 @@
"\"\"\"Integer programming examples that show how to use the APIs.\"\"\"\n",
"\n",
"from ortools.linear_solver import pywraplp\n",
"from ortools.init import pywrapinit\n",
"\n",
"\n",
"def Announce(solver, api_type):\n",
@@ -167,6 +168,7 @@
" RunIntegerExampleNaturalLanguageAPI('CBC')\n",
" RunIntegerExampleNaturalLanguageAPI('SCIP')\n",
" RunIntegerExampleNaturalLanguageAPI('SAT')\n",
" RunIntegerExampleNaturalLanguageAPI('Gurobi')\n",
"\n",
"\n",
"def RunAllIntegerExampleCppStyleAPI():\n",
@@ -174,6 +176,7 @@
" RunIntegerExampleCppStyleAPI('CBC')\n",
" RunIntegerExampleCppStyleAPI('SCIP')\n",
" RunIntegerExampleCppStyleAPI('SAT')\n",
" RunIntegerExampleCppStyleAPI('Gurobi')\n",
"\n",
"\n",
"RunAllIntegerExampleNaturalLanguageAPI()\n",

View File

@@ -189,7 +189,7 @@
" cost_coefficients.append(max_cost * (length - soft_max))\n",
"\n",
" # Just forbid any sequence of true variables with length hard_max + 1\n",
" for start in range(len(works) - hard_max - 1):\n",
" for start in range(len(works) - hard_max):\n",
" model.AddBoolOr(\n",
" [works[i].Not() for i in range(start, start + hard_max + 1)])\n",
" return cost_literals, cost_coefficients\n",

View File

@@ -110,7 +110,7 @@
"for i in range(num_workers):\n",
" t = []\n",
" for j in range(num_tasks):\n",
" t.append(model.NewBoolVar('x[%i,%i]' % (i, j)))\n",
" t.append(model.NewBoolVar(f'x[{i},{j}]'))\n",
" x.append(t)\n",
"# [END variables]\n",
"\n",
@@ -143,13 +143,13 @@
"# Print solution.\n",
"# [START print_solution]\n",
"if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:\n",
" print('Total cost = %i' % solver.ObjectiveValue())\n",
" print(f'Total cost = {solver.ObjectiveValue()}')\n",
" print()\n",
" for i in range(num_workers):\n",
" for j in range(num_tasks):\n",
" if solver.BooleanValue(x[i][j]):\n",
" print('Worker ', i, ' assigned to task ', j, ' Cost = ',\n",
" costs[i][j])\n",
" print(\n",
" f'Worker {i} assigned to task {j} Cost = {costs[i][j]}')\n",
"else:\n",
" print('No solution found.')\n",
"# [END print_solution]\n",

View File

@@ -0,0 +1,135 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Copyright 2020 Google LLC."
]
},
{
"cell_type": "markdown",
"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",
"metadata": {},
"source": [
"# assumptions_sample_sat"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<table align=\"left\">\n",
"<td>\n",
"<a href=\"https://colab.research.google.com/github/google/or-tools/blob/master/examples/notebook/sat/assumptions_sample_sat.ipynb\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/colab_32px.png\"/>Run in Google Colab</a>\n",
"</td>\n",
"<td>\n",
"<a href=\"https://github.com/google/or-tools/blob/master/ortools/sat/samples/assumptions_sample_sat.py\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/github_32px.png\"/>View source on GitHub</a>\n",
"</td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, you must install [ortools](https://pypi.org/project/ortools/) package in this colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install ortools"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Copyright 2021 Xiang Chen\n",
"# 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",
"\"\"\"Code sample that solves a model and gets the infeasibility assumptions.\"\"\"\n",
"# [START program]\n",
"# [START import]\n",
"from ortools.sat.python import cp_model\n",
"# [END import]\n",
"\n",
"\n",
"\"\"\"Showcases assumptions.\"\"\"\n",
"# Creates the model.\n",
"# [START model]\n",
"model = cp_model.CpModel()\n",
"# [END model]\n",
"\n",
"# Creates the variables.\n",
"# [START variables]\n",
"x = model.NewIntVar(0, 10, 'x')\n",
"y = model.NewIntVar(0, 10, 'y')\n",
"z = model.NewIntVar(0, 10, 'z')\n",
"a = model.NewBoolVar('a')\n",
"b = model.NewBoolVar('b')\n",
"c = model.NewBoolVar('c')\n",
"# [END variables]\n",
"\n",
"# Creates the constraints.\n",
"# [START constraints]\n",
"model.Add(x > y).OnlyEnforceIf(a)\n",
"model.Add(y > z).OnlyEnforceIf(b)\n",
"model.Add(z > x).OnlyEnforceIf(c)\n",
"# [END constraints]\n",
"\n",
"# Add assumptions\n",
"model.AddAssumptions([a, b, c])\n",
"\n",
"# Creates a solver and solves.\n",
"# [START solve]\n",
"solver = cp_model.CpSolver()\n",
"status = solver.Solve(model)\n",
"# [END solve]\n",
"\n",
"# Print solution.\n",
"# [START print_solution]\n",
"print(f'Status = {solver.StatusName(status)}')\n",
"if status == cp_model.INFEASIBLE:\n",
" print('SufficientAssumptionsForInfeasibility = '\n",
" f'{solver.SufficientAssumptionsForInfeasibility()}')\n",
"# [END print_solution]\n",
"\n"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -0,0 +1,146 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Copyright 2020 Google LLC."
]
},
{
"cell_type": "markdown",
"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",
"metadata": {},
"source": [
"# copy_model_sample_sat"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<table align=\"left\">\n",
"<td>\n",
"<a href=\"https://colab.research.google.com/github/google/or-tools/blob/master/examples/notebook/sat/copy_model_sample_sat.ipynb\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/colab_32px.png\"/>Run in Google Colab</a>\n",
"</td>\n",
"<td>\n",
"<a href=\"https://github.com/google/or-tools/blob/master/ortools/sat/samples/copy_model_sample_sat.py\"><img src=\"https://raw.githubusercontent.com/google/or-tools/master/tools/github_32px.png\"/>View source on GitHub</a>\n",
"</td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, you must install [ortools](https://pypi.org/project/ortools/) package in this colab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!pip install ortools"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Copyright 2010-2018 Google LLC\n",
"# 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",
"\"\"\"Showcases deep copying of a model.\"\"\"\n",
"\n",
"# [START program]\n",
"from ortools.sat.python import cp_model\n",
"\n",
"\n",
"def CopyModelSat():\n",
" \"\"\"Showcases printing intermediate solutions found during search.\"\"\"\n",
" # Creates the model.\n",
" # [START model]\n",
" model = cp_model.CpModel()\n",
" # [END model]\n",
"\n",
" # Creates the variables.\n",
" # [START variables]\n",
" num_vals = 3\n",
" x = model.NewIntVar(0, num_vals - 1, 'x')\n",
" y = model.NewIntVar(0, num_vals - 1, 'y')\n",
" z = model.NewIntVar(0, num_vals - 1, 'z')\n",
" # [END variables]\n",
"\n",
" # Creates the constraints.\n",
" # [START constraints]\n",
" model.Add(x != y)\n",
" # [END constraints]\n",
"\n",
" # [START objective]\n",
" model.Maximize(x + 2 * y + 3 * z)\n",
" # [END objective]\n",
"\n",
" # Creates a solver and solves.\n",
" # [START solve]\n",
" solver = cp_model.CpSolver()\n",
" status = solver.Solve(model)\n",
" # [END solve]\n",
"\n",
" if status == cp_model.OPTIMAL:\n",
" print('Optimal value of the original model: {}'.format(\n",
" solver.ObjectiveValue()))\n",
"\n",
" # Copy the model.\n",
" copy = cp_model.CpModel()\n",
" copy.CopyFrom(model)\n",
"\n",
" copy_x = copy.GetIntVarFromProtoIndex(x.Index())\n",
" copy_y = copy.GetIntVarFromProtoIndex(y.Index())\n",
"\n",
" copy.Add(copy_x + copy_y <= 1)\n",
" status = solver.Solve(copy)\n",
"\n",
" if status == cp_model.OPTIMAL:\n",
" print('Optimal value of the modified model: {}'.format(\n",
" solver.ObjectiveValue()))\n",
"\n",
"\n",
"CopyModelSat()\n",
"# [END program]\n",
"\n"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}