dotnet: Add VrpBreaks.cs sample
This commit is contained in:
@@ -566,6 +566,7 @@ test_dotnet_constraint_solver_samples:
|
||||
$(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/VrpBreaks.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
|
||||
|
||||
191
ortools/constraint_solver/samples/VrpBreaks.cs
Normal file
191
ortools/constraint_solver/samples/VrpBreaks.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright 2010-2021 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 time matrix.
|
||||
/// </summary>
|
||||
public class VrpBreaks
|
||||
{
|
||||
// [START data_model]
|
||||
class DataModel
|
||||
{
|
||||
public long[,] TimeMatrix = {
|
||||
{ 0, 27, 38, 34, 29, 13, 25, 9, 15, 9, 26, 25, 19, 17, 23, 38, 33 },
|
||||
{ 27, 0, 34, 15, 9, 25, 36, 17, 34, 37, 54, 29, 24, 33, 50, 43, 60 },
|
||||
{ 38, 34, 0, 49, 43, 25, 13, 40, 23, 37, 20, 63, 58, 56, 39, 77, 37 },
|
||||
{ 34, 15, 49, 0, 5, 32, 43, 25, 42, 44, 61, 25, 31, 41, 58, 28, 67 },
|
||||
{ 29, 9, 43, 5, 0, 26, 38, 19, 36, 38, 55, 20, 25, 35, 52, 33, 62 },
|
||||
{ 13, 25, 25, 32, 26, 0, 11, 15, 9, 12, 29, 38, 33, 31, 25, 52, 35 },
|
||||
{ 25, 36, 13, 43, 38, 11, 0, 26, 9, 23, 17, 50, 44, 42, 25, 63, 24 },
|
||||
{ 9, 17, 40, 25, 19, 15, 26, 0, 17, 19, 36, 23, 17, 16, 33, 37, 42 },
|
||||
{ 15, 34, 23, 42, 36, 9, 9, 17, 0, 13, 19, 40, 34, 33, 16, 54, 25 },
|
||||
{ 9, 37, 37, 44, 38, 12, 23, 19, 13, 0, 17, 26, 21, 19, 13, 40, 23 },
|
||||
{ 26, 54, 20, 61, 55, 29, 17, 36, 19, 17, 0, 43, 38, 36, 19, 57, 17 },
|
||||
{ 25, 29, 63, 25, 20, 38, 50, 23, 40, 26, 43, 0, 5, 15, 32, 13, 42 },
|
||||
{ 19, 24, 58, 31, 25, 33, 44, 17, 34, 21, 38, 5, 0, 9, 26, 19, 36 },
|
||||
{ 17, 33, 56, 41, 35, 31, 42, 16, 33, 19, 36, 15, 9, 0, 17, 21, 26 },
|
||||
{ 23, 50, 39, 58, 52, 25, 25, 33, 16, 13, 19, 32, 26, 17, 0, 38, 9 },
|
||||
{ 38, 43, 77, 28, 33, 52, 63, 37, 54, 40, 57, 13, 19, 21, 38, 0, 39 },
|
||||
{ 33, 60, 37, 67, 62, 35, 24, 42, 25, 23, 17, 42, 36, 26, 9, 39, 0 },
|
||||
};
|
||||
public long[] ServiceTime = {
|
||||
0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
};
|
||||
public int VehicleNumber = 4;
|
||||
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 {solution.ObjectiveValue()}:");
|
||||
|
||||
Console.WriteLine("Breaks:");
|
||||
AssignmentIntervalContainer intervals = solution.IntervalVarContainer();
|
||||
for (int i = 0; i < intervals.Size(); ++i)
|
||||
{
|
||||
IntervalVarElement breakInterval = intervals.Element(i);
|
||||
if (breakInterval.PerformedValue() == 1)
|
||||
{
|
||||
Console.WriteLine($"{breakInterval.Var().Name()} " + breakInterval.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{breakInterval.Var().Name()}: Unperformed");
|
||||
}
|
||||
}
|
||||
|
||||
RoutingDimension timeDimension = routing.GetMutableDimension("Time");
|
||||
long totalTime = 0;
|
||||
for (int i = 0; i < manager.GetNumberOfVehicles(); ++i)
|
||||
{
|
||||
Console.WriteLine($"Route for Vehicle {i}:");
|
||||
var index = routing.Start(i);
|
||||
while (routing.IsEnd(index) == false)
|
||||
{
|
||||
IntVar timeVar = timeDimension.CumulVar(index);
|
||||
Console.Write($"{manager.IndexToNode((int)index)} Time({solution.Value(timeVar)}) -> ");
|
||||
index = solution.Value(routing.NextVar(index));
|
||||
}
|
||||
IntVar endTimeVar = timeDimension.CumulVar(index);
|
||||
Console.WriteLine($"{manager.IndexToNode((int)index)} Time({solution.Value(endTimeVar)})");
|
||||
Console.WriteLine($"Time of the route: {solution.Value(endTimeVar)}min");
|
||||
totalTime += solution.Value(endTimeVar);
|
||||
}
|
||||
Console.WriteLine($"Total time of all routes: {totalTime}min");
|
||||
Console.WriteLine($"Problem solved in {routing.solver().WallTime()}ms");
|
||||
}
|
||||
// [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.TimeMatrix.GetLength(0), 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]
|
||||
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) => {
|
||||
// Convert from routing variable Index to time matrix NodeIndex.
|
||||
var fromNode = manager.IndexToNode(fromIndex);
|
||||
var toNode = manager.IndexToNode(toIndex);
|
||||
return data.TimeMatrix[fromNode, toNode] + data.ServiceTime[fromNode];
|
||||
});
|
||||
// [END transit_callback]
|
||||
|
||||
// Define cost of each arc.
|
||||
// [START arc_cost]
|
||||
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
|
||||
// [END arc_cost]
|
||||
|
||||
// Add Time constraint.
|
||||
// [START time_constraint]
|
||||
routing.AddDimension(transitCallbackIndex, 10, 180,
|
||||
true, // start cumul to zero
|
||||
"Time");
|
||||
RoutingDimension timeDimension = routing.GetMutableDimension("Time");
|
||||
timeDimension.SetGlobalSpanCostCoefficient(10);
|
||||
// [END time_constraint]
|
||||
|
||||
// Add Breaks
|
||||
long[] serviceTimes = new long[routing.Size()];
|
||||
for (int index = 0; index < routing.Size(); index++)
|
||||
{
|
||||
int node = manager.IndexToNode(index);
|
||||
serviceTimes[index] = data.ServiceTime[node];
|
||||
}
|
||||
|
||||
Solver solver = routing.solver();
|
||||
for (int vehicle = 0; vehicle < manager.GetNumberOfVehicles(); ++vehicle)
|
||||
{
|
||||
List<IntervalVar> breakIntervals = new List<IntervalVar>();
|
||||
IntervalVar break_interval = solver.MakeFixedDurationIntervalVar(50, // start min
|
||||
60, // start max
|
||||
10, // duration: 10min
|
||||
false, // optional: no
|
||||
"Break for vehicle " + vehicle);
|
||||
breakIntervals.Add(break_interval);
|
||||
|
||||
timeDimension.SetBreakIntervalsOfVehicle(breakIntervals.ToArray(), vehicle, serviceTimes);
|
||||
}
|
||||
|
||||
// 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]
|
||||
if (solution != null)
|
||||
{
|
||||
PrintSolution(routing, manager, solution);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Solution not found.");
|
||||
}
|
||||
// [END print_solution]
|
||||
}
|
||||
}
|
||||
// [END program]
|
||||
24
ortools/constraint_solver/samples/VrpBreaks.csproj
Normal file
24
ortools/constraint_solver/samples/VrpBreaks.csproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
<!-- see https://github.com/dotnet/docs/issues/12237 -->
|
||||
<RollForward>LatestMajor</RollForward>
|
||||
<RestoreSources>../../../packages;$(RestoreSources);https://api.nuget.org/v3/index.json</RestoreSources>
|
||||
<AssemblyName>Google.OrTools.VrpBreaks</AssemblyName>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<GenerateTailCalls>true</GenerateTailCalls>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="VrpBreaks.cs" />
|
||||
<PackageReference Include="Google.OrTools" Version="8.2.*" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user