diff --git a/ortools/constraint_solver/README.md b/ortools/constraint_solver/README.md
index dd81854575..c1d157ec4f 100644
--- a/ortools/constraint_solver/README.md
+++ b/ortools/constraint_solver/README.md
@@ -1,28 +1,33 @@
# Constraint Programming (CP) and Routing Solver
-This directory contains a Constraint Programming (CP) solver and a Vehicle Routing solver.
+This directory contains a Constraint Programming (CP) solver and a Vehicle
+Routing solver.
## CP solver
-[Constraint Programming](http://en.wikipedia.org/wiki/Constraint_programming) is a technology
-issued from IA and used in Operations Research.
+[Constraint Programming](http://en.wikipedia.org/wiki/Constraint_programming) is
+a technology issued from IA and used in Operations Research.
To begin, skim
-* [constraint_solver.h](constraint_solver.h):
-The point of entry for all constraint programming users.
-* [constraint_solveri.h](constraint_solveri.h):
-An additional file that helps extending the constraint programming library.
+
+* [constraint_solver.h](../constraint_solver/constraint_solver.h):
+Declaration of the core objects for the constraint solver.
+* [constraint_solveri.h](../constraint_solver/constraint_solveri.h):
+Collection of objects used to extend the Constraint Solver library.
### Parameters
-* [solver_parameters.proto](solver_parameters.proto):
-The CP solver parameters.
-* [search_limit.proto](search_limit.proto):
-Holds parameters to limit the search space within the CP solver, which is important for performance.
+
+* [solver_parameters.proto](../constraint_solver/solver_parameters.proto):
+This file contains protocol buffers for all parameters of the CP solver.
+* [search_limit.proto](../constraint_solver/search_limit.proto):
+Holds parameters to limit the search space within the CP solver, which is
+important for performance.
### Solution
-* [assignment.proto](assignment.proto):
+
+* [assignment.proto](../constraint_solver/assignment.proto):
Holds the solution of a CP problem.
-* [demon_profiler.proto](demon_profiler.proto):
+* [demon_profiler.proto](../constraint_solver/demon_profiler.proto):
Holds the timeline and execution profile of constraints and demons (daemons).
## Routing solver
@@ -31,18 +36,26 @@ Holds the timeline and execution profile of constraints and demons (daemons).
extension that is implemented on top of the CP solver library.
To begin, skim
-* [routing.h](routing.h):
-The point of entry for routing problems.
+
+* [routing.h](../constraint_solver/routing.h):
+The vehicle routing library lets one model and solve generic vehicle routing
+problems ranging from the Traveling Salesman Problem to more complex problems
+such as the Capacitated Vehicle Routing Problem with Time Windows.
+* [routing_flags.h](../constraint_solver/routing_flags.h)
### Parameters
-* [routing_parameters.proto](routing_parameters.proto):
+
+* [routing_parameters.proto](../constraint_solver/routing_parameters.proto):
The Vehicle Routing solver parameters.
+* [routing_enums.proto](../constraint_solver/routing_enums.proto):
+Enums used to define routing parameters.
### Solution
+
* [assignment.proto](assignment.proto):
Holds the solution of a Routing problem.
-### Recipes
+## Recipes
You can find a set of code recipes in
-[the documentation directory](doc/routing.md).
+[the documentation directory](doc/README.md).
diff --git a/ortools/constraint_solver/doc/CP.md b/ortools/constraint_solver/doc/CP.md
new file mode 100644
index 0000000000..93ea001f11
--- /dev/null
+++ b/ortools/constraint_solver/doc/CP.md
@@ -0,0 +1,163 @@
+# Using the CP solver
+
+
+## Documentation structure
+
+OR-Tools comes with lots of constraint programming samples given in C++, Python,
+Java and .Net. Each language have different requirements for the code samples.
+
+## Basic example
+
+### C++ code samples
+
+```cpp
+#include "ortools/constraint_solver/constraint_solver.h"
+
+namespace operations_research {
+
+void SimpleCpProgram() {
+ // Instantiate the solver.
+ Solver solver("CpSimple");
+
+ // Create the variables.
+ const int64 num_vals = 3;
+ IntVar* const x = solver.MakeIntVar(0, num_vals - 1, "x");
+ IntVar* const y = solver.MakeIntVar(0, num_vals - 1, "y");
+ IntVar* const z = solver.MakeIntVar(0, num_vals - 1, "z");
+
+ // Constraint 0: x != y..
+ solver.AddConstraint(solver.MakeAllDifferent({x, y}));
+ LOG(INFO) << "Number of constraints: "
+ << std::to_string(solver.constraints());
+
+ // Solve the problem.
+ DecisionBuilder* const db = solver.MakePhase(
+ {x, y, z}, Solver::CHOOSE_FIRST_UNBOUND, Solver::ASSIGN_MIN_VALUE);
+
+ // Print solution on console.
+ int count = 0;
+ solver.NewSearch(db);
+ while (solver.NextSolution()) {
+ ++count;
+ LOG(INFO) << "Solution " << count << ":" << std::endl
+ << " x=" << x->Value() << " y=" << y->Value()
+ << " z=" << z->Value();
+ }
+ solver.EndSearch();
+ LOG(INFO) << "Number of solutions found: " << solver.solutions();
+
+ LOG(INFO) << "Advanced usage:" << std::endl
+ << "Problem solved in " << std::to_string(solver.wall_time())
+ << "ms" << std::endl
+ << "Memory usage: " << std::to_string(Solver::MemoryUsage())
+ << "bytes";
+}
+
+} // namespace operations_research
+
+int main(int argc, char** argv) {
+ operations_research::SimpleCpProgram();
+ return EXIT_SUCCESS;
+}
+```
+
+### Python code samples
+
+```python
+"""Simple Constraint optimization example."""
+
+from __future__ import print_function
+from ortools.constraint_solver import pywrapcp
+
+
+def main():
+ """Entry point of the program."""
+ # Instantiate the solver.
+ solver = pywrapcp.Solver('CPSimple')
+
+ # Create the variables.
+ num_vals = 3
+ x = solver.IntVar(0, num_vals - 1, 'x')
+ y = solver.IntVar(0, num_vals - 1, 'y')
+ z = solver.IntVar(0, num_vals - 1, 'z')
+
+ # Constraint 0: x != y.
+ solver.Add(x != y)
+ print('Number of constraints: ', solver.Constraints())
+
+ # Solve the problem.
+ decision_builder = solver.Phase([x, y, z], solver.CHOOSE_FIRST_UNBOUND,
+ solver.ASSIGN_MIN_VALUE)
+
+ # Print solution on console.
+ count = 0
+ solver.NewSearch(decision_builder)
+ while solver.NextSolution():
+ count += 1
+ solution = 'Solution {}:\n'.format(count)
+ for var in [x, y, z]:
+ solution += ' {} = {}'.format(var.Name(), var.Value())
+ print(solution)
+ solver.EndSearch()
+ print('Number of solutions found: ', count)
+
+ print('Advanced usage:')
+ print('Problem solved in ', solver.WallTime(), 'ms')
+ print('Memory usage: ', pywrapcp.Solver.MemoryUsage(), 'bytes')
+
+if __name__ == '__main__':
+ main()
+```
+
+### Java code samples
+
+```java
+```
+
+### .Net code samples
+
+
+```cs
+using System;
+using Google.OrTools.ConstraintSolver;
+
+///
+/// This is a simple CP program.
+///
+public class SimpleCpProgram {
+ public static void Main(String[] args) {
+ // Instantiate the solver.
+ Solver solver = new Solver("CpSimple");
+
+ // Create the variables.
+ const long numVals = 3;
+ IntVar x = solver.MakeIntVar(0, numVals - 1, "x");
+ IntVar y = solver.MakeIntVar(0, numVals - 1, "y");
+ IntVar z = solver.MakeIntVar(0, numVals - 1, "z");
+
+ // Constraint 0: x != y..
+ solver.Add(solver.MakeAllDifferent(new IntVar[]{x, y}));
+ Console.WriteLine($"Number of constraints: {solver.Constraints()}");
+
+ // Solve the problem.
+ DecisionBuilder db = solver.MakePhase(
+ new IntVar[]{x, y, z},
+ Solver.CHOOSE_FIRST_UNBOUND,
+ Solver.ASSIGN_MIN_VALUE);
+
+ // Print solution on console.
+ int count = 0;
+ solver.NewSearch(db);
+ while (solver.NextSolution()) {
+ ++count;
+ Console.WriteLine($"Solution: {count}\n x={x.Value()} y={y.Value()} z={z.Value()}");
+ }
+ solver.EndSearch();
+ Console.WriteLine($"Number of solutions found: {solver.Solutions()}");
+
+ Console.WriteLine("Advanced usage:");
+ Console.WriteLine($"Problem solved in {solver.WallTime()}ms");
+ Console.WriteLine($"Memory usage: {Solver.MemoryUsage()}bytes");
+ }
+}
+```
diff --git a/ortools/constraint_solver/doc/pdp.md b/ortools/constraint_solver/doc/PDP.md
similarity index 99%
rename from ortools/constraint_solver/doc/pdp.md
rename to ortools/constraint_solver/doc/PDP.md
index 289fd84d25..e4eb418511 100644
--- a/ortools/constraint_solver/doc/pdp.md
+++ b/ortools/constraint_solver/doc/PDP.md
@@ -12,6 +12,7 @@ Solution with the default Policy (ANY):

Samples:
+
* [vrp_pickup_delivery.cc](../samples/vrp_pickup_delivery.cc)
* [vrp_pickup_delivery.py](../samples/vrp_pickup_delivery.py)
* [VrpPickupDelivery.java](../samples/VrpPickupDelivery.java)
@@ -22,6 +23,7 @@ Solution with the FIFO Policy:

Samples:
+
* [vrp_pickup_delivery_fifo.cc](../samples/vrp_pickup_delivery_fifo.cc)
* [vrp_pickup_delivery_fifo.py](../samples/vrp_pickup_delivery_fifo.py)
* [VrpPickupDeliveryFifo.java](../samples/VrpPickupDeliveryFifo.java)
@@ -32,6 +34,7 @@ Solution with the LIFO Policy:

Samples:
+
* [vrp_pickup_delivery_lifo.cc](../samples/vrp_pickup_delivery_lifo.cc)
* [vrp_pickup_delivery_lifo.py](../samples/vrp_pickup_delivery_lifo.py)
* [VrpPickupDeliveryLifo.java](../samples/VrpPickupDeliveryLifo.java)
diff --git a/ortools/constraint_solver/doc/README.md b/ortools/constraint_solver/doc/README.md
new file mode 100644
index 0000000000..c7f136dd2a
--- /dev/null
+++ b/ortools/constraint_solver/doc/README.md
@@ -0,0 +1,18 @@
+# Overview
+
+You can find here, the documentation for the two following Or-Tools components.
+
+* [CP Solver](CP.md)
+
+ Constraint programming (CP), is the name given to identifying feasible
+ solutions out of a very large set of candidates, where the problem can be
+ modeled in terms of arbitrary constraints.
+
+ **note:** We **strongly recommend** using the [CP-SAT solver](../../sat)
+ rather than the original CP solver.
+
+* [Routing Solver](ROUTING.md)
+
+ A specialized library for identifying best vehicle routes given constraints.
+
+ This library extensiond is implemented on top of the CP Solver library.
diff --git a/ortools/constraint_solver/doc/ROUTING.md b/ortools/constraint_solver/doc/ROUTING.md
new file mode 100644
index 0000000000..1b598042e3
--- /dev/null
+++ b/ortools/constraint_solver/doc/ROUTING.md
@@ -0,0 +1,223 @@
+# Using the Vehicle Routing solver
+
+
+## Documentation structure
+
+This document presents modeling recipes for the Vehicle routing solver.
+These are grouped by type:
+
+* [Travelling Salesman Problem](TSP.md)
+* [Vehicle Routing Problem](VRP.md)
+* [Pickup and Delivery Problem](PDP.md)
+
+OR-Tools comes with lots of vehicle routing samples given in C++, Python, Java
+and .Net. Each language have different requirements for the code samples.
+
+## Basic example
+
+### C++ code samples
+
+```cpp
+#include
+#include "ortools/constraint_solver/routing.h"
+#include "ortools/constraint_solver/routing_enums.pb.h"
+#include "ortools/constraint_solver/routing_index_manager.h"
+#include "ortools/constraint_solver/routing_parameters.h"
+
+namespace operations_research {
+
+void SimpleRoutingProgram() {
+ // Instantiate the data problem.
+ int num_location = 5;
+ int num_vehicles = 1;
+ RoutingIndexManager::NodeIndex depot{0};
+
+ // Create Routing Index Manager
+ RoutingIndexManager manager(num_location, num_vehicles, depot);
+
+ // Create Routing Model.
+ RoutingModel routing(manager);
+
+ // Define cost of each arc.
+ int distance_call_index = routing.RegisterTransitCallback(
+ [&manager](int64 from_index, int64 to_index) -> int64 {
+ // Convert from routing variable Index to user NodeIndex.
+ auto from_node = manager.IndexToNode(from_index).value();
+ auto to_node = manager.IndexToNode(to_index).value();
+ return std::abs(to_node - from_node);
+ });
+ routing.SetArcCostEvaluatorOfAllVehicles(distance_call_index);
+
+ // Setting first solution heuristic.
+ RoutingSearchParameters searchParameters = DefaultRoutingSearchParameters();
+ searchParameters.set_first_solution_strategy(
+ FirstSolutionStrategy::PATH_CHEAPEST_ARC);
+
+ // Solve the problem.
+ const Assignment* solution = routing.SolveWithParameters(searchParameters);
+
+ // Print solution on console.
+ LOG(INFO) << "Objective: " << solution->ObjectiveValue();
+ // Inspect solution.
+ int64 index = routing.Start(0);
+ LOG(INFO) << "Route for Vehicle 0:";
+ int64 route_distance{0};
+ std::ostringstream route;
+ while (routing.IsEnd(index) == false) {
+ route << manager.IndexToNode(index).value() << " -> ";
+ int64 previous_index = index;
+ index = solution->Value(routing.NextVar(index));
+ route_distance +=
+ routing.GetArcCostForVehicle(previous_index, index, int64{0});
+ }
+ LOG(INFO) << route.str() << manager.IndexToNode(index).value();
+ LOG(INFO) << "Distance of the route: " << route_distance << "m";
+}
+
+} // namespace operations_research
+
+int main(int argc, char** argv) {
+ operations_research::SimpleRoutingProgram();
+ return EXIT_SUCCESS;
+}
+```
+
+### Python code samples
+
+```python
+"""Vehicle Routing example."""
+
+from __future__ import print_function
+from ortools.constraint_solver import routing_enums_pb2
+from ortools.constraint_solver import pywrapcp
+from ortools.constraint_solver import pywrapcp
+
+
+def main():
+ """Entry point of the program."""
+ # Instantiate the data problem.
+ num_locations = 5
+ num_vehicles = 1
+ depot = 0
+
+ # Create the routing index manager.
+ manager = pywrapcp.RoutingIndexManager(
+ num_locations,
+ num_vehicles,
+ depot)
+
+ # Create Routing Model.
+ routing = pywrapcp.RoutingModel(manager)
+
+ # Create and register a transit callback.
+ def distance_callback(from_index, to_index):
+ """Returns the absolute difference between the two nodes."""
+ # Convert from routing variable Index to user NodeIndex.
+ from_node = int(manager.IndexToNode(from_index))
+ to_node = int(manager.IndexToNode(to_index))
+ return abs(to_node - from_node)
+ transit_callback_index = routing.RegisterTransitCallback(distance_callback)
+
+ # Define cost of each arc.
+ routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
+
+ # Setting first solution heuristic.
+ search_parameters = pywrapcp.DefaultRoutingSearchParameters()
+ search_parameters.first_solution_strategy = (
+ routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member
+
+ # Solve the problem.
+ assignment = routing.SolveWithParameters(search_parameters)
+
+ # Print solution on console.
+ print('Objective: {}'.format(assignment.ObjectiveValue()))
+ index = routing.Start(0)
+ plan_output = 'Route for vehicle 0:\n'
+ route_distance = 0
+ while not routing.IsEnd(index):
+ plan_output += '{} -> '.format(manager.IndexToNode(index))
+ previous_index = index
+ index = assignment.Value(routing.NextVar(index))
+ route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
+ plan_output += '{}\n'.format(manager.IndexToNode(index))
+ plan_output += 'Distance of the route: {}m\n'.format(route_distance)
+ print(plan_output)
+
+
+if __name__ == '__main__':
+ main()
+```
+
+### Java code samples
+
+```java
+```
+
+### .Net code samples
+
+
+```cs
+using System;
+using Google.OrTools.ConstraintSolver;
+
+///
+/// This is a sample using the routing library .Net wrapper.
+///
+public class SimpleRoutingProgram {
+ public static void Main(String[] args) {
+ // Instantiate the data problem.
+ const int numLocation = 5;
+ const int numVehicles = 1;
+ const int depot = 0;
+
+ // Create Routing Index Manager
+ RoutingIndexManager manager = new RoutingIndexManager(
+ numLocation,
+ numVehicles,
+ depot);
+
+ // Create Routing Model.
+ RoutingModel routing = new RoutingModel(manager);
+
+ // Create and register a transit callback.
+ int transitCallbackIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ // Convert from routing variable Index to distance matrix NodeIndex.
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return Math.Abs(toNode - fromNode);
+ });
+
+ // Define cost of each arc.
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
+
+ // Setting first solution heuristic.
+ RoutingSearchParameters searchParameters =
+ operations_research_constraint_solver.DefaultRoutingSearchParameters();
+ searchParameters.FirstSolutionStrategy =
+ FirstSolutionStrategy.Types.Value.PathCheapestArc;
+
+ // Solve the problem.
+ Assignment solution = routing.SolveWithParameters(searchParameters);
+
+ // Print solution on console.
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ // Inspect solution.
+ long index = routing.Start(0);
+ Console.WriteLine("Route for Vehicle 0:");
+ long route_distance = 0;
+ while (routing.IsEnd(index) == false) {
+ Console.Write("{0} -> ", manager.IndexToNode((int)index));
+ long previousIndex = index;
+ index = solution.Value(routing.NextVar(index));
+ route_distance += routing.GetArcCostForVehicle(previousIndex, index, 0);
+ }
+ Console.WriteLine("{0}", manager.IndexToNode(index));
+ Console.WriteLine("Distance of the route: {0}m", route_distance);
+ }
+}
+```
+
+## Misc
+Images have been generated using [routing_svg.py](routing_svg.py) through bash
+ script [generate_svg.sh](generate_svg.sh).
diff --git a/ortools/constraint_solver/doc/tsp.md b/ortools/constraint_solver/doc/TSP.md
similarity index 86%
rename from ortools/constraint_solver/doc/tsp.md
rename to ortools/constraint_solver/doc/TSP.md
index c21379749d..81314c8621 100644
--- a/ortools/constraint_solver/doc/tsp.md
+++ b/ortools/constraint_solver/doc/TSP.md
@@ -2,9 +2,10 @@
## Introduction
-The Vehicle Routing solver can be used to solve a TSP.
+The Vehicle Routing solver can be used to solve a Travelling Salesman Problem
+(TSP).
-## Travelling Salesman Problem
+## Using Locations
Data Problem:

@@ -12,6 +13,7 @@ Solution:

Samples:
+
* [tsp.cc](../samples/tsp.cc)
* [tsp.py](../samples/tsp.py)
* [Tsp.java](../samples/Tsp.java)
@@ -25,6 +27,7 @@ Solution:

Samples:
+
* [tsp_distance_matrix.cc](../samples/tsp_distance_matrix.cc)
* [tsp_distance_matrix.py](../samples/tsp_distance_matrix.py)
* [TspDistanceMatrix.java](../samples/TspDistanceMatrix.java)
diff --git a/ortools/constraint_solver/doc/vrp.md b/ortools/constraint_solver/doc/VRP.md
similarity index 99%
rename from ortools/constraint_solver/doc/vrp.md
rename to ortools/constraint_solver/doc/VRP.md
index 494e17b7b7..a5151cf7c2 100644
--- a/ortools/constraint_solver/doc/vrp.md
+++ b/ortools/constraint_solver/doc/VRP.md
@@ -12,6 +12,7 @@ Solution:

Samples:
+
* [vrp.cc](../samples/vrp.cc)
* [vrp.py](../samples/vrp.py)
* [Vrp.java](../samples/Vrp.java)
@@ -25,6 +26,7 @@ Solution:

Samples:
+
* [vrp_global_span.cc](../samples/vrp_global_span.cc)
* [vrp_global_span.py](../samples/vrp_global_span.py)
* [VrpGlobalSpan.java](../samples/VrpGlobalSpan.java)
@@ -38,6 +40,7 @@ Solution:

Samples:
+
* [vrp_capacity.cc](../samples/vrp_capacity.cc)
* [vrp_capacity.py](../samples/vrp_capacity.py)
* [VrpCapacity.java](../samples/VrpCapacity.java)
@@ -51,6 +54,7 @@ Solution:

Samples:
+
* [vrp_drop_nodes.cc](../samples/vrp_drop_nodes.cc)
* [vrp_drop_nodes.py](../samples/vrp_drop_nodes.py)
* [VrpDropNodes.java](../samples/VrpDropNodes.java)
@@ -64,6 +68,7 @@ Solution:

Samples:
+
* [vrp_starts_ends.cc](../samples/vrp_starts_ends.cc)
* [vrp_starts_ends.py](../samples/vrp_starts_ends.py)
* [VrpStartsEnds.java](../samples/VrpStartsEnds.java)
@@ -77,6 +82,7 @@ Solution:

Samples:
+
* [vrp_time_windows.cc](../samples/vrp_time_windows.cc)
* [vrp_time_windows.py](../samples/vrp_time_windows.py)
* [VrpTimeWindows.java](../samples/VrpTimeWindows.java)
@@ -90,6 +96,7 @@ Solution:

Samples:
+
* [vrp_resources.cc](../samples/vrp_resources.cc)
* [vrp_resources.py](../samples/vrp_resources.py)
* [VrpResources.java](../samples/VrpResources.java)
diff --git a/ortools/constraint_solver/doc/cp.md b/ortools/constraint_solver/doc/cp.md
deleted file mode 100644
index 056c4484f8..0000000000
--- a/ortools/constraint_solver/doc/cp.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Using the CP solver
-
-## Table of Contents
-
-OR-Tools comes with lots of constraint programming samples given in C++, Python, Java
-and .Net. Each language have different requirements for the code samples.
-
-## Searching for one solution
-
-### C++ code samples
-```cpp
-../samples/simple_cp_program.cc
-```
-
-### Python code samples
-```python
-../samples/simple_cp_program.py
-```
-
-### Java code samples
-```java
-../samples/SimpleCpProgram.java
-```
-
-### .Net code samples
-```cs
-../samples/SimpleCpProgram.cs
-```
diff --git a/ortools/constraint_solver/doc/routing.md b/ortools/constraint_solver/doc/routing.md
deleted file mode 100644
index 2a9fcc5073..0000000000
--- a/ortools/constraint_solver/doc/routing.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Using the Vehicle Routing solver
-
-## Table of Contents
-
-This document presents modeling recipes for the Vehicle routing solver. These are grouped by type:
-* [Travelling Salesman Problem](tsp.md)
-* [Vehicle Routing Problem](vrp.md)
-* [Pickup and Delivery Problem](pdp.md)
-
-OR-Tools comes with lots of vehicle routing samples given in C++, Python, Java
-and .Net. Each language have different requirements for the code samples.
-
-## Searching for one solution
-
-### C++ code samples
-[simple_routing_program.cc](../samples/simple_routing_program.cc)
-
-### Python code samples
-[simple_routing_program.py](../samples/simple_routing_program.py)
-
-### Java code samples
-[SimpleRoutingProgram.java](../samples/SimpleRoutingProgram.java)
-
-### .Net code samples
-[SimpleRoutingProgram.cs](../samples/SimpleRoutingProgram.cs)
-
-## Misc
-Images have been generated using [routing_svg.py](routing_svg.py) through bash script [generate_svg.sh](generate_svg.sh).
diff --git a/ortools/constraint_solver/doc/routing_svg.py b/ortools/constraint_solver/doc/routing_svg.py
index ef0adcab12..debc964e36 100755
--- a/ortools/constraint_solver/doc/routing_svg.py
+++ b/ortools/constraint_solver/doc/routing_svg.py
@@ -1,6 +1,4 @@
-#!/usr/bin/env python3
-# This Python file uses the following encoding: utf-8
-# Copyright 2018 Google LLC
+# Copyright 2010-2018 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -19,13 +17,13 @@ from __future__ import print_function
import argparse
from ortools.constraint_solver import pywrapcp
from ortools.constraint_solver import routing_enums_pb2
-
# [END import]
# [START data_model]
class DataModel: # pylint: disable=too-many-instance-attributes
"""Stores the data for the problem."""
+
def __init__(self, args):
# Locations in block units
locations = \
@@ -148,20 +146,28 @@ class DataModel: # pylint: disable=too-many-instance-attributes
(10, 15), # 15
(5, 15), # 16
]
- if args['drop_nodes'] is True:
+ if args['drop_nodes']:
self._demands = [0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8]
else:
self._demands = [0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8]
self._pickups_deliveries = [
- [1, 6], [2, 10], [4, 3], [5, 9], [7, 8], [15, 11], [13, 12], [16, 14],]
+ [1, 6],
+ [2, 10],
+ [4, 3],
+ [5, 9],
+ [7, 8],
+ [15, 11],
+ [13, 12],
+ [16, 14],
+ ]
- if args['tsp'] is True:
+ if args['tsp']:
self._num_vehicles = 1
else:
self._num_vehicles = 4
self._vehicle_capacities = [15, 15, 15, 15]
- if args['resources'] is True:
+ if args['resources']:
self._vehicle_load_time = 5
self._vehicle_unload_time = 5
@@ -247,10 +253,10 @@ class DataModel: # pylint: disable=too-many-instance-attributes
# Printer #
###########
class GoogleColorPalette():
- """Google color codes palette"""
+ """Google color codes palette."""
def __init__(self):
- """Initialize Google ColorPalette"""
+ """Initialize Google ColorPalette."""
self._colors = [('blue', r'#4285F4'), ('red', r'#EA4335'),
('yellow', r'#FBBC05'), ('green', r'#34A853'),
('black', r'#101010'), ('white', r'#FFFFFF')]
@@ -297,7 +303,7 @@ class SVG():
@staticmethod
def definitions(colors):
- """Writes definitions"""
+ """Writes definitions."""
print(r'')
print(r'')
@@ -307,8 +313,8 @@ class SVG():
'refX="8" refY="8" markerUnits="strokeWidth" markerWidth="5" markerHeight="5" '
'orient="auto">'.format(colorname=color[0]))
print(
- r' '.
- format(color=color[1]))
+ r' '
+ .format(color=color[1]))
print(r' ')
print(r'')
@@ -448,7 +454,7 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
for vehicle_idx, start in enumerate(self._data.starts):
del vehicle_idx
color = self._color_palette.value_from_name('black')
- #color = self._color_palette.value(vehicle_idx)
+ # color = self._color_palette.value(vehicle_idx)
loc = self._data.locations[start]
self._svg.draw_circle(loc, self._radius, self._stroke_width, color,
'white')
@@ -464,7 +470,7 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
"""Draws all the locations but the depot."""
print(r'')
color = self._color_palette.value_from_name('blue')
- if self._args['starts_ends'] is False:
+ if not self._args['starts_ends']:
for idx, loc in enumerate(self._data.locations):
if idx == self._data.depot:
continue
@@ -491,7 +497,7 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
for x, y in zip(loc, [self._radius * 1.2, self._radius * 1.1])
]
color = self._color_palette.value_from_name('red')
- #color = self._color_palette.value(int(math.log(demand, 2)))
+ # color = self._color_palette.value(int(math.log(demand, 2)))
self._svg.draw_text(demand, position, self._radius, 'none', color)
def draw_pickups_deliveries(self):
@@ -539,8 +545,8 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
color = self._color_palette.value_from_name('black')
for node_idx in dropped_nodes:
loc = self._data.locations[node_idx]
- self._svg.draw_circle(loc, self._radius, self._stroke_width,
- color, 'white')
+ self._svg.draw_circle(loc, self._radius, self._stroke_width, color,
+ 'white')
self._svg.draw_text(node_idx, loc, self._radius, 'none', color)
def routes(self):
@@ -566,7 +572,7 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
# First print route
previous_loc_idx = None
for loc_idx in route:
- if previous_loc_idx != None and previous_loc_idx != loc_idx:
+ if previous_loc_idx and previous_loc_idx != loc_idx:
self._svg.draw_polyline(self._data.locations[previous_loc_idx],
self._data.locations[loc_idx],
self._stroke_width, color, colorname)
@@ -589,7 +595,7 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
self.draw_route(route, color, colorname)
def tw_routes(self):
- """Creates the route time window list from the assignment"""
+ """Creates the route time window list from the assignment."""
if self._assignment is None:
print('')
return []
@@ -598,7 +604,7 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
tw_routes = []
for vehicle_id in range(self._data.num_vehicles):
index = self._routing.Start(vehicle_id)
- #index = self._assignment.Value(self._routing.NextVar(index))
+ # index = self._assignment.Value(self._routing.NextVar(index))
loc_route = []
tw_route = []
while True:
@@ -616,16 +622,16 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
return zip(loc_routes, tw_routes)
def draw_tw_route(self, route_idx, locations, tw_route, color):
- """Draws the time windows for a Route"""
- is_start = -1;
+ """Draws the time windows for a Route."""
+ is_start = -1
for loc_idx, time_window in zip(locations, tw_route):
loc = self._data.locations[loc_idx]
if loc_idx == 0: # special case for depot
position = [
- x + y
- for x, y in zip(loc, [
- self._radius * is_start,
- self._radius * (1.8 + route_idx)])
+ x + y for x, y in zip(loc, [
+ self._radius * is_start, self._radius * (
+ 1.8 + route_idx)
+ ])
]
is_start = 1
else:
@@ -634,12 +640,14 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
for x, y in zip(loc, [self._radius * 0, self._radius * 1.8])
]
self._svg.draw_text(
- '[{t_min}]'.format(t_min=time_window[0]),
- position,
- self._radius * 0.75, 'white', color)
+ '[{t_min}]'.format(t_min=time_window[0]),
+ position,
+ self._radius * 0.75,
+ 'white',
+ color)
def draw_tw_routes(self):
- """Draws the time window routes"""
+ """Draws the time window routes."""
print(r'')
for route_idx, loc_tw in enumerate(self.tw_routes()):
print(r''.format(route_idx))
@@ -647,35 +655,31 @@ class SVGPrinter(): # pylint: disable=too-many-instance-attributes
self.draw_tw_route(route_idx, loc_tw[0], loc_tw[1], color)
def print_to_console(self):
- """Prints a full svg document on stdout"""
+ """Prints a full svg document on stdout."""
margin = self._radius * 2 + 2
size = [8 * 114, 8 * 80]
self._svg.header(size, margin)
self._svg.definitions(self._color_palette.colors)
self.draw_grid()
- if self._args['solution'] is False:
- if self._args['pickup_delivery'] is True:
+ if not self._args['solution']:
+ if self._args['pickup_delivery']:
self.draw_pickups_deliveries()
self.draw_locations()
else:
self.draw_routes()
self.draw_drop_nodes()
- if self._args['starts_ends'] is True:
+ if self._args['starts_ends']:
self.draw_depots()
else:
self.draw_depot()
- if self._args['capacity'] is True:
+ if self._args['capacity']:
self.draw_demands()
- if self._args['drop_nodes'] is True:
+ if self._args['drop_nodes']:
self.draw_demands()
- if (self._args['time_windows'] is True) or (self._args['resources'] is True):
+ if self._args['time_windows'] or self._args['resources']:
self.draw_time_windows()
- if ((
- (self._args['time_windows'] is True) or
- (self._args['resources'] is True)
- ) and (
- self._args['solution'] is True)
- ):
+ if ((self._args['time_windows'] or self._args['resources']) and
+ self._args['solution']):
self.draw_tw_routes()
self._svg.footer()
@@ -744,7 +748,7 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
data = DataModel(args)
# [END data]
- if args['solution'] is False:
+ if not args['solution']:
# Print svg on cout
printer = SVGPrinter(args, data)
printer.print_to_console()
@@ -752,7 +756,7 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
# Create the routing index manager.
# [START index_manager]
- if args['starts_ends'] is True:
+ if args['starts_ends']:
manager = pywrapcp.RoutingIndexManager(
len(data.locations), data.num_vehicles, data.starts, data.ends)
else:
@@ -796,29 +800,29 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
demand_callback_index = routing.RegisterUnaryTransitCallback(
demand_callback)
- if (args['time_windows'] is True) or (args['resources'] is True):
+ if args['time_windows'] or args['resources']:
routing.SetArcCostEvaluatorOfAllVehicles(time_callback_index)
else:
routing.SetArcCostEvaluatorOfAllVehicles(distance_callback_index)
- if (args['global_span'] is True) or (args['pickup_delivery'] is True):
+ if args['global_span'] or args['pickup_delivery']:
dimension_name = 'Distance'
routing.AddDimension(distance_callback_index, 0, 3000, True,
dimension_name)
distance_dimension = routing.GetDimensionOrDie(dimension_name)
distance_dimension.SetGlobalSpanCostCoefficient(100)
- if (args['capacity'] is True) or (args['drop_nodes'] is True):
+ if args['capacity'] or args['drop_nodes']:
routing.AddDimensionWithVehicleCapacity(
demand_callback_index, 0, data.vehicle_capacities, True, 'Capacity')
- if args['drop_nodes'] is True:
+ if args['drop_nodes']:
# Allow to drop nodes.
penalty = 1000
for node in range(1, len(data.locations)):
routing.AddDisjunction([manager.NodeToIndex(node)], penalty)
- if args['pickup_delivery'] is True:
+ if args['pickup_delivery']:
dimension_name = 'Distance'
routing.AddDimension(distance_callback_index, 0, 3000, True,
dimension_name)
@@ -834,14 +838,14 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
routing.solver().Add(
distance_dimension.CumulVar(pickup_index) <=
distance_dimension.CumulVar(delivery_index))
- if args['fifo'] is True:
+ if args['fifo']:
routing.SetPickupAndDeliveryPolicyOfAllVehicles(
pywrapcp.RoutingModel.FIFO)
- if args['lifo'] is True:
+ if args['lifo']:
routing.SetPickupAndDeliveryPolicyOfAllVehicles(
pywrapcp.RoutingModel.LIFO)
- if args['starts_ends'] is True:
+ if args['starts_ends']:
dimension_name = 'Distance'
routing.AddDimension(distance_callback_index, 0, 2000, True,
dimension_name)
@@ -849,11 +853,11 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
distance_dimension.SetGlobalSpanCostCoefficient(100)
time = 'Time'
- if (args['time_windows'] is True) or (args['resources'] is True):
+ if args['time_windows'] or args['resources']:
routing.AddDimension(time_callback_index, 30, 30, False, time)
time_dimension = routing.GetDimensionOrDie(time)
- # Add time window constraints for each location except depot
- # and 'copy' the slack var in the solution object (aka Assignment) to print it
+ # Add time window constraints for each location except depot and 'copy' the
+ # slack var in the solution object (aka Assignment) to print it.
for location_idx, time_window in enumerate(data.time_windows):
if location_idx == 0:
continue
@@ -861,8 +865,8 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
time_dimension.CumulVar(index).SetRange(time_window[0],
time_window[1])
routing.AddToAssignment(time_dimension.SlackVar(index))
- # Add time window constraints for each vehicle start node
- # and 'copy' the slack var in the solution object (aka Assignment) to print it
+ # Add time window constraints for each vehicle start node and 'copy' the
+ # slack var in the solution object (aka Assignment) to print it.
for vehicle_id in range(data.num_vehicles):
index = routing.Start(vehicle_id)
time_window = data.time_windows[0]
@@ -872,41 +876,37 @@ def main(): # pylint: disable=too-many-locals,too-many-branches
# Instantiate route start and end times to produce feasible times.
for vehicle_id in range(data.num_vehicles):
- routing.AddVariableMinimizedByFinalizer(
- time_dimension.CumulVar(routing.End(vehicle_id)))
- routing.AddVariableMinimizedByFinalizer(
- time_dimension.CumulVar(routing.Start(vehicle_id)))
+ routing.AddVariableMinimizedByFinalizer(
+ time_dimension.CumulVar(routing.End(vehicle_id)))
+ routing.AddVariableMinimizedByFinalizer(
+ time_dimension.CumulVar(routing.Start(vehicle_id)))
- if args['resources'] is True:
+ if args['resources']:
# Add resource constraints at the depot.
time_dimension = routing.GetDimensionOrDie(time)
solver = routing.solver()
intervals = []
for i in range(data.num_vehicles):
- # Add loading time at start of routes
- intervals.append(solver.FixedDurationIntervalVar(
- time_dimension.CumulVar(routing.Start(i)),
- data.vehicle_load_time,
- 'depot_interval')
- )
- # Add unloading time at end of routes.
- intervals.append(solver.FixedDurationIntervalVar(
- time_dimension.CumulVar(routing.End(i)),
- data.vehicle_unload_time,
- 'depot_interval ')
- )
+ # Add loading time at start of routes
+ intervals.append(
+ solver.FixedDurationIntervalVar(
+ time_dimension.CumulVar(routing.Start(i)),
+ data.vehicle_load_time, 'depot_interval'))
+ # Add unloading time at end of routes.
+ intervals.append(
+ solver.FixedDurationIntervalVar(
+ time_dimension.CumulVar(routing.End(i)),
+ data.vehicle_unload_time, 'depot_interval '))
depot_usage = [1 for i in range(data.num_vehicles * 2)]
- solver.AddConstraint(solver.Cumulative(
- intervals,
- depot_usage,
- data.depot_capacity,
- 'depot'))
+ solver.AddConstraint(
+ solver.Cumulative(intervals, depot_usage, data.depot_capacity,
+ 'depot'))
# Setting first solution heuristic (cheapest addition).
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
# pylint: disable=no-member
- if args['pickup_delivery'] is False:
+ if not args['pickup_delivery']:
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
else:
diff --git a/ortools/constraint_solver/samples/tsp.py b/ortools/constraint_solver/samples/tsp.py
index c465e5acd6..b2f3afe806 100755
--- a/ortools/constraint_solver/samples/tsp.py
+++ b/ortools/constraint_solver/samples/tsp.py
@@ -21,7 +21,6 @@ http://en.wikipedia.org/wiki/Travelling_salesman_problem.
from __future__ import print_function
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
-
# [END import]
diff --git a/ortools/constraint_solver/samples/vrp_resources.py b/ortools/constraint_solver/samples/vrp_resources.py
index 0f16c29f4f..2478265665 100644
--- a/ortools/constraint_solver/samples/vrp_resources.py
+++ b/ortools/constraint_solver/samples/vrp_resources.py
@@ -17,7 +17,6 @@
from __future__ import print_function
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
-
# [END import]