"""
Contains the methods to solve the Dial a Ride Problem (DARP) of the
drtOnline.py tool.
Methods available: exhaustive_search and simple_rerouting
Track progress https://github.com/eclipse/sumo/issues/8256
"""
from __future__ import print_function
import os
import sys
try:
from time import perf_counter
except ImportError:
from time import clock as perf_counter
if 'SUMO_HOME' in os.environ:
tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
sys.path.append(tools)
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
import traci
findRoute = traci.simulation.findRoute
def res_res_pair(options, res1, res2, veh_type, veh_time_pickup,
veh_time_dropoff, rv_dict, pairs_dua_times):
"""
Search all combinations between two reservations. Notation: the first of
the reservations is defined as 'res1' and the second as 'res2' and 'p'
refers to pick up and 'd' to drop off a reservation. Then 'res2p_res1d'
means pickup reservation 2 and then drop off reservation 1.
"""
if (res1.tw_pickup[0] <= res2.tw_pickup[1] and
res2.tw_dropoff[0] <= res1.tw_dropoff[1]):
res1p_res2p = pairs_dua_times.get("%s_%s" % (res1.fromEdge,
res2.fromEdge))
if res1p_res2p is None:
res1p_res2p = int(findRoute(res1.fromEdge, res2.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res1p_res2p += veh_time_pickup
res2p_res2d = rv_dict.get('%sy_%sz' % (res2.id, res2.id))
if res2p_res2d is None:
res2p_res2d = res2.direct + veh_time_dropoff
pair = '%sy_%sz' % (res2.id, res2.id)
rv_dict[pair] = [res2p_res2d, -1, [res2.id, res2.id]]
else:
res2p_res2d = res2p_res2d[0]
res2d_res1d = pairs_dua_times.get("%s_%s" % (res2.toEdge, res1.toEdge))
if res2d_res1d is None:
res2d_res1d = int(findRoute(res2.toEdge, res1.toEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res2d_res1d += veh_time_dropoff
time_res2p = res1.tw_pickup[0] + res1p_res2p
if time_res2p > res2.tw_pickup[1]:
pass
elif (time_res2p + res2p_res2d) > res2.tw_dropoff[1]:
pass
elif (time_res2p + res2p_res2d + res2d_res1d) > res1.tw_dropoff[1]:
pass
else:
pair = '%sy_%sy' % (res1.id, res2.id)
rv_dict[pair] = [res1p_res2p, 1, [res1.id, res2.id]]
pair = '%sz_%sz' % (res2.id, res1.id)
rv_dict[pair] = [res2d_res1d, -1, [res2.id, res1.id]]
if (res1.tw_pickup[0] <= res2.tw_pickup[1] and
res1.tw_dropoff[0] <= res2.tw_dropoff[1]):
res1p_res2p = rv_dict.get('%sy_%sy' % (res1.id, res2.id))
if res1p_res2p is None:
res1p_res2p = pairs_dua_times.get("%s_%s" % (res1.fromEdge,
res2.fromEdge))
if res1p_res2p is None:
res1p_res2p = int(findRoute(res1.fromEdge, res2.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res1p_res2p += veh_time_pickup
else:
res1p_res2p = res1p_res2p[0]
res2p_res1d = pairs_dua_times.get("%s_%s" % (res2.fromEdge,
res1.toEdge))
if res2p_res1d is None:
res2p_res1d = int(findRoute(res2.fromEdge, res1.toEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res2p_res1d += veh_time_dropoff
res1d_res2d = pairs_dua_times.get("%s_%s" % (res1.toEdge, res2.toEdge))
if res1d_res2d is None:
res1d_res2d = int(findRoute(res1.toEdge, res2.toEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res1d_res2d += veh_time_dropoff
time_res2p = res1.tw_pickup[0] + res1p_res2p
if time_res2p > res2.tw_pickup[1]:
pass
elif (time_res2p + res2p_res1d) > res1.tw_dropoff[1]:
pass
elif (time_res2p + res2p_res1d + res1d_res2d) > res2.tw_dropoff[1]:
pass
else:
pair = '%sy_%sy' % (res1.id, res2.id)
if rv_dict.get(pair) is None:
rv_dict[pair] = [res1p_res2p, 1, [res1.id, res2.id]]
pair = '%sy_%sz' % (res2.id, res1.id)
rv_dict[pair] = [res2p_res1d, -1, [res2.id, res1.id]]
pair = '%sz_%sz' % (res1.id, res2.id)
rv_dict[pair] = [res1d_res2d, -1, [res1.id, res2.id]]
if (res2.tw_pickup[0] <= res1.tw_pickup[1] and
res2.tw_dropoff[0] <= res1.tw_dropoff[1]):
res2p_res1p = pairs_dua_times.get("%s_%s" % (res2.fromEdge,
res1.fromEdge))
if res2p_res1p is None:
res2p_res1p = int(findRoute(res2.fromEdge, res1.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res2p_res1p += veh_time_pickup
res1p_res2d = pairs_dua_times.get("%s_%s" % (res1.fromEdge,
res2.toEdge))
if res1p_res2d is None:
res1p_res2d = int(findRoute(res1.fromEdge, res2.toEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res1p_res2d += veh_time_dropoff
res2d_res1d = rv_dict.get('%sz_%sz' % (res2.id, res1.id))
if res2d_res1d is None:
res2d_res1d = pairs_dua_times.get("%s_%s" % (res2.toEdge,
res1.toEdge))
if res2d_res1d is None:
res2d_res1d = int(findRoute(res2.toEdge, res1.toEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res2d_res1d += veh_time_dropoff
else:
res2d_res1d = res2d_res1d[0]
time_res1p = res2.tw_pickup[0] + res2p_res1p
if time_res1p > res1.tw_pickup[1]:
pass
elif (time_res1p + res1p_res2d) > res2.tw_dropoff[1]:
pass
elif (time_res1p + res1p_res2d + res2d_res1d) > res1.tw_dropoff[1]:
pass
else:
pair = '%sy_%sy' % (res2.id, res1.id)
rv_dict[pair] = [res2p_res1p, 1, [res2.id, res1.id]]
pair = '%sy_%sz' % (res1.id, res2.id)
rv_dict[pair] = [res1p_res2d, -1, [res1.id, res2.id]]
pair = '%sz_%sz' % (res1.id, res2.id)
if rv_dict.get(pair) is None:
rv_dict[pair] = [res2d_res1d, -1, [res2.id, res1.id]]
if (res2.tw_pickup[0] <= res1.tw_pickup[1] and
res1.tw_dropoff[0] <= res2.tw_dropoff[1]):
res2p_res1p = rv_dict.get('%sy_%sy' % (res2.id, res1.id), False)
res1d_res2d = rv_dict.get('%sz_%sz' % (res1.id, res2.id), False)
res1p_res1d = rv_dict.get('%sy_%sz' % (res1.id, res1.id), False)
if not res1p_res1d:
res1p_res1d = res1.direct + veh_time_dropoff
pair = '%sy_%sz' % (res1.id, res1.id)
rv_dict[pair] = [res1p_res1d, -1, [res1.id, res1.id]]
else:
res1p_res1d = res1p_res1d[0]
if not res2p_res1p or not res1d_res2d:
if not res2p_res1p:
res2p_res1p = pairs_dua_times.get("%s_%s" % (res2.fromEdge,
res1.fromEdge))
if res2p_res1p is None:
res2p_res1p = int(findRoute(res2.fromEdge, res1.fromEdge,
veh_type, routingMode=options.routing_mode).travelTime)
res2p_res1p += veh_time_pickup
else:
res2p_res1p = res2p_res1p[0]
if not res1d_res2d:
res1d_res2d = pairs_dua_times.get("%s_%s" % (res1.toEdge,
res2.toEdge))
if res1d_res2d is None:
res1d_res2d = int(findRoute(res1.toEdge, res2.toEdge,
veh_type, routingMode=options.routing_mode).travelTime)
res1d_res2d += veh_time_dropoff
else:
res1d_res2d = res1d_res2d[0]
res1p_res1d = rv_dict.get('%sy_%sz' % (res1.id, res1.id))[0]
time_res1p = res2.tw_pickup[0] + res2p_res1p
if time_res1p > res1.tw_pickup[1]:
pass
elif (time_res1p + res1p_res1d) > res1.tw_dropoff[1]:
pass
elif (time_res1p + res1p_res1d + res1d_res2d) > res2.tw_dropoff[1]:
pass
else:
pair = '%sy_%sy' % (res2.id, res1.id)
if not rv_dict.get(pair, False):
rv_dict[pair] = [res2p_res1p, 1, [res2.id, res1.id]]
pair = '%sz_%sz' % (res1.id, res2.id)
if not rv_dict.get(pair, False):
rv_dict[pair] = [res1d_res2d, -1, [res1.id, res2.id]]
if res1.tw_dropoff[0] <= res2.tw_pickup[1]:
res1d_res2p = pairs_dua_times.get("%s_%s" % (res1.toEdge,
res2.fromEdge))
if res1d_res2p is None:
res1d_res2p = int(findRoute(res1.toEdge, res2.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res1d_res2p += veh_time_pickup
if (res1.tw_dropoff[0] + res1d_res2p) < res2.tw_pickup[1]:
pair = '%sz_%sy' % (res1.id, res2.id)
rv_dict[pair] = [res1d_res2p, 1, [res1.id, res2.id]]
if res2.tw_dropoff[0] <= res1.tw_pickup[1]:
res2d_res1p = pairs_dua_times.get("%s_%s" % (res2.toEdge,
res1.fromEdge))
if res2d_res1p is None:
res2d_res1p = int(findRoute(res2.toEdge, res1.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime)
res2d_res1p += veh_time_pickup
if (res2.tw_dropoff[0] + res2d_res1p) < res1.tw_pickup[1]:
pair = '%sz_%sy' % (res2.id, res1.id)
rv_dict[pair] = [res2d_res1p, 1, [res2.id, res1.id]]
def get_rv(options, res_id_new, res_id_picked, res_all,
veh_type, veh_time_pickup, veh_time_dropoff, rv_dict, step,
veh_edges, pairs_dua_times):
"""
Generates the reservation-vehicle graph, which has the possible
combinations between two reservations and between a reservation and a
vehicle with the required travel time, the number of passengers picked up
or dropped off and the reservation id and/or vehicle id of the pair.
"""
id_current = []
[id_current.extend(veh_id) for veh_id in veh_edges.values()]
id_current.extend(res_all.keys())
[rv_dict.pop(key) for key in list(rv_dict)
if set(rv_dict[key][2]) - set(id_current)]
res_rv_remove = []
res_all_remove = []
for res_id, res in res_all.items():
if res_id in res_id_new:
res_possible = False
for edge, vehicles in veh_edges.items():
pickup_time = pairs_dua_times.get("%s_%s" % (edge,
res.fromEdge))
if pickup_time is None:
pickup_time = findRoute(edge, res.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime
if step+pickup_time > res.tw_pickup[1]:
continue
for veh_id in vehicles:
route_id = '%s_%sy' % (veh_id, res_id)
rv_dict[route_id] = [pickup_time+veh_time_pickup, 1, [veh_id, res_id]]
res_possible = True
if not res_possible:
print("Reservation %s (person %s) cannot be served" %
(res_id, res.persons))
res_all_remove.append(res_id)
res_rv_remove.extend(['%sy' % res_id, '%sz' % res_id])
for person in res.persons:
traci.person.removeStages(person)
continue
route_id = '%sy_%sz' % (res_id, res_id)
rv_dict[route_id] = [res.direct+veh_time_dropoff, -1, [res_id, res_id]]
reservations2 = set(res_all.keys()) ^ set(res_all_remove)
for res2 in reservations2:
if res2 != res_id:
res_res_pair(options, res, res_all.get(res2), veh_type,
veh_time_pickup, veh_time_dropoff,
rv_dict, pairs_dua_times)
elif not res.vehicle:
if res.tw_pickup[1] < step:
print("Reservation %s (person %s) cannot be served" %
(res_id, res.persons))
res_all_remove.append(res_id)
res_rv_remove.extend(['%sy' % res_id, '%sz' % res_id])
for person in res.persons:
traci.person.removeStages(person)
continue
remove = True
for edge, vehicles in veh_edges.items():
pickup_time = pairs_dua_times.get("%s_%s" % (edge,
res.fromEdge))
if pickup_time is None:
pickup_time = findRoute(edge, res.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime
if step+pickup_time <= res.tw_pickup[1]:
for veh_id in vehicles:
route_id = '%s_%sy' % (veh_id, res_id)
if rv_dict.get(route_id, False):
rv_dict[route_id][0] = pickup_time+60
remove = False
else:
for veh_id in vehicles:
route_id = '%s_%sy' % (veh_id, res_id)
if rv_dict.get(route_id, False):
rv_dict.pop(route_id)
if remove:
print("Reservation %s (person %s) cannot be served" %
(res_id, res.persons))
res_all_remove.append(res_id)
res_rv_remove.extend(['%sy' % res_id, '%sz' % res_id])
for person in res.persons:
traci.person.removeStages(person)
elif res_id not in res_id_picked:
route_id = '%s_%sy' % (res.vehicle, res_id)
if rv_dict.get(route_id, False):
if traci.vehicle.getRoadID(res.vehicle).startswith(':'):
edge_index = traci.vehicle.getRouteIndex(res.vehicle) + 1
from_edge = traci.vehicle.getRoute(res.vehicle)[edge_index]
else:
from_edge = traci.vehicle.getRoadID(res.vehicle)
pickup_time = pairs_dua_times.get("%s_%s" % (from_edge,
res.fromEdge))
if pickup_time is None:
pickup_time = findRoute(from_edge, res.fromEdge, veh_type,
routingMode=options.routing_mode).travelTime
rv_dict[route_id][0] = pickup_time+veh_time_pickup
if options.verbose and step+pickup_time > res.tw_pickup[1]:
print("Time window surpassed by", step+pickup_time - res.tw_pickup[1])
elif res_id in res_id_picked:
res_rv_remove.append('%sy' % res_id)
if traci.vehicle.getRoadID(res.vehicle).startswith(':'):
edge_index = traci.vehicle.getRouteIndex(res.vehicle) + 1
from_edge = traci.vehicle.getRoute(res.vehicle)[edge_index]
else:
from_edge = traci.vehicle.getRoadID(res.vehicle)
dropoff_time = pairs_dua_times.get("%s_%s" % (from_edge,
res.toEdge))
if dropoff_time is None:
dropoff_time = int(findRoute(from_edge, res.toEdge, veh_type,
routingMode=options.routing_mode).travelTime)
route_id = '%s_%sz' % (res.vehicle, res_id)
rv_dict[route_id] = [dropoff_time+veh_time_dropoff, -1, [res.vehicle, res_id]]
else:
print("Error: Reservation state not considered")
if res_rv_remove:
[rv_dict.pop(key) for key in list(rv_dict) if set(res_rv_remove) & set(key.split("_"))]
if res_all_remove:
[res_all.pop(key) for key in res_all_remove]
def simple_rerouting(options, res_id_unassigned, res_id_picked,
res_all, fleet, rv_dict, step):
"""
Search possible trips allowing vehicles to change their trip in real time
(rerouting). Not all trips are covered, being the result not exact.
"""
rtv_dict = {}
trip_id = {}
id_current = []
id_current.extend(fleet)
id_current.extend(res_all.keys())
[rv_dict.pop(key) for key in list(rv_dict)
if set(rv_dict[key][2]) - set(id_current)]
rtv_res = list(res_all.keys())
for veh_id in fleet:
veh_bin = [0] * len(fleet)
veh_bin[fleet.index(veh_id)] = 1
veh_capacity = (traci.vehicle.getPersonCapacity(veh_id)
- traci.vehicle.getPersonNumber(veh_id))
res_assigned_veh = [res_id for res_id, res in res_all.items()
if res.vehicle == veh_id]
filter_valid = list(res_id_unassigned)
filter_valid.append(veh_id)
filter_valid.extend(res_assigned_veh)
pairs = [pair_id for pair_id, pair in
sorted(rv_dict.items(), key=lambda pair: pair[1][0])
if pair[2][0] in filter_valid and pair[2][1] in filter_valid]
res_picked_veh = list(set(res_assigned_veh) & set(res_id_picked))
first_pairs = []
if res_assigned_veh:
for next_stop in traci.vehicle.getStops(veh_id):
next_act = next_stop.actType.split(",")[0].split(" ")[0]
next_id = next_stop.actType.split(",")[0].split(" ")[-1][1:-1]
if next_act == 'pickup' and next_id in res_id_picked:
continue
elif next_act == 'dropOff' and next_id not in res_all.keys():
continue
else:
if next_act == 'pickup':
first_pairs = ["%s_%sy" % (veh_id, next_id)]
else:
first_pairs = ["%s_%sz" % (veh_id, next_id)]
break
else:
first_pairs = [pair for pair in pairs
if pair.split("_")[0] == veh_id]
for first_pair in first_pairs:
trip = first_pair
i = 1
while (i <= (len(filter_valid)-1)*2 and
len(trip.split("_"))-1 < (len(filter_valid)-1)*2):
for pair in pairs:
if pair.split("_")[0] != trip.split("_")[-1]:
continue
trip_new = ("_").join([trip, pair.split("_")[-1]])
stops = trip_new.split("_")
trip_pick = list(res_picked_veh)
trip_pick.extend([stop[:-1] for stop in trip_new.split('_')[1:]
if stop.endswith("y")])
trip_drop = [stop[:-1] for stop in trip_new.split('_')[1:]
if stop.endswith("z")]
if (len(trip_pick) != len(set(trip_pick))
or len(trip_drop) != len(set(trip_drop))):
continue
abort = False
for stop in trip_drop:
try:
if stop in res_picked_veh:
index_pu = -1
else:
index_pu = stops.index(('%sy' % stop))
index_do = stops.index(('%sz' % stop))
except ValueError:
abort = True
break
if index_pu > index_do:
abort = True
break
if abort:
continue
if trip == first_pair:
pax = rv_dict[first_pair][1] + rv_dict[pair][1]
trip_time = (rv_dict[first_pair][0] + step
+ rv_dict[pair][0])
else:
pax = trip_id[trip][1] + rv_dict[pair][1]
trip_time = trip_id[trip][0] + rv_dict[pair][0]
if pax > veh_capacity:
continue
stop_id = pair.split("_")[-1]
if stop_id.endswith('y'):
stop_tw = res_all[stop_id[:-1]].tw_pickup
if trip_time > stop_tw[1]:
continue
elif trip_time < stop_tw[0] and pax == 1:
trip_time = stop_tw[0]
else:
stop_tw = res_all[stop_id[:-1]].tw_dropoff
if trip_time > stop_tw[1]:
continue
trip_id[trip_new] = [trip_time, pax]
if set(trip_pick) == set(trip_drop):
if (set(res_assigned_veh)
!= set(trip_pick) & set(res_assigned_veh)):
continue
else:
res_bin = [0] * len(rtv_res)
for stop in trip_pick:
res_bin[rtv_res.index(stop)] = 1
trip_cost = trip_time - sum(res_bin)*options.c_ko
rtv_dict[trip_new] = [trip_time, veh_bin, res_bin,
trip_cost]
trip = trip_new
i += 1
if len(fleet) == 1 and rtv_dict:
trips_list = list(rtv_dict.keys())
costs_list = [value[3] for key, value in rtv_dict.items()]
trip_index = costs_list.index(min(costs_list))
trip_id = trips_list[trip_index]
return {trip_id: rtv_dict[trip_id]}, rtv_res
return rtv_dict, rtv_res
def search_trips(trip, pairs, res_assigned_veh, res_picked_veh, res_all,
rv_dict, rtv_res, veh_capacity, veh_bin, rtv_dict, trips_tree,
options, start_time):
"""
Search all possible new trips by adding a new stop to the current trip.
If the maximum search time given is not surpass, all possible trips are
consider.
"""
trip_id, trip_time, trip_pax = trip
for pair in pairs:
if (perf_counter() - start_time) > options.rtv_time:
break
if pair.split("_")[0] != trip_id.split("_")[-1]:
continue
new_trip_id = ("_").join([trip_id, pair.split("_")[-1]])
stops = new_trip_id.split("_")
trip_pick = list(res_picked_veh)
trip_pick.extend([stop[:-1] for stop in new_trip_id.split('_')[1:]
if stop.endswith("y")])
trip_drop = [stop[:-1] for stop in new_trip_id.split('_')[1:]
if stop.endswith("z")]
if (len(trip_pick) != len(set(trip_pick))
or len(trip_drop) != len(set(trip_drop))):
continue
abort = False
for stop in trip_drop:
try:
if stop in res_picked_veh:
index_pu = -1
else:
index_pu = stops.index(('%sy' % stop))
index_do = stops.index(('%sz' % stop))
except ValueError:
abort = True
break
if index_pu > index_do:
abort = True
break
if abort:
continue
new_trip_pax = trip_pax + rv_dict[pair][1]
new_trip_time = trip_time + rv_dict[pair][0]
if new_trip_pax > veh_capacity:
continue
stop_id = pair.split("_")[-1]
if stop_id.endswith('y'):
stop_tw = res_all[stop_id[:-1]].tw_pickup
if new_trip_time > stop_tw[1]:
continue
elif new_trip_time < stop_tw[0] and new_trip_pax == 1:
new_trip_time = stop_tw[0]
else:
stop_tw = res_all[stop_id[:-1]].tw_dropoff
if new_trip_time > stop_tw[1]:
continue
trips_tree.append([new_trip_id, new_trip_time, new_trip_pax])
if set(trip_pick) == set(trip_drop):
if set(res_assigned_veh) != set(trip_pick) & set(res_assigned_veh):
continue
else:
res_bin = [0] * len(rtv_res)
for stop in trip_pick:
res_bin[rtv_res.index(stop)] = 1
trip_cost = new_trip_time - sum(res_bin)*options.c_ko
rtv_dict[new_trip_id] = [new_trip_time, veh_bin, res_bin,
trip_cost]
return trips_tree, rtv_dict
def exhaustive_search(options, res_id_unassigned, res_id_picked, res_all,
fleet, rv_dict, step, memory_problems, veh_edges):
"""
Search all possible trips for each vehicle allowing dynamic rerouting.
If the maximum search time given is not surpass, the method is exact.
"""
rtv_dict = {}
rtv_res = list(res_all.keys())
idle_veh = traci.vehicle.getTaxiFleet(0)
for vehicles in veh_edges.values():
if len(vehicles) > 1:
vehicles_capacity = [traci.vehicle.getPersonCapacity(veh_id) for veh_id in vehicles]
vehicles_idle = [veh_id in idle_veh for veh_id in vehicles]
vehicles_unique = []
for veh_idx, veh_id in enumerate(vehicles):
if veh_idx == 0:
vehicles_unique.append(veh_id)
continue
if not vehicles_idle[veh_idx]:
vehicles_unique.append(veh_id)
continue
for compare_veh in range(veh_idx+1):
if (vehicles_idle[compare_veh] and
vehicles_capacity[veh_idx] == vehicles_capacity[compare_veh]):
vehicles_unique.append(vehicles[compare_veh])
break
else:
vehicles_unique = vehicles
for veh_id in set(vehicles_unique):
veh_bin = [0] * len(fleet)
veh_bin[fleet.index(veh_id)] = 1
veh_capacity = (traci.vehicle.getPersonCapacity(veh_id)
- traci.vehicle.getPersonNumber(veh_id))
res_assigned_veh = [res_id for res_id, res in res_all.items()
if res.vehicle == veh_id]
filter_valid = list(res_id_unassigned)
filter_valid.append(veh_id)
filter_valid.extend(res_assigned_veh)
pairs = [pair_id for pair_id, pair in
sorted(rv_dict.items(), key=lambda pair: pair[1][0])
if pair[2][0] in filter_valid and
pair[2][1] in filter_valid]
res_picked_veh = list(set(res_assigned_veh) & set(res_id_picked))
trips_tree = [[]]
i = 0
if res_assigned_veh:
for next_stop in traci.vehicle.getStops(veh_id):
next_act = next_stop.actType.split(",")[0].split(" ")[0]
next_id = next_stop.actType.split(",")[0].split(" ")[-1][1:-1]
if next_act == 'pickup' and next_id in res_id_picked:
continue
elif next_act == 'dropOff' and next_id not in res_all.keys():
continue
else:
if next_act == 'pickup':
trip_id = "%s_%sy" % (veh_id, next_id)
trip_time = rv_dict[trip_id][0]
trips_tree[i] = [[trip_id, trip_time+step, 1]]
break
else:
trip_id = "%s_%sz" % (veh_id, next_id)
trip_time = rv_dict[trip_id][0]
trips_tree[i] = [[trip_id, trip_time+step, -1]]
break
if not trips_tree[i]:
trips_tree[i] = [[pair, rv_dict[pair][0]+step, 1] for pair in pairs
if pair.split("_")[0] == veh_id]
start_time = perf_counter()
while trips_tree[i]:
trips_tree.append([])
for trip in trips_tree[i]:
trips_tree[i + 1], rtv_dict = search_trips(trip, pairs, res_assigned_veh, res_picked_veh, res_all,
rv_dict, rtv_res, veh_capacity, veh_bin, rtv_dict,
trips_tree[i + 1], options, start_time)
if (perf_counter() - start_time) > options.rtv_time:
memory_problems.append(False)
break
del trips_tree[i][:]
i = i + 1
for veh_idx, veh_id in enumerate(vehicles):
if veh_id in vehicles_unique:
continue
equal_veh_id = vehicles_unique[veh_idx]
veh_bin = [0] * len(fleet)
veh_bin[fleet.index(veh_id)] = 1
copy_rtv_keys = [key for key in rtv_dict.keys() if key.split("_")[0] == equal_veh_id]
for key in copy_rtv_keys:
new_trip_id = key.replace(equal_veh_id, veh_id)
trip_time = rtv_dict[key][0]
res_bin = rtv_dict[key][2]
trip_cost = rtv_dict[key][3]
rtv_dict[new_trip_id] = [trip_time, veh_bin, res_bin,
trip_cost]
if len(fleet) == 1 and rtv_dict:
trips_list = list(rtv_dict.keys())
costs_list = [value[3] for trip, value in rtv_dict.items()]
trip_index = costs_list.index(min(costs_list))
trip_id = trips_list[trip_index]
return {trip_id: rtv_dict[trip_id]}, None, memory_problems
return rtv_dict, rtv_res, memory_problems
def main(options, step, fleet, veh_type, veh_time_pickup, veh_time_dropoff,
res_all, res_id_new, res_id_unassigned, res_id_picked,
veh_edges, pairs_dua_times):
"""
Run specified solver
"""
if 'rv_dict' not in globals():
global rv_dict
rv_dict = {}
if 'exact_sol' not in globals():
global exact_sol
exact_sol = [True]
if options.darp_solver == 'exhaustive_search':
get_rv(options, res_id_new, res_id_picked, res_all,
veh_type, veh_time_pickup, veh_time_dropoff, rv_dict, step,
veh_edges, pairs_dua_times)
rtv_dict, rtv_res, exact_sol = exhaustive_search(options, res_id_unassigned, res_id_picked,
res_all, fleet, rv_dict, step,
exact_sol, veh_edges)
return (rtv_dict, rtv_res, exact_sol)
elif options.darp_solver == 'simple_rerouting':
get_rv(options, res_id_new, res_id_picked, res_all,
veh_type, veh_time_pickup, veh_time_dropoff, rv_dict, step,
veh_edges, pairs_dua_times)
rtv_dict, rtv_res = simple_rerouting(options, res_id_unassigned,
res_id_picked,
res_all, fleet, rv_dict, step)
return (rtv_dict, rtv_res, [False])