Я хотел сделать простой VRP с минимизацией расстояния, сохраняя при этом ограничения по времени для каждого узла. Проблема в том, что со временем я сделал то, что было сказано в руководстве по VRP, но это просто не работает. Выходные данные дают мне:
Day: 0, ((0, 7)) Item: 3
Day: 1, ((0, 4)) Item: 3
Day: 2, ((0, 7)) Item: 0
Day: 3, ((0, 1)) Item: 2
Day: 4, ((0, 7)) Item: 2
Day: 5, ((0, 7)) Item: 0
Day: 6, ((0, 3)) Item: 1
((x, y)) значения - это значения временного диапазона для узлов (они правильно читаются), но не используются должным образом, например, узел 2 находится в день 3, даже если он имеет предел от 0 до 1.
from __future__ import print_function
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def create_data_model():
"""Stores the data for the problem."""
data = {}
data['distance_matrix'] = [
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 20, 20, 30, 30],
[0, 0, 0, 10, 0, 0, 30, 30],
[0, 0, 0, 10, 0, 0, 30, 30],
[0, 0, 0, 10, 20, 20, 0, 0],
[0, 0, 0, 10, 20, 20, 0, 0],
]
data['deadlines'] = [
(0, 7), # 0 - 1
(0, 7), # 0 - 2
(0, 3), # 1 - 3
(0, 7), # 2 - 4
(0, 1), # 2 - 5
(0, 4), # 3 - 6
(0, 7), # 3 - 7
]
data['num_items'] = 5
data['num_days'] = 7
data['types'] = [0,0,1,2,2,3,3]
data['num_vehicles'] = 1
data['depot'] = 0
data['storage_cost'] = 10
return data
def print_solution(data, manager, routing, solution):
"""Prints solution on console."""
time_dimension = routing.GetDimensionOrDie('Time')
print(routing.status())
max_route_distance = 0
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
plan_output = 'Schedule: \n'
route_distance = 0
previous_index = index
index = solution.Value(routing.NextVar(index))
day = 0
while not routing.IsEnd(index):
time_var = time_dimension.CumulVar(index)
print(time_var)
plan_output += 'Day: {0}, ({1}) Item: {2} \n'.format(day, data['deadlines'][index-1], data['types'][manager.IndexToNode(index)-1])
previous_index = index
index = solution.Value(routing.NextVar(index))
print(index)
route_distance += routing.GetArcCostForVehicle(previous_index, index, vehicle_id)
day += 1
plan_output += 'Cost : {}\n'.format(route_distance)
print(plan_output)
max_route_distance = max(route_distance, max_route_distance)
#total_time += solution.Min(time_var)
#print('Total time of all routes: {} days'.format(total_time))
print('Minimum cost: {}'.format(max_route_distance))
def main():
"""Solve the CVRP problem."""
# Instantiate the data problem.
data = create_data_model()
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(data['num_days']+1,
data['num_vehicles'], data['depot'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
# --- DISTANCE ---
# Create and register a transit callback.
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
# storage = (7 - day)*data['storage_cost']
return data['distance_matrix'][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# --- TIME ---
#Add Time Windows constraint.
def time_callback(index):
return 1
transit_callback_index = routing.RegisterPositiveUnaryTransitCallback(time_callback)
time = 'Time'
routing.AddDimension(
transit_callback_index,
0, # allow waiting time
data['num_days'], # maximum time per vehicle
True,
time)
time_dimension = routing.GetDimensionOrDie(time)
# Add time window constraints for each location except depot.
for location_idx, time_window in enumerate(data['deadlines']):
index = manager.NodeToIndex(location_idx)
time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])
# Add time window constraints for each vehicle start node.
time_dimension.CumulVar(routing.Start(0)).SetRange(data['deadlines'][0][0], data['deadlines'][0][1])
# Instantiate route start and end times to produce feasible times.
#routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.Start(0)))
#routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(0)))
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if solution:
print_solution(data, manager, routing, solution)
else:
print('No solution')
if __name__ == '__main__':
main()