Adding TspCities and TspCircuitBoard example
This commit is contained in:
@@ -370,6 +370,8 @@ test_cc_constraint_solver_samples: \
|
||||
rcc_simple_ls_program \
|
||||
rcc_simple_routing_program \
|
||||
rcc_tsp \
|
||||
rcc_tsp_cities \
|
||||
rcc_tsp_circuit_board \
|
||||
rcc_tsp_distance_matrix \
|
||||
rcc_vrp \
|
||||
rcc_vrp_capacity \
|
||||
|
||||
@@ -442,6 +442,8 @@ test_dotnet_algorithms_samples: ;
|
||||
test_dotnet_constraint_solver_samples:
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/SimpleRoutingProgram.cs
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/Tsp.cs
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/TspCities.cs
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/TspCircuitBoard.cs
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/TspDistanceMatrix.cs
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/Vrp.cs
|
||||
$(MAKE) run SOURCE=ortools/constraint_solver/samples/VrpCapacity.cs
|
||||
|
||||
@@ -375,6 +375,8 @@ test_java_algorithms_samples: \
|
||||
test_java_constraint_solver_samples: \
|
||||
rjava_SimpleRoutingProgram \
|
||||
rjava_Tsp \
|
||||
rjava_TspCities \
|
||||
rjava_TspCircuitBoard \
|
||||
rjava_TspDistanceMatrix \
|
||||
rjava_Vrp \
|
||||
rjava_VrpCapacity \
|
||||
|
||||
@@ -501,6 +501,8 @@ test_python_constraint_solver_samples: \
|
||||
rpy_simple_cp_program \
|
||||
rpy_simple_routing_program \
|
||||
rpy_tsp \
|
||||
rpy_tsp_cities \
|
||||
rpy_tsp_circuit_board \
|
||||
rpy_tsp_distance_matrix \
|
||||
rpy_vrp \
|
||||
rpy_vrp_capacity \
|
||||
|
||||
187
ortools/constraint_solver/samples/TspCircuitBoard.cs
Normal file
187
ortools/constraint_solver/samples/TspCircuitBoard.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// [START program]
|
||||
// [START import]
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Google.OrTools.ConstraintSolver;
|
||||
// [END import]
|
||||
|
||||
/// <summary>
|
||||
/// Minimal TSP.
|
||||
/// A description of the problem can be found here:
|
||||
/// http://en.wikipedia.org/wiki/Travelling_salesman_problem.
|
||||
/// </summary>
|
||||
public class TspCircuitBoard {
|
||||
// [START data_model]
|
||||
class DataModel {
|
||||
public int[,] Locations = {
|
||||
{288, 149}, {288, 129}, {270, 133}, {256, 141}, {256, 157}, {246, 157},
|
||||
{236, 169}, {228, 169}, {228, 161}, {220, 169}, {212, 169}, {204, 169},
|
||||
{196, 169}, {188, 169}, {196, 161}, {188, 145}, {172, 145}, {164, 145},
|
||||
{156, 145}, {148, 145}, {140, 145}, {148, 169}, {164, 169}, {172, 169},
|
||||
{156, 169}, {140, 169}, {132, 169}, {124, 169}, {116, 161}, {104, 153},
|
||||
{104, 161}, {104, 169}, {90, 165}, {80, 157}, {64, 157}, {64, 165},
|
||||
{56, 169}, {56, 161}, {56, 153}, {56, 145}, {56, 137}, {56, 129},
|
||||
{56, 121}, {40, 121}, {40, 129}, {40, 137}, {40, 145}, {40, 153},
|
||||
{40, 161}, {40, 169}, {32, 169}, {32, 161}, {32, 153}, {32, 145},
|
||||
{32, 137}, {32, 129}, {32, 121}, {32, 113}, {40, 113}, {56, 113},
|
||||
{56, 105}, {48, 99}, {40, 99}, {32, 97}, {32, 89}, {24, 89}, {16, 97},
|
||||
{16, 109}, {8, 109}, {8, 97}, {8, 89}, {8, 81}, {8, 73}, {8, 65},
|
||||
{8, 57}, {16, 57}, {8, 49}, {8, 41}, {24, 45}, {32, 41}, {32, 49},
|
||||
{32, 57}, {32, 65}, {32, 73}, {32, 81}, {40, 83}, {40, 73}, {40, 63},
|
||||
{40, 51}, {44, 43}, {44, 35}, {44, 27}, {32, 25}, {24, 25}, {16, 25},
|
||||
{16, 17}, {24, 17}, {32, 17}, {44, 11}, {56, 9}, {56, 17}, {56, 25},
|
||||
{56, 33}, {56, 41}, {64, 41}, {72, 41}, {72, 49}, {56, 49}, {48, 51},
|
||||
{56, 57}, {56, 65}, {48, 63}, {48, 73}, {56, 73}, {56, 81}, {48, 83},
|
||||
{56, 89}, {56, 97}, {104, 97}, {104, 105}, {104, 113}, {104, 121},
|
||||
{104, 129}, {104, 137}, {104, 145}, {116, 145}, {124, 145}, {132, 145},
|
||||
{132, 137}, {140, 137}, {148, 137}, {156, 137}, {164, 137}, {172, 125},
|
||||
{172, 117}, {172, 109}, {172, 101}, {172, 93}, {172, 85}, {180, 85},
|
||||
{180, 77}, {180, 69}, {180, 61}, {180, 53}, {172, 53}, {172, 61},
|
||||
{172, 69}, {172, 77}, {164, 81}, {148, 85}, {124, 85}, {124, 93},
|
||||
{124, 109}, {124, 125}, {124, 117}, {124, 101}, {104, 89}, {104, 81},
|
||||
{104, 73}, {104, 65}, {104, 49}, {104, 41}, {104, 33}, {104, 25},
|
||||
{104, 17}, {92, 9}, {80, 9}, {72, 9}, {64, 21}, {72, 25}, {80, 25},
|
||||
{80, 25}, {80, 41}, {88, 49}, {104, 57}, {124, 69}, {124, 77}, {132, 81},
|
||||
{140, 65}, {132, 61}, {124, 61}, {124, 53}, {124, 45}, {124, 37},
|
||||
{124, 29}, {132, 21}, {124, 21}, {120, 9}, {128, 9}, {136, 9}, {148, 9},
|
||||
{162, 9}, {156, 25}, {172, 21}, {180, 21}, {180, 29}, {172, 29},
|
||||
{172, 37}, {172, 45}, {180, 45}, {180, 37}, {188, 41}, {196, 49},
|
||||
{204, 57}, {212, 65}, {220, 73}, {228, 69}, {228, 77}, {236, 77},
|
||||
{236, 69}, {236, 61}, {228, 61}, {228, 53}, {236, 53}, {236, 45},
|
||||
{228, 45}, {228, 37}, {236, 37}, {236, 29}, {228, 29}, {228, 21},
|
||||
{236, 21}, {252, 21}, {260, 29}, {260, 37}, {260, 45}, {260, 53},
|
||||
{260, 61}, {260, 69}, {260, 77}, {276, 77}, {276, 69}, {276, 61},
|
||||
{276, 53}, {284, 53}, {284, 61}, {284, 69}, {284, 77}, {284, 85},
|
||||
{284, 93}, {284, 101}, {288, 109}, {280, 109}, {276, 101}, {276, 93},
|
||||
{276, 85}, {268, 97}, {260, 109}, {252, 101}, {260, 93}, {260, 85},
|
||||
{236, 85}, {228, 85}, {228, 93}, {236, 93}, {236, 101}, {228, 101},
|
||||
{228, 109}, {228, 117}, {228, 125}, {220, 125}, {212, 117}, {204, 109},
|
||||
{196, 101}, {188, 93}, {180, 93}, {180, 101}, {180, 109}, {180, 117},
|
||||
{180, 125}, {196, 145}, {204, 145}, {212, 145}, {220, 145}, {228, 145},
|
||||
{236, 145}, {246, 141}, {252, 125}, {260, 129}, {280, 133},
|
||||
};
|
||||
public int VehicleNumber = 1;
|
||||
public int Depot = 0;
|
||||
};
|
||||
// [END data_model]
|
||||
|
||||
// [START euclidean_distance]
|
||||
/// <summary>
|
||||
/// Euclidean distance implemented as a callback. It uses an array of
|
||||
/// positions and computes the Euclidean distance between the two
|
||||
/// positions of two different indices.
|
||||
/// </summary>
|
||||
static long[,] ComputeEuclideanDistanceMatrix(in int[,] locations) {
|
||||
// Calculate the distance matrix using Euclidean distance.
|
||||
int locationNumber = locations.GetLength(0);
|
||||
long[,] distanceMatrix = new long[locationNumber, locationNumber];
|
||||
for (int fromNode = 0; fromNode < locationNumber; fromNode++) {
|
||||
for (int toNode = 0; toNode < locationNumber; toNode++) {
|
||||
if (fromNode == toNode)
|
||||
distanceMatrix[fromNode, toNode] = 0;
|
||||
else
|
||||
distanceMatrix[fromNode, toNode] =
|
||||
(long)Math.Sqrt(
|
||||
Math.Pow(locations[toNode, 0] -
|
||||
locations[fromNode, 0], 2) +
|
||||
Math.Pow(locations[toNode, 1] -
|
||||
locations[fromNode, 1], 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
return distanceMatrix;
|
||||
}
|
||||
// [END euclidean_distance]
|
||||
|
||||
// [START solution_printer]
|
||||
/// <summary>
|
||||
/// Print the solution.
|
||||
/// </summary>
|
||||
static void PrintSolution(
|
||||
in RoutingModel routing,
|
||||
in RoutingIndexManager manager,
|
||||
in Assignment solution) {
|
||||
Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
|
||||
// Inspect solution.
|
||||
Console.WriteLine("Route:");
|
||||
long routeDistance = 0;
|
||||
var index = routing.Start(0);
|
||||
while (routing.IsEnd(index) == false) {
|
||||
Console.Write("{0} -> ", manager.IndexToNode((int)index));
|
||||
var previousIndex = index;
|
||||
index = solution.Value(routing.NextVar(index));
|
||||
routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
|
||||
}
|
||||
Console.WriteLine("{0}", manager.IndexToNode((int)index));
|
||||
Console.WriteLine("Route distance: {0}m", routeDistance);
|
||||
}
|
||||
// [END solution_printer]
|
||||
|
||||
public static void Main(String[] args) {
|
||||
// Instantiate the data problem.
|
||||
// [START data]
|
||||
DataModel data = new DataModel();
|
||||
// [END data]
|
||||
|
||||
// Create Routing Index Manager
|
||||
// [START index_manager]
|
||||
RoutingIndexManager manager = new RoutingIndexManager(
|
||||
data.Locations.GetLength(0),
|
||||
data.VehicleNumber,
|
||||
data.Depot);
|
||||
// [END index_manager]
|
||||
|
||||
// Create Routing Model.
|
||||
// [START routing_model]
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// [END routing_model]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START transit_callback]
|
||||
long[,] distanceMatrix = ComputeEuclideanDistanceMatrix(data.Locations);
|
||||
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 distanceMatrix[fromNode, toNode]; }
|
||||
);
|
||||
// [END transit_callback]
|
||||
|
||||
// [START arc_cost
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// [END arc_cost]
|
||||
|
||||
// Setting first solution heuristic.
|
||||
// [START parameters]
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy =
|
||||
FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
// [END parameters]
|
||||
|
||||
// Solve the problem.
|
||||
// [START solve]
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// [END solve]
|
||||
|
||||
// Print solution on console.
|
||||
// [START print_solution]
|
||||
PrintSolution(routing, manager, solution);
|
||||
// [END print_solution]
|
||||
}
|
||||
}
|
||||
// [END program]
|
||||
20
ortools/constraint_solver/samples/TspCircuitBoard.csproj
Normal file
20
ortools/constraint_solver/samples/TspCircuitBoard.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<LangVersion>7.2</LangVersion>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
<RestoreSources>../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json</RestoreSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<GenerateTailCalls>true</GenerateTailCalls>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="TspCircuitBoard.cs" />
|
||||
<PackageReference Include="Google.OrTools" Version="7.0.6170-*" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
177
ortools/constraint_solver/samples/TspCircuitBoard.java
Normal file
177
ortools/constraint_solver/samples/TspCircuitBoard.java
Normal file
@@ -0,0 +1,177 @@
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// [START program]
|
||||
// [START import]
|
||||
|
||||
import com.google.ortools.constraintsolver.Assignment;
|
||||
import com.google.ortools.constraintsolver.FirstSolutionStrategy;
|
||||
import com.google.ortools.constraintsolver.RoutingIndexManager;
|
||||
import com.google.ortools.constraintsolver.RoutingModel;
|
||||
import com.google.ortools.constraintsolver.RoutingSearchParameters;
|
||||
import com.google.ortools.constraintsolver.main;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
// [END import]
|
||||
|
||||
/** Minimal TSP. */
|
||||
public class TspCircuitBoard {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TspCircuitBoard.class.getName());
|
||||
|
||||
// [START data_model]
|
||||
static class DataModel {
|
||||
public final int[][] locations = {{288, 149}, {288, 129}, {270, 133}, {256, 141}, {256, 157},
|
||||
{246, 157}, {236, 169}, {228, 169}, {228, 161}, {220, 169}, {212, 169}, {204, 169},
|
||||
{196, 169}, {188, 169}, {196, 161}, {188, 145}, {172, 145}, {164, 145}, {156, 145},
|
||||
{148, 145}, {140, 145}, {148, 169}, {164, 169}, {172, 169}, {156, 169}, {140, 169},
|
||||
{132, 169}, {124, 169}, {116, 161}, {104, 153}, {104, 161}, {104, 169}, {90, 165},
|
||||
{80, 157}, {64, 157}, {64, 165}, {56, 169}, {56, 161}, {56, 153}, {56, 145}, {56, 137},
|
||||
{56, 129}, {56, 121}, {40, 121}, {40, 129}, {40, 137}, {40, 145}, {40, 153}, {40, 161},
|
||||
{40, 169}, {32, 169}, {32, 161}, {32, 153}, {32, 145}, {32, 137}, {32, 129}, {32, 121},
|
||||
{32, 113}, {40, 113}, {56, 113}, {56, 105}, {48, 99}, {40, 99}, {32, 97}, {32, 89},
|
||||
{24, 89}, {16, 97}, {16, 109}, {8, 109}, {8, 97}, {8, 89}, {8, 81}, {8, 73}, {8, 65},
|
||||
{8, 57}, {16, 57}, {8, 49}, {8, 41}, {24, 45}, {32, 41}, {32, 49}, {32, 57}, {32, 65},
|
||||
{32, 73}, {32, 81}, {40, 83}, {40, 73}, {40, 63}, {40, 51}, {44, 43}, {44, 35}, {44, 27},
|
||||
{32, 25}, {24, 25}, {16, 25}, {16, 17}, {24, 17}, {32, 17}, {44, 11}, {56, 9}, {56, 17},
|
||||
{56, 25}, {56, 33}, {56, 41}, {64, 41}, {72, 41}, {72, 49}, {56, 49}, {48, 51}, {56, 57},
|
||||
{56, 65}, {48, 63}, {48, 73}, {56, 73}, {56, 81}, {48, 83}, {56, 89}, {56, 97}, {104, 97},
|
||||
{104, 105}, {104, 113}, {104, 121}, {104, 129}, {104, 137}, {104, 145}, {116, 145},
|
||||
{124, 145}, {132, 145}, {132, 137}, {140, 137}, {148, 137}, {156, 137}, {164, 137},
|
||||
{172, 125}, {172, 117}, {172, 109}, {172, 101}, {172, 93}, {172, 85}, {180, 85}, {180, 77},
|
||||
{180, 69}, {180, 61}, {180, 53}, {172, 53}, {172, 61}, {172, 69}, {172, 77}, {164, 81},
|
||||
{148, 85}, {124, 85}, {124, 93}, {124, 109}, {124, 125}, {124, 117}, {124, 101}, {104, 89},
|
||||
{104, 81}, {104, 73}, {104, 65}, {104, 49}, {104, 41}, {104, 33}, {104, 25}, {104, 17},
|
||||
{92, 9}, {80, 9}, {72, 9}, {64, 21}, {72, 25}, {80, 25}, {80, 25}, {80, 41}, {88, 49},
|
||||
{104, 57}, {124, 69}, {124, 77}, {132, 81}, {140, 65}, {132, 61}, {124, 61}, {124, 53},
|
||||
{124, 45}, {124, 37}, {124, 29}, {132, 21}, {124, 21}, {120, 9}, {128, 9}, {136, 9},
|
||||
{148, 9}, {162, 9}, {156, 25}, {172, 21}, {180, 21}, {180, 29}, {172, 29}, {172, 37},
|
||||
{172, 45}, {180, 45}, {180, 37}, {188, 41}, {196, 49}, {204, 57}, {212, 65}, {220, 73},
|
||||
{228, 69}, {228, 77}, {236, 77}, {236, 69}, {236, 61}, {228, 61}, {228, 53}, {236, 53},
|
||||
{236, 45}, {228, 45}, {228, 37}, {236, 37}, {236, 29}, {228, 29}, {228, 21}, {236, 21},
|
||||
{252, 21}, {260, 29}, {260, 37}, {260, 45}, {260, 53}, {260, 61}, {260, 69}, {260, 77},
|
||||
{276, 77}, {276, 69}, {276, 61}, {276, 53}, {284, 53}, {284, 61}, {284, 69}, {284, 77},
|
||||
{284, 85}, {284, 93}, {284, 101}, {288, 109}, {280, 109}, {276, 101}, {276, 93}, {276, 85},
|
||||
{268, 97}, {260, 109}, {252, 101}, {260, 93}, {260, 85}, {236, 85}, {228, 85}, {228, 93},
|
||||
{236, 93}, {236, 101}, {228, 101}, {228, 109}, {228, 117}, {228, 125}, {220, 125},
|
||||
{212, 117}, {204, 109}, {196, 101}, {188, 93}, {180, 93}, {180, 101}, {180, 109},
|
||||
{180, 117}, {180, 125}, {196, 145}, {204, 145}, {212, 145}, {220, 145}, {228, 145},
|
||||
{236, 145}, {246, 141}, {252, 125}, {260, 129}, {280, 133}};
|
||||
public final int vehicleNumber = 1;
|
||||
public final int depot = 0;
|
||||
}
|
||||
// [END data_model]
|
||||
|
||||
// [START euclidean_distance]
|
||||
/// @brief Compute Euclidean distance matrix from locations array.
|
||||
/// @details It uses an array of locations and computes
|
||||
/// the Euclidean distance between any two locations.
|
||||
private static long[][] computeEuclideanDistanceMatrix(int[][] locations) {
|
||||
// Calculate distance matrix using Euclidean distance.
|
||||
long[][] distanceMatrix = new long[locations.length][locations.length];
|
||||
for (int fromNode = 0; fromNode < locations.length; ++fromNode) {
|
||||
for (int toNode = 0; toNode < locations.length; ++toNode) {
|
||||
if (fromNode == toNode) {
|
||||
distanceMatrix[fromNode][toNode] = 0;
|
||||
} else {
|
||||
distanceMatrix[fromNode][toNode] =
|
||||
(long) Math.hypot(locations[toNode][0] - locations[fromNode][0],
|
||||
locations[toNode][1] - locations[fromNode][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return distanceMatrix;
|
||||
}
|
||||
// [END euclidean_distance]
|
||||
|
||||
// [START solution_printer]
|
||||
/// @brief Print the solution.
|
||||
static void printSolution(
|
||||
DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) {
|
||||
// Solution cost.
|
||||
logger.info("Objective: " + solution.objectiveValue());
|
||||
// Inspect solution.
|
||||
logger.info("Route:");
|
||||
long routeDistance = 0;
|
||||
String route = "";
|
||||
long index = routing.start(0);
|
||||
while (!routing.isEnd(index)) {
|
||||
route += manager.indexToNode(index) + " -> ";
|
||||
long previousIndex = index;
|
||||
index = solution.value(routing.nextVar(index));
|
||||
routing.getArcCostForVehicle(previousIndex, index, 0);
|
||||
}
|
||||
route += manager.indexToNode(routing.end(0));
|
||||
logger.info(route);
|
||||
logger.info("Route distance: " + routeDistance);
|
||||
}
|
||||
// [END solution_printer]
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Instantiate the data problem.
|
||||
// [START data]
|
||||
final DataModel data = new DataModel();
|
||||
// [END data]
|
||||
|
||||
// Create Routing Index Manager
|
||||
// [START index_manager]
|
||||
RoutingIndexManager manager =
|
||||
new RoutingIndexManager(data.locations.length, data.vehicleNumber, data.depot);
|
||||
// [END index_manager]
|
||||
|
||||
// Create Routing Model.
|
||||
// [START routing_model]
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// [END routing_model]
|
||||
|
||||
// Create and register a transit callback.
|
||||
// [START transit_callback]
|
||||
final long[][] distanceMatrix = computeEuclideanDistanceMatrix(data.locations);
|
||||
final int transitCallbackIndex =
|
||||
routing.registerTransitCallback((long fromIndex, long toIndex) -> {
|
||||
// Convert from routing variable Index to user NodeIndex.
|
||||
int fromNode = manager.indexToNode(fromIndex);
|
||||
int toNode = manager.indexToNode(toIndex);
|
||||
return distanceMatrix[fromNode][toNode];
|
||||
});
|
||||
// [END transit_callback]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START arc_cost]
|
||||
routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// [END arc_cost]
|
||||
|
||||
// Setting first solution heuristic.
|
||||
// [START parameters]
|
||||
RoutingSearchParameters searchParameters =
|
||||
main.defaultRoutingSearchParameters()
|
||||
.toBuilder()
|
||||
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC)
|
||||
.build();
|
||||
// [END parameters]
|
||||
|
||||
// Solve the problem.
|
||||
// [START solve]
|
||||
Assignment solution = routing.solveWithParameters(searchParameters);
|
||||
// [END solve]
|
||||
|
||||
// Print solution on console.
|
||||
// [START print_solution]
|
||||
printSolution(data, routing, manager, solution);
|
||||
// [END print_solution]
|
||||
}
|
||||
}
|
||||
// [END program]
|
||||
124
ortools/constraint_solver/samples/TspCities.cs
Normal file
124
ortools/constraint_solver/samples/TspCities.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// [START program]
|
||||
// [START import]
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Google.OrTools.ConstraintSolver;
|
||||
// [END import]
|
||||
|
||||
/// <summary>
|
||||
/// Minimal TSP using distance matrix.
|
||||
/// </summary>
|
||||
public class TspCities {
|
||||
// [START data_model]
|
||||
class DataModel {
|
||||
public long[,] DistanceMatrix = {
|
||||
{0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972},
|
||||
{2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579},
|
||||
{713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260},
|
||||
{1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987},
|
||||
{1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371},
|
||||
{1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999},
|
||||
{2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701},
|
||||
{213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099},
|
||||
{2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600},
|
||||
{875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162},
|
||||
{1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200},
|
||||
{2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504},
|
||||
{1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0},
|
||||
};
|
||||
public int VehicleNumber = 1;
|
||||
public int Depot = 0;
|
||||
};
|
||||
// [END data_model]
|
||||
|
||||
// [START solution_printer]
|
||||
/// <summary>
|
||||
/// Print the solution.
|
||||
/// </summary>
|
||||
static void PrintSolution(
|
||||
in RoutingModel routing,
|
||||
in RoutingIndexManager manager,
|
||||
in Assignment solution) {
|
||||
Console.WriteLine("Objective: {0} miles", solution.ObjectiveValue());
|
||||
// Inspect solution.
|
||||
Console.WriteLine("Route:");
|
||||
long routeDistance = 0;
|
||||
var index = routing.Start(0);
|
||||
while (routing.IsEnd(index) == false) {
|
||||
Console.Write("{0} -> ", manager.IndexToNode((int)index));
|
||||
var previousIndex = index;
|
||||
index = solution.Value(routing.NextVar(index));
|
||||
routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
|
||||
}
|
||||
Console.WriteLine("{0}", manager.IndexToNode((int)index));
|
||||
Console.WriteLine("Route distance: {0}miles", routeDistance);
|
||||
}
|
||||
// [END solution_printer]
|
||||
|
||||
public static void Main(String[] args) {
|
||||
// Instantiate the data problem.
|
||||
// [START data]
|
||||
DataModel data = new DataModel();
|
||||
// [END data]
|
||||
|
||||
// Create Routing Index Manager
|
||||
// [START index_manager]
|
||||
RoutingIndexManager manager = new RoutingIndexManager(
|
||||
data.DistanceMatrix.GetLength(0),
|
||||
data.VehicleNumber,
|
||||
data.Depot);
|
||||
// [END index_manager]
|
||||
|
||||
// Create Routing Model.
|
||||
// [START routing_model]
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// [END routing_model]
|
||||
|
||||
// [START 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 data.DistanceMatrix[fromNode, toNode]; }
|
||||
);
|
||||
// [END transit_callback]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START arc_cost]
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// [END arc_cost]
|
||||
|
||||
// Setting first solution heuristic.
|
||||
// [START parameters]
|
||||
RoutingSearchParameters searchParameters =
|
||||
operations_research_constraint_solver.DefaultRoutingSearchParameters();
|
||||
searchParameters.FirstSolutionStrategy =
|
||||
FirstSolutionStrategy.Types.Value.PathCheapestArc;
|
||||
// [END parameters]
|
||||
|
||||
// Solve the problem.
|
||||
// [START solve]
|
||||
Assignment solution = routing.SolveWithParameters(searchParameters);
|
||||
// [END solve]
|
||||
|
||||
// Print solution on console.
|
||||
// [START print_solution]
|
||||
PrintSolution(routing, manager, solution);
|
||||
// [END print_solution]
|
||||
}
|
||||
}
|
||||
// [END program]
|
||||
20
ortools/constraint_solver/samples/TspCities.csproj
Normal file
20
ortools/constraint_solver/samples/TspCities.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<LangVersion>7.2</LangVersion>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
<RestoreSources>../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json</RestoreSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<GenerateTailCalls>true</GenerateTailCalls>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="TspCities.cs" />
|
||||
<PackageReference Include="Google.OrTools" Version="7.0.6170-*" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
132
ortools/constraint_solver/samples/TspCities.java
Normal file
132
ortools/constraint_solver/samples/TspCities.java
Normal file
@@ -0,0 +1,132 @@
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// [START program]
|
||||
// [START import]
|
||||
import com.google.ortools.constraintsolver.Assignment;
|
||||
import com.google.ortools.constraintsolver.FirstSolutionStrategy;
|
||||
import com.google.ortools.constraintsolver.RoutingIndexManager;
|
||||
import com.google.ortools.constraintsolver.RoutingModel;
|
||||
import com.google.ortools.constraintsolver.RoutingSearchParameters;
|
||||
import com.google.ortools.constraintsolver.main;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
// [END import]
|
||||
|
||||
/** Minimal TSP using distance matrix. */
|
||||
public class TspCities {
|
||||
static {
|
||||
System.loadLibrary("jniortools");
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TspCities.class.getName());
|
||||
|
||||
// [START data_model]
|
||||
static class DataModel {
|
||||
public final long[][] distanceMatrix = {
|
||||
{0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972},
|
||||
{2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579},
|
||||
{713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260},
|
||||
{1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987},
|
||||
{1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371},
|
||||
{1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999},
|
||||
{2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701},
|
||||
{213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099},
|
||||
{2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600},
|
||||
{875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162},
|
||||
{1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200},
|
||||
{2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504},
|
||||
{1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0},
|
||||
};
|
||||
public final int vehicleNumber = 1;
|
||||
public final int depot = 0;
|
||||
}
|
||||
// [END data_model]
|
||||
|
||||
// [START solution_printer]
|
||||
/// @brief Print the solution.
|
||||
static void printSolution(
|
||||
DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) {
|
||||
// Solution cost.
|
||||
logger.info("Objective: " + solution.objectiveValue() + "miles");
|
||||
// Inspect solution.
|
||||
logger.info("Route:");
|
||||
long routeDistance = 0;
|
||||
String route = "";
|
||||
long index = routing.start(0);
|
||||
while (!routing.isEnd(index)) {
|
||||
route += manager.indexToNode(index) + " -> ";
|
||||
long previousIndex = index;
|
||||
index = solution.value(routing.nextVar(index));
|
||||
routeDistance += routing.getArcCostForVehicle(previousIndex, index, 0);
|
||||
}
|
||||
route += manager.indexToNode(routing.end(0));
|
||||
logger.info(route);
|
||||
logger.info("Route distance: " + routeDistance + "miles");
|
||||
}
|
||||
// [END solution_printer]
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Instantiate the data problem.
|
||||
// [START data]
|
||||
final DataModel data = new DataModel();
|
||||
// [END data]
|
||||
|
||||
// Create Routing Index Manager
|
||||
// [START index_manager]
|
||||
RoutingIndexManager manager =
|
||||
new RoutingIndexManager(data.distanceMatrix.length, data.vehicleNumber, data.depot);
|
||||
// [END index_manager]
|
||||
|
||||
// Create Routing Model.
|
||||
// [START routing_model]
|
||||
RoutingModel routing = new RoutingModel(manager);
|
||||
// [END routing_model]
|
||||
|
||||
// Create and register a transit callback.
|
||||
// [START transit_callback]
|
||||
final int transitCallbackIndex =
|
||||
routing.registerTransitCallback((long fromIndex, long toIndex) -> {
|
||||
// Convert from routing variable Index to user NodeIndex.
|
||||
int fromNode = manager.indexToNode(fromIndex);
|
||||
int toNode = manager.indexToNode(toIndex);
|
||||
return data.distanceMatrix[fromNode][toNode];
|
||||
});
|
||||
// [END transit_callback]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START arc_cost]
|
||||
routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// [END arc_cost]
|
||||
|
||||
// Setting first solution heuristic.
|
||||
// [START parameters]
|
||||
RoutingSearchParameters searchParameters =
|
||||
main.defaultRoutingSearchParameters()
|
||||
.toBuilder()
|
||||
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC)
|
||||
.build();
|
||||
// [END parameters]
|
||||
|
||||
// Solve the problem.
|
||||
// [START solve]
|
||||
Assignment solution = routing.solveWithParameters(searchParameters);
|
||||
// [END solve]
|
||||
|
||||
// Print solution on console.
|
||||
// [START print_solution]
|
||||
printSolution(data, routing, manager, solution);
|
||||
// [END print_solution]
|
||||
}
|
||||
}
|
||||
// [END program]
|
||||
175
ortools/constraint_solver/samples/tsp_circuit_board.cc
Normal file
175
ortools/constraint_solver/samples/tsp_circuit_board.cc
Normal file
@@ -0,0 +1,175 @@
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// [START program]
|
||||
// [START import]
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#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"
|
||||
// [END import]
|
||||
|
||||
namespace operations_research {
|
||||
// [START distance_matrix]
|
||||
// @brief Generate distance matrix.
|
||||
std::vector<std::vector<int64>> GenerateDistanceMatrix(
|
||||
const std::vector<std::vector<int>>& locations) {
|
||||
std::vector<std::vector<int64>> distances = std::vector<std::vector<int64>>(
|
||||
locations.size(), std::vector<int64>(locations.size(), int64{0}));
|
||||
for (int fromNode = 0; fromNode < locations.size(); fromNode++) {
|
||||
for (int toNode = 0; toNode < locations.size(); toNode++) {
|
||||
if (fromNode != toNode)
|
||||
distances[fromNode][toNode] = static_cast<int64>(
|
||||
std::hypot((locations[toNode][0] - locations[fromNode][0]),
|
||||
(locations[toNode][1] - locations[fromNode][1])));
|
||||
}
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
// [END distance_matrix]
|
||||
|
||||
// [START solution_printer]
|
||||
//! @brief Print the solution
|
||||
//! @param[in] manager Index manager used.
|
||||
//! @param[in] routing Routing solver used.
|
||||
//! @param[in] solution Solution found by the solver.
|
||||
void PrintSolution(const RoutingIndexManager& manager,
|
||||
const RoutingModel& routing, const Assignment& solution) {
|
||||
LOG(INFO) << "Objective: " << solution.ObjectiveValue();
|
||||
// Inspect solution.
|
||||
int64 index = routing.Start(0);
|
||||
LOG(INFO) << "Route:";
|
||||
int64 distance{0};
|
||||
std::stringstream route;
|
||||
while (routing.IsEnd(index) == false) {
|
||||
route << manager.IndexToNode(index).value() << " -> ";
|
||||
int64 previous_index = index;
|
||||
index = solution.Value(routing.NextVar(index));
|
||||
distance += const_cast<RoutingModel&>(routing).GetArcCostForVehicle(
|
||||
previous_index, index, int64{0});
|
||||
}
|
||||
LOG(INFO) << route.str() << manager.IndexToNode(index).value();
|
||||
LOG(INFO) << "Route distance: " << distance << "miles";
|
||||
LOG(INFO) << "";
|
||||
LOG(INFO) << "Advanced usage:";
|
||||
LOG(INFO) << "Problem solved in " << routing.solver()->wall_time() << "ms";
|
||||
}
|
||||
// [END solution_printer]
|
||||
|
||||
void Tsp() {
|
||||
// Instantiate the data problem.
|
||||
// [START data]
|
||||
const std::vector<std::vector<int>> locations = {
|
||||
{288, 149}, {288, 129}, {270, 133}, {256, 141}, {256, 157}, {246, 157},
|
||||
{236, 169}, {228, 169}, {228, 161}, {220, 169}, {212, 169}, {204, 169},
|
||||
{196, 169}, {188, 169}, {196, 161}, {188, 145}, {172, 145}, {164, 145},
|
||||
{156, 145}, {148, 145}, {140, 145}, {148, 169}, {164, 169}, {172, 169},
|
||||
{156, 169}, {140, 169}, {132, 169}, {124, 169}, {116, 161}, {104, 153},
|
||||
{104, 161}, {104, 169}, {90, 165}, {80, 157}, {64, 157}, {64, 165},
|
||||
{56, 169}, {56, 161}, {56, 153}, {56, 145}, {56, 137}, {56, 129},
|
||||
{56, 121}, {40, 121}, {40, 129}, {40, 137}, {40, 145}, {40, 153},
|
||||
{40, 161}, {40, 169}, {32, 169}, {32, 161}, {32, 153}, {32, 145},
|
||||
{32, 137}, {32, 129}, {32, 121}, {32, 113}, {40, 113}, {56, 113},
|
||||
{56, 105}, {48, 99}, {40, 99}, {32, 97}, {32, 89}, {24, 89},
|
||||
{16, 97}, {16, 109}, {8, 109}, {8, 97}, {8, 89}, {8, 81},
|
||||
{8, 73}, {8, 65}, {8, 57}, {16, 57}, {8, 49}, {8, 41},
|
||||
{24, 45}, {32, 41}, {32, 49}, {32, 57}, {32, 65}, {32, 73},
|
||||
{32, 81}, {40, 83}, {40, 73}, {40, 63}, {40, 51}, {44, 43},
|
||||
{44, 35}, {44, 27}, {32, 25}, {24, 25}, {16, 25}, {16, 17},
|
||||
{24, 17}, {32, 17}, {44, 11}, {56, 9}, {56, 17}, {56, 25},
|
||||
{56, 33}, {56, 41}, {64, 41}, {72, 41}, {72, 49}, {56, 49},
|
||||
{48, 51}, {56, 57}, {56, 65}, {48, 63}, {48, 73}, {56, 73},
|
||||
{56, 81}, {48, 83}, {56, 89}, {56, 97}, {104, 97}, {104, 105},
|
||||
{104, 113}, {104, 121}, {104, 129}, {104, 137}, {104, 145}, {116, 145},
|
||||
{124, 145}, {132, 145}, {132, 137}, {140, 137}, {148, 137}, {156, 137},
|
||||
{164, 137}, {172, 125}, {172, 117}, {172, 109}, {172, 101}, {172, 93},
|
||||
{172, 85}, {180, 85}, {180, 77}, {180, 69}, {180, 61}, {180, 53},
|
||||
{172, 53}, {172, 61}, {172, 69}, {172, 77}, {164, 81}, {148, 85},
|
||||
{124, 85}, {124, 93}, {124, 109}, {124, 125}, {124, 117}, {124, 101},
|
||||
{104, 89}, {104, 81}, {104, 73}, {104, 65}, {104, 49}, {104, 41},
|
||||
{104, 33}, {104, 25}, {104, 17}, {92, 9}, {80, 9}, {72, 9},
|
||||
{64, 21}, {72, 25}, {80, 25}, {80, 25}, {80, 41}, {88, 49},
|
||||
{104, 57}, {124, 69}, {124, 77}, {132, 81}, {140, 65}, {132, 61},
|
||||
{124, 61}, {124, 53}, {124, 45}, {124, 37}, {124, 29}, {132, 21},
|
||||
{124, 21}, {120, 9}, {128, 9}, {136, 9}, {148, 9}, {162, 9},
|
||||
{156, 25}, {172, 21}, {180, 21}, {180, 29}, {172, 29}, {172, 37},
|
||||
{172, 45}, {180, 45}, {180, 37}, {188, 41}, {196, 49}, {204, 57},
|
||||
{212, 65}, {220, 73}, {228, 69}, {228, 77}, {236, 77}, {236, 69},
|
||||
{236, 61}, {228, 61}, {228, 53}, {236, 53}, {236, 45}, {228, 45},
|
||||
{228, 37}, {236, 37}, {236, 29}, {228, 29}, {228, 21}, {236, 21},
|
||||
{252, 21}, {260, 29}, {260, 37}, {260, 45}, {260, 53}, {260, 61},
|
||||
{260, 69}, {260, 77}, {276, 77}, {276, 69}, {276, 61}, {276, 53},
|
||||
{284, 53}, {284, 61}, {284, 69}, {284, 77}, {284, 85}, {284, 93},
|
||||
{284, 101}, {288, 109}, {280, 109}, {276, 101}, {276, 93}, {276, 85},
|
||||
{268, 97}, {260, 109}, {252, 101}, {260, 93}, {260, 85}, {236, 85},
|
||||
{228, 85}, {228, 93}, {236, 93}, {236, 101}, {228, 101}, {228, 109},
|
||||
{228, 117}, {228, 125}, {220, 125}, {212, 117}, {204, 109}, {196, 101},
|
||||
{188, 93}, {180, 93}, {180, 101}, {180, 109}, {180, 117}, {180, 125},
|
||||
{196, 145}, {204, 145}, {212, 145}, {220, 145}, {228, 145}, {236, 145},
|
||||
{246, 141}, {252, 125}, {260, 129}, {280, 133},
|
||||
};
|
||||
const int num_vehicles(1);
|
||||
const RoutingIndexManager::NodeIndex depot(0);
|
||||
// [END data]
|
||||
// Create Routing Index Manager
|
||||
// [START index_manager]
|
||||
RoutingIndexManager manager(locations.size(), num_vehicles, depot);
|
||||
// [END index_manager]
|
||||
|
||||
// Create Routing Model.
|
||||
// [START routing_model]
|
||||
RoutingModel routing(manager);
|
||||
// [END routing_model]
|
||||
|
||||
// [START transit_callback]
|
||||
const auto distance_matrix = GenerateDistanceMatrix(locations);
|
||||
const int transit_callback_index = routing.RegisterTransitCallback(
|
||||
[&distance_matrix, &manager](int64 from_index, int64 to_index) -> int64 {
|
||||
// Convert from routing variable Index to distance matrix NodeIndex.
|
||||
auto from_node = manager.IndexToNode(from_index).value();
|
||||
auto to_node = manager.IndexToNode(to_index).value();
|
||||
return distance_matrix[from_node][to_node];
|
||||
});
|
||||
// [End transit_callback]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START arc_cost]
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index);
|
||||
// [END arc_cost]
|
||||
|
||||
// Setting first solution heuristic.
|
||||
// [START parameters]
|
||||
RoutingSearchParameters searchParameters = DefaultRoutingSearchParameters();
|
||||
searchParameters.set_first_solution_strategy(
|
||||
FirstSolutionStrategy::PATH_CHEAPEST_ARC);
|
||||
// [END parameters]
|
||||
|
||||
// Solve the problem.
|
||||
// [START solve]
|
||||
const Assignment* solution = routing.SolveWithParameters(searchParameters);
|
||||
// [END solve]
|
||||
|
||||
// Print solution on console.
|
||||
// [START print_solution]
|
||||
PrintSolution(manager, routing, *solution);
|
||||
// [END print_solution]
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
operations_research::Tsp();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// [END program]
|
||||
410
ortools/constraint_solver/samples/tsp_circuit_board.py
Normal file
410
ortools/constraint_solver/samples/tsp_circuit_board.py
Normal file
@@ -0,0 +1,410 @@
|
||||
# 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
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# [START program]
|
||||
"""Simple travelling salesman problem on a circuit board."""
|
||||
|
||||
# [START import]
|
||||
from __future__ import print_function
|
||||
import math
|
||||
from ortools.constraint_solver import routing_enums_pb2
|
||||
from ortools.constraint_solver import pywrapcp
|
||||
# [END import]
|
||||
|
||||
|
||||
# [START data_model]
|
||||
def create_data_model():
|
||||
"""Stores the data for the problem."""
|
||||
data = {}
|
||||
# Locations in block units
|
||||
data['locations'] = [
|
||||
[288, 149],
|
||||
[288, 129],
|
||||
[270, 133],
|
||||
[256, 141],
|
||||
[256, 157],
|
||||
[246, 157],
|
||||
[236, 169],
|
||||
[228, 169],
|
||||
[228, 161],
|
||||
[220, 169],
|
||||
[212, 169],
|
||||
[204, 169],
|
||||
[196, 169],
|
||||
[188, 169],
|
||||
[196, 161],
|
||||
[188, 145],
|
||||
[172, 145],
|
||||
[164, 145],
|
||||
[156, 145],
|
||||
[148, 145],
|
||||
[140, 145],
|
||||
[148, 169],
|
||||
[164, 169],
|
||||
[172, 169],
|
||||
[156, 169],
|
||||
[140, 169],
|
||||
[132, 169],
|
||||
[124, 169],
|
||||
[116, 161],
|
||||
[104, 153],
|
||||
[104, 161],
|
||||
[104, 169],
|
||||
[90, 165],
|
||||
[80, 157],
|
||||
[64, 157],
|
||||
[64, 165],
|
||||
[56, 169],
|
||||
[56, 161],
|
||||
[56, 153],
|
||||
[56, 145],
|
||||
[56, 137],
|
||||
[56, 129],
|
||||
[56, 121],
|
||||
[40, 121],
|
||||
[40, 129],
|
||||
[40, 137],
|
||||
[40, 145],
|
||||
[40, 153],
|
||||
[40, 161],
|
||||
[40, 169],
|
||||
[32, 169],
|
||||
[32, 161],
|
||||
[32, 153],
|
||||
[32, 145],
|
||||
[32, 137],
|
||||
[32, 129],
|
||||
[32, 121],
|
||||
[32, 113],
|
||||
[40, 113],
|
||||
[56, 113],
|
||||
[56, 105],
|
||||
[48, 99],
|
||||
[40, 99],
|
||||
[32, 97],
|
||||
[32, 89],
|
||||
[24, 89],
|
||||
[16, 97],
|
||||
[16, 109],
|
||||
[8, 109],
|
||||
[8, 97],
|
||||
[8, 89],
|
||||
[8, 81],
|
||||
[8, 73],
|
||||
[8, 65],
|
||||
[8, 57],
|
||||
[16, 57],
|
||||
[8, 49],
|
||||
[8, 41],
|
||||
[24, 45],
|
||||
[32, 41],
|
||||
[32, 49],
|
||||
[32, 57],
|
||||
[32, 65],
|
||||
[32, 73],
|
||||
[32, 81],
|
||||
[40, 83],
|
||||
[40, 73],
|
||||
[40, 63],
|
||||
[40, 51],
|
||||
[44, 43],
|
||||
[44, 35],
|
||||
[44, 27],
|
||||
[32, 25],
|
||||
[24, 25],
|
||||
[16, 25],
|
||||
[16, 17],
|
||||
[24, 17],
|
||||
[32, 17],
|
||||
[44, 11],
|
||||
[56, 9],
|
||||
[56, 17],
|
||||
[56, 25],
|
||||
[56, 33],
|
||||
[56, 41],
|
||||
[64, 41],
|
||||
[72, 41],
|
||||
[72, 49],
|
||||
[56, 49],
|
||||
[48, 51],
|
||||
[56, 57],
|
||||
[56, 65],
|
||||
[48, 63],
|
||||
[48, 73],
|
||||
[56, 73],
|
||||
[56, 81],
|
||||
[48, 83],
|
||||
[56, 89],
|
||||
[56, 97],
|
||||
[104, 97],
|
||||
[104, 105],
|
||||
[104, 113],
|
||||
[104, 121],
|
||||
[104, 129],
|
||||
[104, 137],
|
||||
[104, 145],
|
||||
[116, 145],
|
||||
[124, 145],
|
||||
[132, 145],
|
||||
[132, 137],
|
||||
[140, 137],
|
||||
[148, 137],
|
||||
[156, 137],
|
||||
[164, 137],
|
||||
[172, 125],
|
||||
[172, 117],
|
||||
[172, 109],
|
||||
[172, 101],
|
||||
[172, 93],
|
||||
[172, 85],
|
||||
[180, 85],
|
||||
[180, 77],
|
||||
[180, 69],
|
||||
[180, 61],
|
||||
[180, 53],
|
||||
[172, 53],
|
||||
[172, 61],
|
||||
[172, 69],
|
||||
[172, 77],
|
||||
[164, 81],
|
||||
[148, 85],
|
||||
[124, 85],
|
||||
[124, 93],
|
||||
[124, 109],
|
||||
[124, 125],
|
||||
[124, 117],
|
||||
[124, 101],
|
||||
[104, 89],
|
||||
[104, 81],
|
||||
[104, 73],
|
||||
[104, 65],
|
||||
[104, 49],
|
||||
[104, 41],
|
||||
[104, 33],
|
||||
[104, 25],
|
||||
[104, 17],
|
||||
[92, 9],
|
||||
[80, 9],
|
||||
[72, 9],
|
||||
[64, 21],
|
||||
[72, 25],
|
||||
[80, 25],
|
||||
[80, 25],
|
||||
[80, 41],
|
||||
[88, 49],
|
||||
[104, 57],
|
||||
[124, 69],
|
||||
[124, 77],
|
||||
[132, 81],
|
||||
[140, 65],
|
||||
[132, 61],
|
||||
[124, 61],
|
||||
[124, 53],
|
||||
[124, 45],
|
||||
[124, 37],
|
||||
[124, 29],
|
||||
[132, 21],
|
||||
[124, 21],
|
||||
[120, 9],
|
||||
[128, 9],
|
||||
[136, 9],
|
||||
[148, 9],
|
||||
[162, 9],
|
||||
[156, 25],
|
||||
[172, 21],
|
||||
[180, 21],
|
||||
[180, 29],
|
||||
[172, 29],
|
||||
[172, 37],
|
||||
[172, 45],
|
||||
[180, 45],
|
||||
[180, 37],
|
||||
[188, 41],
|
||||
[196, 49],
|
||||
[204, 57],
|
||||
[212, 65],
|
||||
[220, 73],
|
||||
[228, 69],
|
||||
[228, 77],
|
||||
[236, 77],
|
||||
[236, 69],
|
||||
[236, 61],
|
||||
[228, 61],
|
||||
[228, 53],
|
||||
[236, 53],
|
||||
[236, 45],
|
||||
[228, 45],
|
||||
[228, 37],
|
||||
[236, 37],
|
||||
[236, 29],
|
||||
[228, 29],
|
||||
[228, 21],
|
||||
[236, 21],
|
||||
[252, 21],
|
||||
[260, 29],
|
||||
[260, 37],
|
||||
[260, 45],
|
||||
[260, 53],
|
||||
[260, 61],
|
||||
[260, 69],
|
||||
[260, 77],
|
||||
[276, 77],
|
||||
[276, 69],
|
||||
[276, 61],
|
||||
[276, 53],
|
||||
[284, 53],
|
||||
[284, 61],
|
||||
[284, 69],
|
||||
[284, 77],
|
||||
[284, 85],
|
||||
[284, 93],
|
||||
[284, 101],
|
||||
[288, 109],
|
||||
[280, 109],
|
||||
[276, 101],
|
||||
[276, 93],
|
||||
[276, 85],
|
||||
[268, 97],
|
||||
[260, 109],
|
||||
[252, 101],
|
||||
[260, 93],
|
||||
[260, 85],
|
||||
[236, 85],
|
||||
[228, 85],
|
||||
[228, 93],
|
||||
[236, 93],
|
||||
[236, 101],
|
||||
[228, 101],
|
||||
[228, 109],
|
||||
[228, 117],
|
||||
[228, 125],
|
||||
[220, 125],
|
||||
[212, 117],
|
||||
[204, 109],
|
||||
[196, 101],
|
||||
[188, 93],
|
||||
[180, 93],
|
||||
[180, 101],
|
||||
[180, 109],
|
||||
[180, 117],
|
||||
[180, 125],
|
||||
[196, 145],
|
||||
[204, 145],
|
||||
[212, 145],
|
||||
[220, 145],
|
||||
[228, 145],
|
||||
[236, 145],
|
||||
[246, 141],
|
||||
[252, 125],
|
||||
[260, 129],
|
||||
[280, 133],
|
||||
]
|
||||
data['num_vehicles'] = 1
|
||||
data['depot'] = 0
|
||||
return data
|
||||
# [END data_model]
|
||||
|
||||
|
||||
# [START distance_callback]
|
||||
def compute_euclidean_distance_matrix(data):
|
||||
"""Creates callback to return distance between points."""
|
||||
distances = {}
|
||||
for from_counter, from_node in enumerate(data['locations']):
|
||||
distances[from_counter] = {}
|
||||
for to_counter, to_node in enumerate(data['locations']):
|
||||
if from_counter == to_counter:
|
||||
distances[from_counter][to_counter] = 0
|
||||
else:
|
||||
# Euclidean distance
|
||||
distances[from_counter][to_counter] = (int(
|
||||
math.hypot((from_node[0] - to_node[0]),
|
||||
(from_node[1] - to_node[1]))))
|
||||
return distances
|
||||
# [END distance_callback]
|
||||
|
||||
|
||||
# [START solution_printer]
|
||||
def print_solution(manager, routing, assignment):
|
||||
"""Prints assignment on console."""
|
||||
print('Objective: {}'.format(assignment.ObjectiveValue()))
|
||||
index = routing.Start(0)
|
||||
plan_output = 'Route:\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))
|
||||
print(plan_output)
|
||||
plan_output += 'Objective: {}m\n'.format(route_distance)
|
||||
# [END solution_printer]
|
||||
|
||||
|
||||
def main():
|
||||
"""Entry point of the program."""
|
||||
# Instantiate the data problem.
|
||||
# [START data]
|
||||
data = create_data_model()
|
||||
# [END data]
|
||||
|
||||
# Create the routing index manager.
|
||||
# [START index_manager]
|
||||
manager = pywrapcp.RoutingIndexManager(
|
||||
len(data['locations']), data['num_vehicles'], data['depot'])
|
||||
# [END index_manager]
|
||||
|
||||
# Create Routing Model.
|
||||
# [START routing_model]
|
||||
routing = pywrapcp.RoutingModel(manager)
|
||||
# [END routing_model]
|
||||
|
||||
# [START transit_callback]
|
||||
distance_matrix = compute_euclidean_distance_matrix(data)
|
||||
|
||||
def distance_callback(from_index, to_index):
|
||||
"""Returns the distance between the two nodes."""
|
||||
# Convert from routing variable Index to distance matrix NodeIndex.
|
||||
from_node = manager.IndexToNode(from_index)
|
||||
to_node = manager.IndexToNode(to_index)
|
||||
return distance_matrix[from_node][to_node]
|
||||
|
||||
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
|
||||
# [END transit_callback]
|
||||
|
||||
# Define cost of each arc.
|
||||
# [START arc_cost]
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
|
||||
# [END arc_cost]
|
||||
|
||||
# Setting first solution heuristic.
|
||||
# [START parameters]
|
||||
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
|
||||
search_parameters.first_solution_strategy = (
|
||||
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
|
||||
# [END parameters]
|
||||
|
||||
# Solve the problem.
|
||||
# [START solve]
|
||||
assignment = routing.SolveWithParameters(search_parameters)
|
||||
# [END solve]
|
||||
|
||||
# Print solution on console.
|
||||
# [START print_solution]
|
||||
if assignment:
|
||||
print_solution(manager, routing, assignment)
|
||||
# [END print_solution]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
# [END program]
|
||||
124
ortools/constraint_solver/samples/tsp_cities.cc
Normal file
124
ortools/constraint_solver/samples/tsp_cities.cc
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// [START program]
|
||||
// [START import]
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#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"
|
||||
// [END import]
|
||||
|
||||
namespace operations_research {
|
||||
// [START solution_printer]
|
||||
//! @brief Print the solution.
|
||||
//! @param[in] manager Index manager used.
|
||||
//! @param[in] routing Routing solver used.
|
||||
//! @param[in] solution Solution found by the solver.
|
||||
void PrintSolution(const RoutingIndexManager& manager,
|
||||
const RoutingModel& routing, const Assignment& solution) {
|
||||
// Inspect solution.
|
||||
LOG(INFO) << "Objective: " << solution.ObjectiveValue() << " miles";
|
||||
int64 index = routing.Start(0);
|
||||
LOG(INFO) << "Route:";
|
||||
int64 distance{0};
|
||||
std::stringstream route;
|
||||
while (routing.IsEnd(index) == false) {
|
||||
route << manager.IndexToNode(index).value() << " -> ";
|
||||
int64 previous_index = index;
|
||||
index = solution.Value(routing.NextVar(index));
|
||||
distance += const_cast<RoutingModel&>(routing).GetArcCostForVehicle(
|
||||
previous_index, index, 0LL);
|
||||
}
|
||||
LOG(INFO) << route.str() << manager.IndexToNode(index).value();
|
||||
LOG(INFO) << "Route distance: " << distance << "miles";
|
||||
LOG(INFO) << "";
|
||||
LOG(INFO) << "Advanced usage:";
|
||||
LOG(INFO) << "Problem solved in " << routing.solver()->wall_time() << "ms";
|
||||
}
|
||||
// [END solution_printer]
|
||||
|
||||
void Tsp() {
|
||||
// Instantiate the data problem.
|
||||
// [START data]
|
||||
const std::vector<std::vector<int64>> distance_matrix = {
|
||||
{0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972},
|
||||
{2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579},
|
||||
{713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260},
|
||||
{1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987},
|
||||
{1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371},
|
||||
{1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999},
|
||||
{2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701},
|
||||
{213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099},
|
||||
{2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600},
|
||||
{875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162},
|
||||
{1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200},
|
||||
{2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504},
|
||||
{1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0},
|
||||
};
|
||||
const int num_vehicles(1);
|
||||
const RoutingIndexManager::NodeIndex depot(0);
|
||||
// [END data]
|
||||
|
||||
// Create Routing Index Manager
|
||||
// [START index_manager]
|
||||
RoutingIndexManager manager(distance_matrix.size(), num_vehicles, depot);
|
||||
// [END index_manager]
|
||||
|
||||
// Create Routing Model.
|
||||
// [START routing_model]
|
||||
RoutingModel routing(manager);
|
||||
// [END routing_model]
|
||||
|
||||
// [START transit_callback]
|
||||
const int transit_callback_index = routing.RegisterTransitCallback(
|
||||
[&distance_matrix, &manager](int64 from_index, int64 to_index) -> int64 {
|
||||
// Convert from routing variable Index to distance matrix NodeIndex.
|
||||
auto from_node = manager.IndexToNode(from_index).value();
|
||||
auto to_node = manager.IndexToNode(to_index).value();
|
||||
return distance_matrix[from_node][to_node];
|
||||
});
|
||||
// [END transit_callback]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START arc_cost]
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index);
|
||||
// [END arc_cost]
|
||||
|
||||
// Setting first solution heuristic.
|
||||
// [START parameters]
|
||||
RoutingSearchParameters searchParameters = DefaultRoutingSearchParameters();
|
||||
searchParameters.set_first_solution_strategy(
|
||||
FirstSolutionStrategy::PATH_CHEAPEST_ARC);
|
||||
// [END parameters]
|
||||
|
||||
// Solve the problem.
|
||||
// [START solve]
|
||||
const Assignment* solution = routing.SolveWithParameters(searchParameters);
|
||||
// [END solve]
|
||||
|
||||
// Print solution on console.
|
||||
// [START print_solution]
|
||||
PrintSolution(manager, routing, *solution);
|
||||
// [END print_solution]
|
||||
}
|
||||
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
operations_research::Tsp();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// [END program]
|
||||
131
ortools/constraint_solver/samples/tsp_cities.py
Normal file
131
ortools/constraint_solver/samples/tsp_cities.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# 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
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# [START program]
|
||||
"""Simple travelling salesman problem between cities."""
|
||||
|
||||
# [START import]
|
||||
from __future__ import print_function
|
||||
from ortools.constraint_solver import routing_enums_pb2
|
||||
from ortools.constraint_solver import pywrapcp
|
||||
# [END import]
|
||||
|
||||
|
||||
# [START data_model]
|
||||
def create_data_model():
|
||||
"""Stores the data for the problem."""
|
||||
data = {}
|
||||
data['distance_matrix'] = [
|
||||
[
|
||||
0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145,
|
||||
1972
|
||||
],
|
||||
[2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579],
|
||||
[713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260],
|
||||
[1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987],
|
||||
[1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371],
|
||||
[1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999],
|
||||
[
|
||||
2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114,
|
||||
701
|
||||
],
|
||||
[
|
||||
213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300,
|
||||
2099
|
||||
],
|
||||
[2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600],
|
||||
[875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162],
|
||||
[1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200],
|
||||
[2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504],
|
||||
[1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0]
|
||||
]
|
||||
data['num_vehicles'] = 1
|
||||
data['depot'] = 0
|
||||
return data
|
||||
# [END data_model]
|
||||
|
||||
|
||||
# [START solution_printer]
|
||||
def print_solution(manager, routing, assignment):
|
||||
"""Prints assignment on console."""
|
||||
print('Objective: {} miles'.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))
|
||||
print(plan_output)
|
||||
plan_output += 'Route distance: {}miles\n'.format(route_distance)
|
||||
# [END solution_printer]
|
||||
|
||||
|
||||
def main():
|
||||
"""Entry point of the program."""
|
||||
# Instantiate the data problem.
|
||||
# [START data]
|
||||
data = create_data_model()
|
||||
# [END data]
|
||||
|
||||
# Create the routing index manager.
|
||||
# [START index_manager]
|
||||
manager = pywrapcp.RoutingIndexManager(
|
||||
len(data['distance_matrix']), data['num_vehicles'], data['depot'])
|
||||
# [END index_manager]
|
||||
|
||||
# Create Routing Model.
|
||||
# [START routing_model]
|
||||
routing = pywrapcp.RoutingModel(manager)
|
||||
|
||||
# [END routing_model]
|
||||
|
||||
# [START transit_callback]
|
||||
def distance_callback(from_index, to_index):
|
||||
"""Returns the distance between the two nodes."""
|
||||
# Convert from routing variable Index to distance matrix NodeIndex.
|
||||
from_node = manager.IndexToNode(from_index)
|
||||
to_node = manager.IndexToNode(to_index)
|
||||
return data['distance_matrix'][from_node][to_node]
|
||||
|
||||
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
|
||||
# [END transit_callback]
|
||||
|
||||
# Define cost of each arc.
|
||||
# [START arc_cost]
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
|
||||
# [END arc_cost]
|
||||
|
||||
# Setting first solution heuristic.
|
||||
# [START parameters]
|
||||
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
|
||||
search_parameters.first_solution_strategy = (
|
||||
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
|
||||
# [END parameters]
|
||||
|
||||
# Solve the problem.
|
||||
# [START solve]
|
||||
assignment = routing.SolveWithParameters(search_parameters)
|
||||
# [END solve]
|
||||
|
||||
# Print solution on console.
|
||||
# [START print_solution]
|
||||
if assignment:
|
||||
print_solution(manager, routing, assignment)
|
||||
# [END print_solution]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
# [END program]
|
||||
Reference in New Issue
Block a user