title: Google OR-TOOLS VRP Problem with previous OR-TOOLS Assignment problem
body: <p>Im trying to solve a 2 step problem, where in the first one I run an assignment model which calculates the best option that optimize the pick up and deliveries arcs between nodes because not all the vehicles can transport the same products and other complications the problem has. The result of the first model are the arcs that serves as an input in the second VRP model as data['pickups_deliveries'].  The next code is an easy example where the code works but a node cant be a delivery and also a pickup node at the same time. Which is what i need to solve.</p>
  <pre><code>&quot;&quot;&quot;Capacited Vehicles Routing Problem (CVRP).&quot;&quot;&quot;
  
  from ortools.constraint_solver import routing_enums_pb2
  from ortools.constraint_solver import pywrapcp
  
  
  def create_data_model():
      &quot;&quot;&quot;Stores the data for the problem.&quot;&quot;&quot;
      data = {}
      data['distance_matrix'] = [
          [
              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
          ],
      ]
      data['pickups_deliveries'] = [
          [1, 6],
          [2, 10],
          [4, 3],
          [5, 9],
          [7, 8],
          [15, 11],
          [13, 12],
          [16, 14]
      ]
      data['demands'] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
      data['vehicle_capacities'] = [1, 1, 1, 1, 1, 1, 1, 1, 1]
      data['num_vehicles'] = 9
      data['depot'] = 0
      return data
  
  
  def print_solution(data, manager, routing, solution):
      &quot;&quot;&quot;Prints solution on console.&quot;&quot;&quot;
      print(f'Objective: {solution.ObjectiveValue()}')
      total_distance = 0
      total_load = 0
      for vehicle_id in range(data['num_vehicles']):
          index = routing.Start(vehicle_id)
          plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
          route_distance = 0
          route_load = 0
          while not routing.IsEnd(index):
              node_index = manager.IndexToNode(index)
              route_load += data['demands'][node_index]
              plan_output += ' {0} Load({1}) -&gt; '.format(node_index, route_load)
              previous_index = index
              index = solution.Value(routing.NextVar(index))
              route_distance += routing.GetArcCostForVehicle(
                  previous_index, index, vehicle_id)
          plan_output += ' {0} Load({1})\n'.format(manager.IndexToNode(index),
                                                   route_load)
          plan_output += 'Distance of the route: {}m\n'.format(route_distance)
          plan_output += 'Load of the route: {}\n'.format(route_load)
          print(plan_output)
          total_distance += route_distance
          total_load += route_load
      print('Total distance of all routes: {}m'.format(total_distance))
      print('Total load of all routes: {}'.format(total_load))
  
  
  def main():
      &quot;&quot;&quot;Entry point of the program.&quot;&quot;&quot;
      # Instantiate the data problem.
      # [START data]
      data = create_data_model()
      # [END data]
  
      # Create the routing index manager.
      # [START index_manager]
      manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
                                             data['num_vehicles'], data['depot'])
      # [END index_manager]
  
      # Create Routing Model.
      # [START routing_model]
      routing = pywrapcp.RoutingModel(manager)
  
      # [END routing_model]
  
      # Define cost of each arc.
      # [START arc_cost]
      def distance_callback(from_index, to_index):
          &quot;&quot;&quot;Returns the manhattan distance between the two nodes.&quot;&quot;&quot;
          # Convert from routing variable Index to distance matrix NodeIndex.
          from_node = manager.IndexToNode(from_index)
          to_node = manager.IndexToNode(to_index)
          return data['distance_matrix'][from_node][to_node]
  
      transit_callback_index = routing.RegisterTransitCallback(distance_callback)
      routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
      # [END arc_cost]
  
      # Add Distance constraint.
      # [START distance_constraint]
      dimension_name = 'Distance'
      routing.AddDimension(
          transit_callback_index,
          0,  # no slack
          3000,  # vehicle maximum travel distance
          True,  # start cumul to zero
          dimension_name)
      distance_dimension = routing.GetDimensionOrDie(dimension_name)
      distance_dimension.SetGlobalSpanCostCoefficient(100)
      # [END distance_constraint]
  
      # Define Transportation Requests.
      # [START pickup_delivery_constraint]
      for request in data['pickups_deliveries']:
          pickup_index = manager.NodeToIndex(request[0])
          delivery_index = manager.NodeToIndex(request[1])
          routing.AddPickupAndDelivery(pickup_index, delivery_index)
          routing.solver().Add(
              routing.VehicleVar(pickup_index) == routing.VehicleVar(
                  delivery_index))
          routing.solver().Add(
              distance_dimension.CumulVar(pickup_index) &lt;=
              distance_dimension.CumulVar(delivery_index))
      routing.SetPickupAndDeliveryPolicyOfAllVehicles(
          pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_FIFO)
      # [END pickup_delivery_constraint]
  
      # Setting first solution heuristic.
      search_parameters = pywrapcp.DefaultRoutingSearchParameters()
      search_parameters.first_solution_strategy = (
          routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
      search_parameters.local_search_metaheuristic = (
          routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
      search_parameters.time_limit.FromSeconds(1)
  
      # Solve the problem.
      solution = routing.SolveWithParameters(search_parameters)
  
      # Print solution on console.
      if solution:
          print_solution(data, manager, routing, solution)
  
  
  if __name__ == '__main__':
      main()
  </code></pre>
  <pre><code>Route for vehicle 0:
   0 Load(1) -&gt;  4 Load(2) -&gt;  3 Load(3) -&gt;  5 Load(4) -&gt;  9 Load(5) -&gt;  0 Load(5)
  Distance of the route: 1780m
  Load of the route: 5
  
  Route for vehicle 1:
   0 Load(1) -&gt;  2 Load(2) -&gt;  10 Load(3) -&gt;  0 Load(3)
  Distance of the route: 1712m
  Load of the route: 3
  
  Route for vehicle 2:
   0 Load(1) -&gt;  0 Load(1)
  Distance of the route: 0m
  Load of the route: 1
  
  Route for vehicle 3:
   0 Load(1) -&gt;  0 Load(1)
  Distance of the route: 0m
  Load of the route: 1
  
  Route for vehicle 4:
   0 Load(1) -&gt;  0 Load(1)
  Distance of the route: 0m
  Load of the route: 1
  
  Route for vehicle 5:
   0 Load(1) -&gt;  0 Load(1)
  Distance of the route: 0m
  Load of the route: 1
  
  Route for vehicle 6:
   0 Load(1) -&gt;  1 Load(2) -&gt;  6 Load(3) -&gt;  0 Load(3)
  Distance of the route: 1780m
  Load of the route: 3
  
  Route for vehicle 7:
   0 Load(1) -&gt;  7 Load(2) -&gt;  8 Load(3) -&gt;  16 Load(4) -&gt;  14 Load(5) -&gt;  0 Load(5)
  Distance of the route: 1712m
  Load of the route: 5
  
  Route for vehicle 8:
   0 Load(1) -&gt;  13 Load(2) -&gt;  12 Load(3) -&gt;  15 Load(4) -&gt;  11 Load(5) -&gt;  0 Load(5)
  Distance of the route: 1712m
  Load of the route: 5
  </code></pre>
  <p>This code works fine for simple graph assignment where <strong>each pickup node is just a pickup node and each delivery node is just a delivery node</strong>. But if a want a node to be pickup and delivery, I thought i can add this as another graph, for example, making node 14, former delivery node, also  a pickup node for the arc[14,13]. I thought i could force one vehicle to go 16-&gt;14-&gt;13-&gt;12 by adding this to the data['pickups_deliveries'] but python collapse and stops working.</p>
  <pre><code>data['pickups_deliveries'] = [
          [1, 6],
          [2, 10],
          [4, 3],
          [5, 9],
          [7, 8],
          [15, 11],
          [13, 12],
          [16, 14],
         [14,13] ## Added
      ]
  </code></pre>
  <p><strong>Mainly what I want to do is be able to add graphs where in one a node can be a pickup node and in another the same node can be a delivery one.</strong><br />
  Thanks and sorry for the extension.</p>