switch_literals = []
for vehicle_id in all_vehicles:
arcs = []
vehicle_tasks_rank = v_tasks_rank[vehicle_id]
for trip_x in trips.itertuples():
# Initial arc from the dummy node (0) to a task.
start_lit = model.NewBoolVar('')
arcs.append([0, trip_x.Index + 1, start_lit])
# If this task is the first, set both rank and start to 0.
model.Add(vehicle_tasks_rank[trip_x.Index] == 0).OnlyEnforceIf(start_lit)
# Final arc from an arc to the dummy node.
arcs.append([trip_x.Index + 1, 0, model.NewBoolVar('')])
# Self arc if the task is not performed.
arcs.append([trip_x.Index + 1, trip_x.Index + 1, shifts[vehicle_id,trip_x.Index].Not()])
model.Add(vehicle_tasks_rank[trip_x.Index] == -1).OnlyEnforceIf(
shifts[vehicle_id,trip_x.Index].Not())
for trip_y in trips.itertuples() :
if trip_x == trip_y:
continue
lit = model.NewBoolVar('%i follows %i' % (trip_x.Index, trip_y.Index))
arcs.append([trip_x.Index + 1, trip_y.Index + 1, lit])
model.AddImplication(lit, shifts[vehicle_id,trip_x.Index])
model.AddImplication(lit, shifts[vehicle_id,trip_y.Index])
# Maintain rank incrementally.
model.Add(vehicle_tasks_rank[trip_y.Index] == vehicle_tasks_rank[trip_x.Index] + 1).OnlyEnforceIf(lit)
# Compute the transition time if task j is the successor of task i.
switch_literals.append(lit*100)#deadhead_times[trip_x.Index,trip_y.Index])
model.AddCircuit(arcs)