diff --git a/makefiles/Makefile.dotnet.mk b/makefiles/Makefile.dotnet.mk
index d3a6fc4b46..ab98885cd2 100644
--- a/makefiles/Makefile.dotnet.mk
+++ b/makefiles/Makefile.dotnet.mk
@@ -522,7 +522,13 @@ 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/TspDistanceMatrix.cs
$(MAKE) run SOURCE=ortools/constraint_solver/samples/Vrp.cs
+ $(MAKE) run SOURCE=ortools/constraint_solver/samples/VrpCapacity.cs
+ $(MAKE) run SOURCE=ortools/constraint_solver/samples/VrpDropNodes.cs
+ $(MAKE) run SOURCE=ortools/constraint_solver/samples/VrpGlobalSpan.cs
+ $(MAKE) run SOURCE=ortools/constraint_solver/samples/VrpStartsEnds.cs
+ $(MAKE) run SOURCE=ortools/constraint_solver/samples/VrpTimeWindows.cs
.PHONY: test_dotnet_graph_samples # Build and Run all .Net LP Samples (located in ortools/graph/samples)
test_dotnet_graph_samples: ;
diff --git a/ortools/constraint_solver/samples/SimpleRoutingProgram.cs b/ortools/constraint_solver/samples/SimpleRoutingProgram.cs
index 89bd35629a..7973eaba7a 100644
--- a/ortools/constraint_solver/samples/SimpleRoutingProgram.cs
+++ b/ortools/constraint_solver/samples/SimpleRoutingProgram.cs
@@ -21,10 +21,7 @@ using Google.OrTools.ConstraintSolver;
/// This is a sample using the routing library .Net wrapper.
///
public class SimpleRoutingProgram {
- ///
- /// Solves the current routing problem.
- ///
- static void Solve() {
+ public static void Main(String[] args) {
// Instantiate the data problem.
// [START data]
const int num_location = 5;
@@ -81,8 +78,5 @@ public class SimpleRoutingProgram {
Console.WriteLine("Distance of the route: {0}m", route_distance);
// [END print_solution]
}
-
- public static void Main(String[] args) {
- Solve();
- }
}
+// [END program]
diff --git a/ortools/constraint_solver/samples/Tsp.cs b/ortools/constraint_solver/samples/Tsp.cs
index 8f9087fe6d..ac311dfe02 100644
--- a/ortools/constraint_solver/samples/Tsp.cs
+++ b/ortools/constraint_solver/samples/Tsp.cs
@@ -1,4 +1,4 @@
-// Copyright 2018 Google
+// Copyright 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
@@ -11,22 +11,23 @@
// 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]
///
-/// This is a sample using the routing library .Net wrapper to solve a TSP
-/// problem.
+/// Minimal TSP.
/// A description of the problem can be found here:
/// http://en.wikipedia.org/wiki/Travelling_salesman_problem.
///
-public class TSP {
- class DataProblem {
- private int[,] locations_;
-
+public class Tsp {
+ // [START data_model]
+ class DataModel {
// Constructor:
- public DataProblem() {
+ public DataModel() {
locations_ = new int[,] {
{4, 4},
{2, 0}, {8, 0},
@@ -44,38 +45,36 @@ public class TSP {
locations_[i, 1] *= 80;
}
}
-
public ref readonly int[,] GetLocations() { return ref locations_;}
public int GetVehicleNumber() { return 1;}
public int GetDepot() { return 0;}
+
+ private int[,] locations_;
};
+ // [END data_model]
-
+ // [START manhattan_distance]
///
/// Manhattan distance implemented as a callback. It uses an array of
/// positions and computes the Manhattan distance between the two
/// positions of two different indices.
///
class ManhattanDistance : LongLongToLong {
- private int[,] distances_;
- private RoutingIndexManager manager_;
-
- public ManhattanDistance(in DataProblem data,
- in RoutingIndexManager manager) {
+ public ManhattanDistance(
+ in DataModel data,
+ in RoutingIndexManager manager) {
// precompute distance between location to have distance callback in O(1)
int locationNumber = data.GetLocations().GetLength(0);
- distances_ = new int[locationNumber, locationNumber];
- manager_ = manager;
+ distancesMatrix_ = new long[locationNumber, locationNumber];
+ indexManager_ = manager;
for (int fromNode = 0; fromNode < locationNumber; fromNode++) {
for (int toNode = 0; toNode < locationNumber; toNode++) {
if (fromNode == toNode)
- distances_[fromNode, toNode] = 0;
+ distancesMatrix_[fromNode, toNode] = 0;
else
- distances_[fromNode, toNode] =
- Math.Abs(data.GetLocations()[toNode, 0] -
- data.GetLocations()[fromNode, 0]) +
- Math.Abs(data.GetLocations()[toNode, 1] -
- data.GetLocations()[fromNode, 1]);
+ distancesMatrix_[fromNode, toNode] =
+ Math.Abs(data.GetLocations()[toNode, 0] - data.GetLocations()[fromNode, 0]) +
+ Math.Abs(data.GetLocations()[toNode, 1] - data.GetLocations()[fromNode, 1]);
}
}
}
@@ -84,67 +83,84 @@ public class TSP {
/// Returns the manhattan distance between the two nodes
///
public override long Run(long FromIndex, long ToIndex) {
- int FromNode = manager_.IndexToNode(FromIndex);
- int ToNode = manager_.IndexToNode(ToIndex);
- return distances_[FromNode, ToNode];
+ int FromNode = indexManager_.IndexToNode(FromIndex);
+ int ToNode = indexManager_.IndexToNode(ToIndex);
+ return distancesMatrix_[FromNode, ToNode];
}
+ private long[,] distancesMatrix_;
+ private RoutingIndexManager indexManager_;
};
+ // [END manhattan_distance]
+ // [START solution_printer]
///
- /// Print the solution
+ /// Print the solution.
///
static void PrintSolution(
- in DataProblem data,
in RoutingModel routing,
in RoutingIndexManager manager,
in Assignment solution) {
Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
// Inspect solution.
- var index = routing.Start(0);
Console.WriteLine("Route for Vehicle 0:");
- long distance = 0;
+ 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));
- distance += routing.GetArcCostForVehicle(previousIndex, index, 0);
+ routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
}
Console.WriteLine("{0}", manager.IndexToNode((int)index));
- Console.WriteLine("Distance of the route: {0}m", distance);
+ Console.WriteLine("Distance of the route: {0}m", routeDistance);
}
+ // [END solution_printer]
- ///
- /// Solves the current routing problem.
- ///
- static void Solve() {
+ public static void Main(String[] args) {
// Instantiate the data problem.
- DataProblem data = new DataProblem();
+ // [START data]
+ DataModel data = new DataModel();
+ // [END data]
- // Create Routing Model
+ // Create Routing Index Manager
+ // [START index_manager]
RoutingIndexManager manager = new RoutingIndexManager(
data.GetLocations().GetLength(0),
data.GetVehicleNumber(),
data.GetDepot());
- RoutingModel routing = new RoutingModel(manager);
+ // [END index_manager]
- // Define weight of each edge
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
LongLongToLong distanceEvaluator = new ManhattanDistance(data, manager);
//protect callbacks from the GC
GC.KeepAlive(distanceEvaluator);
- routing.SetArcCostEvaluatorOfAllVehicles(
- routing.RegisterTransitCallback(distanceEvaluator));
+ int transitCostIndex = routing.RegisterTransitCallback(distanceEvaluator);
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [END arc_cost]
- // Setting first solution heuristic (cheapest addition).
+ // Setting first solution heuristic.
+ // [START parameters]
RoutingSearchParameters searchParameters =
- operations_research_constraint_solver.DefaultRoutingSearchParameters();
+ operations_research_constraint_solver.DefaultRoutingSearchParameters();
searchParameters.FirstSolutionStrategy =
- FirstSolutionStrategy.Types.Value.PathCheapestArc;
+ FirstSolutionStrategy.Types.Value.PathCheapestArc;
+ // [END parameters]
+ // Solve the problem.
+ // [START solve]
Assignment solution = routing.SolveWithParameters(searchParameters);
- PrintSolution(data, routing, manager, solution);
- }
+ // [END solve]
- public static void Main(String[] args) {
- Solve();
+ // Print solution on console.
+ // [START print_solution]
+ PrintSolution(routing, manager, solution);
+ // [END print_solution]
}
}
+// [END program]
diff --git a/ortools/constraint_solver/samples/Tsp.csproj b/ortools/constraint_solver/samples/Tsp.csproj
index e8c4ced7b5..b9933418e9 100644
--- a/ortools/constraint_solver/samples/Tsp.csproj
+++ b/ortools/constraint_solver/samples/Tsp.csproj
@@ -15,6 +15,6 @@
-
+
diff --git a/ortools/constraint_solver/samples/TspDistanceMatrix.cs b/ortools/constraint_solver/samples/TspDistanceMatrix.cs
new file mode 100644
index 0000000000..7ea80687b9
--- /dev/null
+++ b/ortools/constraint_solver/samples/TspDistanceMatrix.cs
@@ -0,0 +1,130 @@
+// Copyright 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]
+
+///
+/// Minimal TSP using distance matrix.
+///
+public class TspDistanceMatrix {
+ // [START data_model]
+ class DataModel {
+ // Constructor:
+ public DataModel() {
+ distancesMatrix_ = new long[,] {
+ {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
+ {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
+ {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
+ {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
+ {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
+ {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
+ {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
+ {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
+ {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
+ {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
+ {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
+ {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
+ {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
+ {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
+ {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
+ {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
+ {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
+ };
+ }
+ public ref readonly long[,] GetDistanceMatrix() { return ref distancesMatrix_;}
+ public int GetVehicleNumber() { return 1;}
+ public int GetDepot() { return 0;}
+
+ private long[,] distancesMatrix_;
+ };
+ // [END data_model]
+
+ // [START solution_printer]
+ ///
+ /// Print the solution.
+ ///
+ static void PrintSolution(
+ in RoutingModel routing,
+ in RoutingIndexManager manager,
+ in Assignment solution) {
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ // Inspect solution.
+ Console.WriteLine("Route for Vehicle 0:");
+ 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("Distance of the route: {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.GetDistanceMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetDepot());
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetDistanceMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [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]
diff --git a/ortools/constraint_solver/samples/TspDistanceMatrix.csproj b/ortools/constraint_solver/samples/TspDistanceMatrix.csproj
new file mode 100644
index 0000000000..c938f27b96
--- /dev/null
+++ b/ortools/constraint_solver/samples/TspDistanceMatrix.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ 7.2
+ netcoreapp2.1
+ false
+ ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json
+
+
+
+ full
+ true
+ true
+
+
+
+
+
+
+
diff --git a/ortools/constraint_solver/samples/Vrp.cs b/ortools/constraint_solver/samples/Vrp.cs
index d0eb3a61a9..f24c6c0ea6 100644
--- a/ortools/constraint_solver/samples/Vrp.cs
+++ b/ortools/constraint_solver/samples/Vrp.cs
@@ -1,4 +1,4 @@
-// Copyright 2018 Google
+// Copyright 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
@@ -11,171 +11,126 @@
// 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]
///
-/// This is a sample using the routing library .Net wrapper to solve a VRP problem.
-/// A description of the problem can be found here:
-/// http://en.wikipedia.org/wiki/Vehicle_routing_problem.
+/// Minimal TSP using distance matrix.
///
-public class VRP {
- class DataProblem {
- private int[,] locations_;
-
+public class Vrp {
+ // [START data_model]
+ class DataModel {
// Constructor:
- public DataProblem() {
- locations_ = new int[,] {
- {4, 4},
- {2, 0}, {8, 0},
- {0, 1}, {1, 1},
- {5, 2}, {7, 2},
- {3, 3}, {6, 3},
- {5, 5}, {8, 5},
- {1, 6}, {2, 6},
- {3, 7}, {6, 7},
- {0, 8}, {7, 8}
+ public DataModel() {
+ distancesMatrix_ = new long[,] {
+ {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
+ {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
+ {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
+ {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
+ {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
+ {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
+ {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
+ {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
+ {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
+ {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
+ {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
+ {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
+ {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
+ {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
+ {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
+ {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
+ {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
};
-
- // Compute locations in meters using the block dimension defined as follow
- // Manhattan average block: 750ft x 264ft -> 228m x 80m
- // here we use: 114m x 80m city block
- // src: https://nyti.ms/2GDoRIe "NY Times: Know Your distance"
- int[] cityBlock = {228/2, 80};
- for (int i=0; i < locations_.GetLength(0); i++) {
- locations_[i, 0] = locations_[i, 0] * cityBlock[0];
- locations_[i, 1] = locations_[i, 1] * cityBlock[1];
- }
}
-
+ public ref readonly long[,] GetDistanceMatrix() { return ref distancesMatrix_;}
public int GetVehicleNumber() { return 4;}
- public ref readonly int[,] GetLocations() { return ref locations_;}
- public int GetLocationNumber() { return locations_.GetLength(0);}
public int GetDepot() { return 0;}
+
+ private long[,] distancesMatrix_;
};
+ // [END data_model]
-
+ // [START solution_printer]
///
- /// Manhattan distance implemented as a callback. It uses an array of
- /// positions and computes the Manhattan distance between the two
- /// positions of two different indices.
- ///
- class ManhattanDistance : LongLongToLong {
- private int[,] distances_;
- private RoutingIndexManager manager_;
-
- public ManhattanDistance(in DataProblem data,
- in RoutingIndexManager manager) {
- // precompute distance between location to have distance callback in O(1)
- distances_ = new int[data.GetLocationNumber(), data.GetLocationNumber()];
- manager_ = manager;
- for (int fromNode = 0; fromNode < data.GetLocationNumber(); fromNode++) {
- for (int toNode = 0; toNode < data.GetLocationNumber(); toNode++) {
- if (fromNode == toNode)
- distances_[fromNode, toNode] = 0;
- else
- distances_[fromNode, toNode] =
- Math.Abs(data.GetLocations()[toNode, 0] -
- data.GetLocations()[fromNode, 0]) +
- Math.Abs(data.GetLocations()[toNode, 1] -
- data.GetLocations()[fromNode, 1]);
- }
- }
- }
-
- ///
- /// Returns the manhattan distance between the two nodes
- ///
- public override long Run(long FromIndex, long ToIndex) {
- int FromNode = manager_.IndexToNode(FromIndex);
- int ToNode = manager_.IndexToNode(ToIndex);
- return distances_[FromNode, ToNode];
- }
- };
-
- ///
- /// Add distance Dimension
- ///
- static void AddDistanceDimension(
- in DataProblem data,
- in RoutingModel routing,
- in int distance_index) {
- String distance = "Distance";
- routing.AddDimension(
- distance_index,
- 0, // null slack
- 3000, // maximum distance per vehicle
- true, // start cumul to zero
- distance);
- RoutingDimension distanceDimension = routing.GetDimensionOrDie(distance);
- // Try to minimize the max distance among vehicles.
- // /!\ It doesn't mean the standard deviation is minimized
- distanceDimension.SetGlobalSpanCostCoefficient(100);
- }
-
- ///
- /// Print the solution
+ /// Print the solution.
///
static void PrintSolution(
- in DataProblem data,
+ in DataModel data,
in RoutingModel routing,
in RoutingIndexManager manager,
in Assignment solution) {
Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
// Inspect solution.
long totalDistance = 0;
- for (int i=0; i < data.GetVehicleNumber(); ++i) {
- Console.WriteLine("Route for Vehicle " + i + ":");
- long distance = 0;
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ Console.WriteLine("Route for Vehicle {0}:", i);
+ long routeDistance = 0;
var index = routing.Start(i);
while (routing.IsEnd(index) == false) {
Console.Write("{0} -> ", manager.IndexToNode((int)index));
var previousIndex = index;
index = solution.Value(routing.NextVar(index));
- distance += routing.GetArcCostForVehicle(previousIndex, index, i);
+ routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
}
Console.WriteLine("{0}", manager.IndexToNode((int)index));
- Console.WriteLine("Distance of the route: {0}m", distance);
- totalDistance += distance;
+ Console.WriteLine("Distance of the route: {0}m", routeDistance);
+ totalDistance += routeDistance;
}
Console.WriteLine("Total Distance of all routes: {0}m", totalDistance);
}
-
- ///
- /// Solves the current routing problem.
- ///
- static void Solve() {
- // Instantiate the data problem.
- DataProblem data = new DataProblem();
-
- // Create Routing Model
- RoutingIndexManager manager = new RoutingIndexManager(
- data.GetLocationNumber(),
- data.GetVehicleNumber(),
- data.GetDepot());
- RoutingModel routing = new RoutingModel(manager);
-
- // Define weight of each edge
- LongLongToLong distanceEvaluator = new ManhattanDistance(data, manager);
- //protect callbacks from the GC
- GC.KeepAlive(distanceEvaluator);
- int distance_index = routing.RegisterTransitCallback(distanceEvaluator);
- routing.SetArcCostEvaluatorOfAllVehicles(distance_index);
-
- AddDistanceDimension(data, routing, distance_index);
-
- // Setting first solution heuristic (cheapest addition).
- RoutingSearchParameters searchParameters =
- operations_research_constraint_solver.DefaultRoutingSearchParameters();
- searchParameters.FirstSolutionStrategy =
- FirstSolutionStrategy.Types.Value.PathCheapestArc;
-
- Assignment solution = routing.SolveWithParameters(searchParameters);
- PrintSolution(data, routing, manager, solution);
- }
+ // [END solution_printer]
public static void Main(String[] args) {
- Solve();
+ // Instantiate the data problem.
+ // [START data]
+ DataModel data = new DataModel();
+ // [END data]
+
+ // Create Routing Index Manager
+ // [START index_manager]
+ RoutingIndexManager manager = new RoutingIndexManager(
+ data.GetDistanceMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetDepot());
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetDistanceMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [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(data, routing, manager, solution);
+ // [END print_solution]
}
}
+// [END program]
diff --git a/ortools/constraint_solver/samples/Vrp.csproj b/ortools/constraint_solver/samples/Vrp.csproj
index fb99f95278..52034cc441 100644
--- a/ortools/constraint_solver/samples/Vrp.csproj
+++ b/ortools/constraint_solver/samples/Vrp.csproj
@@ -15,6 +15,6 @@
-
+
diff --git a/ortools/constraint_solver/samples/VrpCapacity.cs b/ortools/constraint_solver/samples/VrpCapacity.cs
new file mode 100644
index 0000000000..b0967767cd
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpCapacity.cs
@@ -0,0 +1,162 @@
+// Copyright 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]
+
+///
+/// Minimal TSP using distance matrix.
+///
+public class VrpCapacity {
+ // [START data_model]
+ class DataModel {
+ // Constructor:
+ public DataModel() {
+ distancesMatrix_ = new long[,] {
+ {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
+ {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
+ {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
+ {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
+ {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
+ {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
+ {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
+ {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
+ {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
+ {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
+ {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
+ {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
+ {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
+ {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
+ {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
+ {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
+ {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
+ };
+ demands_ = new long[] {0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8};
+ vehicleCapacities_ = new long[] {15, 15, 15, 15};
+ }
+ public ref readonly long[,] GetDistanceMatrix() { return ref distancesMatrix_;}
+ public ref readonly long[] GetDemands() { return ref demands_;}
+ public int GetVehicleNumber() { return 4;}
+ public ref readonly long[] GetVehicleCapacities() { return ref vehicleCapacities_;}
+ public int GetDepot() { return 0;}
+
+ private long[,] distancesMatrix_;
+ private long[] demands_;
+ private long[] vehicleCapacities_;
+ };
+ // [END data_model]
+
+ // [START solution_printer]
+ ///
+ /// Print the solution.
+ ///
+ static void PrintSolution(
+ in DataModel data,
+ in RoutingModel routing,
+ in RoutingIndexManager manager,
+ in Assignment solution) {
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ // Inspect solution.
+ long totalDistance = 0;
+ long totalLoad = 0;
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ Console.WriteLine("Route for Vehicle {0}:", i);
+ long routeDistance = 0;
+ long routeLoad = 0;
+ var index = routing.Start(i);
+ while (routing.IsEnd(index) == false) {
+ long nodeIndex = manager.IndexToNode(index);
+ routeLoad += data.GetDemands()[nodeIndex];
+ Console.Write("{0} Load({1}) -> ", nodeIndex, routeLoad);
+ var previousIndex = index;
+ index = solution.Value(routing.NextVar(index));
+ routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
+ }
+ Console.WriteLine("{0}", manager.IndexToNode((int)index));
+ Console.WriteLine("Distance of the route: {0}m", routeDistance);
+ totalDistance += routeDistance;
+ totalLoad += routeLoad;
+ }
+ Console.WriteLine("Total Distance of all routes: {0}m", totalDistance);
+ Console.WriteLine("Total Load of all routes: {0}m", totalLoad);
+ }
+ // [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.GetDistanceMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetDepot());
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetDistanceMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [END arc_cost]
+
+ // Add Capacity constraint.
+ // [START capacity_constraint]
+ int demandCostIndex = routing.RegisterUnaryTransitCallback(
+ (long fromIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ return data.GetDemands()[fromNode]; }
+ );
+ routing.AddDimensionWithVehicleCapacity(
+ demandCostIndex, 0, // null capacity slack
+ data.GetVehicleCapacities(), // vehicle maximum capacities
+ true, // start cumul to zero
+ "Capacity");
+ // [END capacity_constraint]
+
+ // 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(data, routing, manager, solution);
+ // [END print_solution]
+ }
+}
+// [END program]
diff --git a/ortools/constraint_solver/samples/VrpCapacity.csproj b/ortools/constraint_solver/samples/VrpCapacity.csproj
new file mode 100644
index 0000000000..1f67cee865
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpCapacity.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ 7.2
+ netcoreapp2.1
+ false
+ ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json
+
+
+
+ full
+ true
+ true
+
+
+
+
+
+
+
diff --git a/ortools/constraint_solver/samples/VrpDropNodes.cs b/ortools/constraint_solver/samples/VrpDropNodes.cs
new file mode 100644
index 0000000000..e00540bb2e
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpDropNodes.cs
@@ -0,0 +1,180 @@
+// Copyright 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]
+
+///
+/// Minimal Vrp with drop nodes.
+///
+public class VrpDropNodes {
+ // [START data_model]
+ class DataModel {
+ // Constructor:
+ public DataModel() {
+ distancesMatrix_ = new long[,] {
+ {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
+ {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
+ {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
+ {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
+ {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
+ {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
+ {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
+ {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
+ {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
+ {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
+ {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
+ {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
+ {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
+ {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
+ {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
+ {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
+ {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
+ };
+ demands_ = new long[] {0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8};
+ vehicleCapacities_ = new long[] {15, 15, 15, 15};
+ }
+ public ref readonly long[,] GetDistanceMatrix() { return ref distancesMatrix_;}
+ public ref readonly long[] GetDemands() { return ref demands_;}
+ public int GetVehicleNumber() { return 4;}
+ public ref readonly long[] GetVehicleCapacities() { return ref vehicleCapacities_;}
+ public int GetDepot() { return 0;}
+
+ private long[,] distancesMatrix_;
+ private long[] demands_;
+ private long[] vehicleCapacities_;
+ };
+ // [END data_model]
+
+ // [START solution_printer]
+ ///
+ /// Print the solution.
+ ///
+ static void PrintSolution(
+ in DataModel data,
+ in RoutingModel routing,
+ in RoutingIndexManager manager,
+ in Assignment solution) {
+ // Solution cost.
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ // Display dropped nodes.
+ string droppedNodes = "Dropped nodes:";
+ for (int index = 0; index < routing.Size(); ++index) {
+ if (routing.IsStart(index) || routing.IsEnd(index)) {
+ continue;
+ }
+ if (solution.Value(routing.NextVar(index)) == index) {
+ droppedNodes += " " + manager.IndexToNode(index);
+ }
+ }
+ Console.WriteLine("{0}", droppedNodes);
+ // Inspect solution.
+ long totalDistance = 0;
+ long totalLoad = 0;
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ Console.WriteLine("Route for Vehicle {0}:", i);
+ long routeDistance = 0;
+ long routeLoad = 0;
+ var index = routing.Start(i);
+ while (routing.IsEnd(index) == false) {
+ long nodeIndex = manager.IndexToNode(index);
+ routeLoad += data.GetDemands()[nodeIndex];
+ Console.Write("{0} Load({1}) -> ", nodeIndex, routeLoad);
+ var previousIndex = index;
+ index = solution.Value(routing.NextVar(index));
+ routeDistance += routing.GetArcCostForVehicle(previousIndex, index, 0);
+ }
+ Console.WriteLine("{0}", manager.IndexToNode((int)index));
+ Console.WriteLine("Distance of the route: {0}m", routeDistance);
+ totalDistance += routeDistance;
+ totalLoad += routeLoad;
+ }
+ Console.WriteLine("Total Distance of all routes: {0}m", totalDistance);
+ Console.WriteLine("Total Load of all routes: {0}m", totalLoad);
+ }
+ // [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.GetDistanceMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetDepot());
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetDistanceMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [END arc_cost]
+
+ // Add Capacity constraint.
+ // [START capacity_constraint]
+ int demandCostIndex = routing.RegisterUnaryTransitCallback(
+ (long fromIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ return data.GetDemands()[fromNode]; }
+ );
+ routing.AddDimensionWithVehicleCapacity(
+ demandCostIndex, 0, // null capacity slack
+ data.GetVehicleCapacities(), // vehicle maximum capacities
+ true, // start cumul to zero
+ "Capacity");
+ // Allow to drop nodes.
+ long penalty = 1000;
+ for (int i = 1; i < data.GetDistanceMatrix().GetLength(0); ++i) {
+ routing.AddDisjunction(
+ new long[] {manager.NodeToIndex(i)}, penalty);
+ }
+ // [END capacity_constraint]
+
+ // 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(data, routing, manager, solution);
+ // [END print_solution]
+ }
+}
+// [END program]
diff --git a/ortools/constraint_solver/samples/VrpDropNodes.csproj b/ortools/constraint_solver/samples/VrpDropNodes.csproj
new file mode 100644
index 0000000000..6fb5ecd6b3
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpDropNodes.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ 7.2
+ netcoreapp2.1
+ false
+ ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json
+
+
+
+ full
+ true
+ true
+
+
+
+
+
+
+
diff --git a/ortools/constraint_solver/samples/VrpGlobalSpan.cs b/ortools/constraint_solver/samples/VrpGlobalSpan.cs
new file mode 100644
index 0000000000..c85931c974
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpGlobalSpan.cs
@@ -0,0 +1,146 @@
+// Copyright 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]
+
+///
+/// Minimal TSP using distance matrix.
+///
+public class VrpGlobalSpan {
+ // [START data_model]
+ class DataModel {
+ // Constructor:
+ public DataModel() {
+ distancesMatrix_ = new long[,] {
+ {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
+ {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
+ {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
+ {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
+ {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
+ {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
+ {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
+ {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
+ {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
+ {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
+ {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
+ {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
+ {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
+ {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
+ {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
+ {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
+ {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
+ };
+ }
+ public ref readonly long[,] GetDistanceMatrix() { return ref distancesMatrix_;}
+ public int GetVehicleNumber() { return 4;}
+ public int GetDepot() { return 0;}
+
+ private long[,] distancesMatrix_;
+ };
+ // [END data_model]
+
+ // [START solution_printer]
+ ///
+ /// Print the solution.
+ ///
+ static void PrintSolution(
+ in DataModel data,
+ in RoutingModel routing,
+ in RoutingIndexManager manager,
+ in Assignment solution) {
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ // Inspect solution.
+ long totalDistance = 0;
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ Console.WriteLine("Route for Vehicle {0}:", i);
+ long routeDistance = 0;
+ var index = routing.Start(i);
+ 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("Distance of the route: {0}m", routeDistance);
+ totalDistance += routeDistance;
+ }
+ Console.WriteLine("Total Distance of all routes: {0}m", totalDistance);
+ }
+ // [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.GetDistanceMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetDepot());
+
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetDistanceMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [END arc_cost]
+
+ // Add Distance constraint.
+ // [START distance_constraint]
+ routing.AddDimension(transitCostIndex, 0, 3000,
+ true, // start cumul to zero
+ "Distance");
+ RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
+ distanceDimension.SetGlobalSpanCostCoefficient(100);
+ // [END distance_constraint]
+
+ // 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(data, routing, manager, solution);
+ // [END print_solution]
+ }
+}
+// [END program]
diff --git a/ortools/constraint_solver/samples/VrpGlobalSpan.csproj b/ortools/constraint_solver/samples/VrpGlobalSpan.csproj
new file mode 100644
index 0000000000..2059dd24bc
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpGlobalSpan.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ 7.2
+ netcoreapp2.1
+ false
+ ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json
+
+
+
+ full
+ true
+ true
+
+
+
+
+
+
+
diff --git a/ortools/constraint_solver/samples/VrpStartsEnds.cs b/ortools/constraint_solver/samples/VrpStartsEnds.cs
new file mode 100644
index 0000000000..3354343dd1
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpStartsEnds.cs
@@ -0,0 +1,152 @@
+// Copyright 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]
+
+///
+/// Minimal TSP using distance matrix.
+///
+public class VrpStartsEnds {
+ // [START data_model]
+ class DataModel {
+ // Constructor:
+ public DataModel() {
+ distancesMatrix_ = new long[,] {
+ {0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662},
+ {548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210},
+ {776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754},
+ {696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358},
+ {582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244},
+ {274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708},
+ {502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480},
+ {194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856},
+ {308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514},
+ {194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468},
+ {536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354},
+ {502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844},
+ {388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730},
+ {354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536},
+ {468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194},
+ {776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798},
+ {662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0}
+ };
+ starts_ = new int[] {1, 2, 15, 16};
+ ends_ = new int[] {0, 0, 0, 0};
+ }
+ public ref readonly long[,] GetDistanceMatrix() { return ref distancesMatrix_;}
+ public int GetVehicleNumber() { return 4;}
+ public ref readonly int[] GetStarts() { return ref starts_;}
+ public ref readonly int[] GetEnds() { return ref ends_;}
+
+ private long[,] distancesMatrix_;
+ private int[] starts_;
+ private int[] ends_;
+ };
+ // [END data_model]
+
+ // [START solution_printer]
+ ///
+ /// Print the solution.
+ ///
+ static void PrintSolution(
+ in DataModel data,
+ in RoutingModel routing,
+ in RoutingIndexManager manager,
+ in Assignment solution) {
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ // Inspect solution.
+ long totalDistance = 0;
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ Console.WriteLine("Route for Vehicle {0}:", i);
+ long routeDistance = 0;
+ var index = routing.Start(i);
+ 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("Distance of the route: {0}m", routeDistance);
+ totalDistance += routeDistance;
+ }
+ Console.WriteLine("Total Distance of all routes: {0}m", totalDistance);
+ }
+ // [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.GetDistanceMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetStarts(),
+ data.GetEnds());
+
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetDistanceMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [END arc_cost]
+
+ // Add Distance constraint.
+ // [START distance_constraint]
+ routing.AddDimension(transitCostIndex, 0, 2000,
+ true, // start cumul to zero
+ "Distance");
+ RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
+ distanceDimension.SetGlobalSpanCostCoefficient(100);
+ // [END distance_constraint]
+
+ // 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(data, routing, manager, solution);
+ // [END print_solution]
+ }
+}
+// [END program]
diff --git a/ortools/constraint_solver/samples/VrpStartsEnds.csproj b/ortools/constraint_solver/samples/VrpStartsEnds.csproj
new file mode 100644
index 0000000000..87c6f54b13
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpStartsEnds.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ 7.2
+ netcoreapp2.1
+ false
+ ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json
+
+
+
+ full
+ true
+ true
+
+
+
+
+
+
+
diff --git a/ortools/constraint_solver/samples/VrpTimeWindows.cs b/ortools/constraint_solver/samples/VrpTimeWindows.cs
new file mode 100644
index 0000000000..603579bb0c
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpTimeWindows.cs
@@ -0,0 +1,200 @@
+// Copyright 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]
+
+///
+/// Minimal TSP using distance matrix.
+///
+public class VrpTimeWindows {
+ // [START data_model]
+ class DataModel {
+ // Constructor:
+ public DataModel() {
+ timeMatrix_ = new long[,] {
+ {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7},
+ {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14},
+ {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9},
+ {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16},
+ {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14},
+ {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8},
+ {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5},
+ {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10},
+ {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6},
+ {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5},
+ {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4},
+ {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10},
+ {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8},
+ {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6},
+ {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2},
+ {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9},
+ {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0},
+ };
+ timeWindows_ = new long[,] {
+ {0, 0},
+ {10, 15},
+ {10, 15},
+ {5, 10},
+ {5, 10},
+ {0, 5},
+ {5, 10},
+ {0, 5},
+ {5, 10},
+ {0, 5},
+ {10, 15},
+ {10, 15},
+ {0, 5},
+ {5, 10},
+ {5, 10},
+ {10, 15},
+ {5, 10},
+ };
+ }
+ public ref readonly long[,] GetTimeMatrix() { return ref timeMatrix_;}
+ public ref readonly long[,] GetTimeWindows() { return ref timeWindows_;}
+ public int GetVehicleNumber() { return 4;}
+ public int GetDepot() { return 0;}
+
+ private long[,] timeMatrix_;
+ private long[,] timeWindows_;
+ };
+ // [END data_model]
+
+ // [START solution_printer]
+ ///
+ /// Print the solution.
+ ///
+ static void PrintSolution(
+ in DataModel data,
+ in RoutingModel routing,
+ in RoutingIndexManager manager,
+ in Assignment solution) {
+ Console.WriteLine("Objective: {0}", solution.ObjectiveValue());
+ RoutingDimension timeDimension = routing.GetMutableDimension("Time");
+ // Inspect solution.
+ long totalTime = 0;
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ Console.WriteLine("Route for Vehicle {0}:", i);
+ long routeTime = 0;
+ var index = routing.Start(i);
+ while (routing.IsEnd(index) == false) {
+ var timeVar = timeDimension.CumulVar(index);
+ var slackVar = timeDimension.SlackVar(index);
+ Console.Write("{0} Time({1},{2}) Slack({3},{4}) -> ",
+ manager.IndexToNode(index),
+ solution.Min(timeVar),
+ solution.Max(timeVar),
+ solution.Min(slackVar),
+ solution.Max(slackVar));
+ var previousIndex = index;
+ index = solution.Value(routing.NextVar(index));
+ routeTime += routing.GetArcCostForVehicle(previousIndex, index, 0);
+ }
+ var endTimeVar = timeDimension.CumulVar(index);
+ Console.WriteLine("{0} Time({1},{2})",
+ manager.IndexToNode(index),
+ solution.Min(endTimeVar),
+ solution.Max(endTimeVar));
+ Console.WriteLine("Time of the route: {0}m", routeTime);
+ totalTime += routeTime;
+ }
+ Console.WriteLine("Total Distance of all routes: {0}m", totalTime);
+ }
+ // [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.GetTimeMatrix().GetLength(0),
+ data.GetVehicleNumber(),
+ data.GetDepot());
+
+ // [END index_manager]
+
+ // Create Routing Model.
+ // [START routing_model]
+ RoutingModel routing = new RoutingModel(manager);
+ // [END routing_model]
+
+ // Define cost of each arc.
+ // [START arc_cost]
+ int transitCostIndex = routing.RegisterTransitCallback(
+ (long fromIndex, long toIndex) => {
+ var fromNode = manager.IndexToNode(fromIndex);
+ var toNode = manager.IndexToNode(toIndex);
+ return data.GetTimeMatrix()[fromNode, toNode]; }
+ );
+ routing.SetArcCostEvaluatorOfAllVehicles(transitCostIndex);
+ // [END arc_cost]
+
+ // Add Distance constraint.
+ // [START time_constraint]
+ routing.AddDimension(
+ transitCostIndex, // transit callback
+ 30, // allow waiting time
+ 30, // vehicle maximum capacities
+ false, // start cumul to zero
+ "Time");
+ RoutingDimension timeDimension = routing.GetMutableDimension("Time");
+ // Add time window constraints for each location except depot
+ // and 'copy' the slack var in the solution object (aka Assignment) to print it
+ for (int i = 1; i < data.GetTimeWindows().GetLength(0); ++i) {
+ long index = manager.NodeToIndex(i);
+ timeDimension.CumulVar(index).SetRange(
+ data.GetTimeWindows()[i, 0],
+ data.GetTimeWindows()[i, 1]);
+ routing.AddToAssignment(timeDimension.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
+ for (int i = 0; i < data.GetVehicleNumber(); ++i) {
+ long index = routing.Start(i);
+ timeDimension.CumulVar(index).SetRange(
+ data.GetTimeWindows()[0, 0],
+ data.GetTimeWindows()[0, 1]);
+ routing.AddToAssignment(timeDimension.SlackVar(index));
+ }
+ // [END time_constraint]
+
+ // 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(data, routing, manager, solution);
+ // [END print_solution]
+ }
+}
+// [END program]
diff --git a/ortools/constraint_solver/samples/VrpTimeWindows.csproj b/ortools/constraint_solver/samples/VrpTimeWindows.csproj
new file mode 100644
index 0000000000..db8e53a17b
--- /dev/null
+++ b/ortools/constraint_solver/samples/VrpTimeWindows.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ 7.2
+ netcoreapp2.1
+ false
+ ../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json
+
+
+
+ full
+ true
+ true
+
+
+
+
+
+
+