// начинается здесь
Код: Выделить всё
public void VRP(DataModel data)
{
try
{
// Create Routing Index Manager
RoutingIndexManager manager = new RoutingIndexManager(data.DistanceMatrix.GetLength(0), data.VehicleNumber, data.Depot);
// Create Routing Model.
RoutingModel routing = new RoutingModel(manager);
// Create and register a transit callback.
int transitCallbackIndex = routing.RegisterTransitCallback((long fromIndex, long toIndex) =>
{
// Convert from routing variable Index to
// distance matrix NodeIndex.
var fromNode = manager.IndexToNode(fromIndex);
var toNode = manager.IndexToNode(toIndex);
return data.DistanceMatrix[fromNode, toNode];
});
// Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
int transitCallbackIndextime = 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];
});
routing.SetArcCostEvaluatorOfAllVehicles(transitCallbackIndextime);
// Add Distance constraint.
routing.AddDimension(transitCallbackIndex, 0, Int32.MaxValue,
true, // start cumul to zero
"Distance");
RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
distanceDimension.SetGlobalSpanCostCoefficient(100);
//Define Transportation Requests.
if (data.PickupsDeliveries != null)
{
Solver solver = routing.solver();
for (int i = 0; i < data.PickupsDeliveries.GetLength(0); i++)
{
long pickupIndex = manager.NodeToIndex(data.PickupsDeliveries[i][0]);
long deliveryIndex = manager.NodeToIndex(data.PickupsDeliveries[i][1]);
routing.AddPickupAndDelivery(pickupIndex, deliveryIndex);
solver.Add(solver.MakeEquality(routing.VehicleVar(pickupIndex), routing.VehicleVar(deliveryIndex)));
solver.Add(solver.MakeLessOrEqual(distanceDimension.CumulVar(pickupIndex),
distanceDimension.CumulVar(deliveryIndex)));
}
}
if (data.TimeWindows != null)
{
for (int i = 0; i < data.TimeWindows.GetLength(0); i++)
{
for (int j = 0; j < data.TimeWindows.GetLength(1); j++)
{
data.TimeWindows[i, j] *= 3600;
}
}
routing.AddDimension(transitCallbackIndextime, // transit callback
3600, // allow waiting time
Int32.MaxValue, // vehicle maximum capacities
false, // start cumul to zero
"Time");
RoutingDimension timeDimension = routing.GetMutableDimension("Time");
// Add time window constraints for each location except depot.
for (int i = 1; i < data.TimeWindows.GetLength(0); ++i)
{
long index = manager.NodeToIndex(i);
timeDimension.CumulVar(index).SetRange(data.TimeWindows[i, 0], data.TimeWindows[i, 1]);
}
// Add time window constraints for each vehicle start node.
for (int i = 0; i < data.VehicleNumber; ++i)
{
long index = routing.Start(i);
timeDimension.CumulVar(index).SetRange(data.TimeWindows[0, 0], data.TimeWindows[0, 1]);
}
for (int i = 0; i < data.VehicleNumber; ++i)
{
routing.AddVariableMinimizedByFinalizer(timeDimension.CumulVar(routing.Start(i)));
routing.AddVariableMinimizedByFinalizer(timeDimension.CumulVar(routing.End(i)));
}
}
// Setting first solution heuristic.
RoutingSearchParameters searchParameters = operations_research_constraint_solver.DefaultRoutingSearchParameters();
searchParameters.FirstSolutionStrategy = FirstSolutionStrategy.Types.Value.PathCheapestArc;
// Solve the problem.
Assignment solution = routing.SolveWithParameters(searchParameters);
if (solution != null)
{
// Print solution on console.
PrintSolutionVRP(data, routing, manager, solution);
PrintSolutionTW(data, routing, manager, solution);
}
}
catch (Exception ex)
{
throw ex;
}
}
также мне нужно время доставки каждой остановки.
Я пробовал изменить значение параметров adddimension, но все равно не получил правильного решения.
Я хочу оптимизировать маршрут с учетом пунктов самовывоза и доставки, а также временных окон с помощью инструментов решения vrp или инструментов.
Подробнее здесь: https://stackoverflow.com/questions/784 ... e-or-tools