google / or-tools

Google's Operations Research tools:
https://developers.google.com/optimization/
Apache License 2.0
11.16k stars 2.12k forks source link

when adding AddDimensionWithVehicleCapacity to VRPTW, getting verflowError: in method 'RoutingIndexManager_IndexToNode', argument 2 of type 'int64' #2127

Closed amitca71 closed 4 years ago

amitca71 commented 4 years ago

What version of OR-tools and what language are you using? Version: 7.7.7810 Language: Python

Which solver are you using (e.g. CP-SAT, Routing Solver, GLOP, BOP, Gurobi) constraint_solver What operating system (Linux, Windows, ...) and version? Windows 10

What did you do? Steps to reproduce the behavior: adding capacity constraint to VRPTW without adding the capacity constraint all worked well, and i got good results (try to comment line 86 (routing.AddDimensionWithVehicleCapacity , and you get outcome)

What did you expect to see expected to get solution with capacity constraint

What did you see instead? \Anaconda3\envs\myenv\lib\site-packages\ortools\constraint_solver\pywrapcp.py in IndexToNode(self, index) 2791 def IndexToNode(self, index: "int64") -> "operations_research::RoutingIndexManager::NodeIndex": -> 2792 return _pywrapcp.RoutingIndexManager_IndexToNode(self, index) 2793

OverflowError: in method 'RoutingIndexManager_IndexToNode', argument 2 of type 'int64'

The above exception was the direct cause of the following exception:

Make sure you include information that can help us debug (full error message, model Proto).

Anything else we should know about your project / environment

lperron commented 4 years ago

can you fix the indent problem ? You need to add 4 space in front of each line of code.

amitca71 commented 4 years ago
from __future__ import print_function
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
from time import sleep 
import math
from itertools import combinations

    def create_data_model():
        data = {}
        data['time_matrix'] = [[0, 15, 11], [15, 0, 3], [11, 3, 0]]
        data['num_vehicles'] = 3
        data['time_windows']=[(0, 15), (15, 37), (11, 37)]
        data['depot']=0
        data['demands']=[1, 1]
        data['vehicle_capacities']=[3, 3, 3]
        return data

    def createModel(timeFrameData, maxTimePerVehicle=50):
        manager = pywrapcp.RoutingIndexManager(len(timeFrameData['time_matrix']),
                                               timeFrameData['num_vehicles'], timeFrameData['depot'])
        routing = pywrapcp.RoutingModel(manager)
        def time_callback(from_index, to_index):
            try:
                from_node = manager.IndexToNode(from_index)
                to_node = manager.IndexToNode(to_index)
            except Exception (e):
                print(e)
            return timeFrameData['time_matrix'][from_node][to_node]

        transit_callback_index = routing.RegisterTransitCallback(time_callback)
        routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
        time = 'Time'
        routing.AddDimension(
            transit_callback_index,
            0,  
            maxTimePerVehicle,  
            False,  
            time)
        time_dimension = routing.GetDimensionOrDie(time)
        for location_idx, time_window in enumerate(timeFrameData['time_windows']):
            if location_idx == 0:
                continue
            index = manager.NodeToIndex(location_idx)
            time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])
        for vehicle_id in range(timeFrameData['num_vehicles']):
            index = routing.Start(vehicle_id)
            time_dimension.CumulVar(index).SetRange(timeFrameData['time_windows'][0][0],
                                                    timeFrameData['time_windows'][0][1])

        for i in range(timeFrameData['num_vehicles']):
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.Start(i)))
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.End(i)))
        def demand_callback(from_index):
            from_node = manager.IndexToNode(from_index)
            return data['demands'][from_node]

        demand_callback_index = routing.RegisterUnaryTransitCallback(
            demand_callback)
        routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, timeFrameData['vehicle_capacities'], True, 'Capacity')
        search_parameters = pywrapcp.DefaultRoutingSearchParameters()
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

        solution = routing.SolveWithParameters(search_parameters)
        return(manager, routing, solution)

    def print_solution(data, manager, routing, solution):
        time_dimension = routing.GetDimensionOrDie('Time')
        total_time = 0
        for vehicle_id in range(data['num_vehicles']):
            index = routing.Start(vehicle_id)
            plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
            while not routing.IsEnd(index):
                time_var = time_dimension.CumulVar(index)
                plan_output += '{0} Time({1},{2}) -> '.format(
                    manager.IndexToNode(index), solution.Min(time_var),
                    solution.Max(time_var))
                index = solution.Value(routing.NextVar(index))
            time_var = time_dimension.CumulVar(index)
            plan_output += '{0} Time({1},{2})\n'.format(manager.IndexToNode(index),
                                                        solution.Min(time_var),
                                                    solution.Max(time_var))
            plan_output += 'Time of the route: {}min\n'.format(
                solution.Min(time_var))
            print(plan_output)
            total_time += solution.Min(time_var)
         print('Total time of all routes: {}min'.format(total_time))

    def main():
        data = create_data_model()
        print(data)

        manager, routing, solution=createModel(data)
        print_solution(data, manager, routing, solution)

    if __name__ == '__main__':
        main()
amitca71 commented 4 years ago

can you fix the indent problem ? You need to add 4 space in front of each line of code.

done

Mizux commented 4 years ago

do you know from which line, this exception is throw ?

Mizux commented 4 years ago

The line data['demands']=[1, 1] should be replaced by data['demands']=[0, 1, 1] otherwise, the second location, i.e. 2, will be out of bound...

when used here:

def demand_callback(from_index):
        from_node = manager.IndexToNode(from_index)
        return data['demands'][from_node]
amitca71 commented 4 years ago

Thanks alot for such a prompt answer 🥇 the exception is abit misleading....