def assign_lift(route, buses, picked_up): new_route = Route() for stop_ind, stop in enumerate(route.stops): if picked_up[stop_ind]: continue #If this is a wheelchair stop, see whether we can add it to the route if stop.count_needs("W") > 0 or stop.count_needs("L") > 0: new_route.add_stop(stop) picked_up[stop_ind] = True possible = False for bus in buses: if bus.route == None and bus.lift and bus.can_handle( new_route): possible = True break if not possible: new_route.remove_stop(stop) picked_up[stop_ind] = False #Now as many wheelchair students as can fit on one #bus have been picked up. Add other students if possible for stop_ind, stop in enumerate(route.stops): if picked_up[stop_ind]: continue if stop.count_needs("W") == 0 and stop.count_needs("L") == 0: if not new_route.add_stop(stop): continue picked_up[stop_ind] = True possible = False for bus in buses: if bus.route == None and bus.lift and bus.can_handle( new_route): possible = True break if not possible: new_route.remove_stop(stop) picked_up[stop_ind] = False for bus in buses: if bus.lift and bus.can_handle(new_route): assert bus.assign(new_route) break #Keep stops in the same order. This ensures that the travel time #doesn't increase, violating regulations. new_route.stops.sort(key=lambda s: route.stops.index(s)) new_route.recompute_length() buses.remove(new_route.bus) #If we failed to pick up all wheelchair students, #need to continue assigning wheelchair buses. recursive_routes = [] for stop_ind, stop in enumerate(route.stops): if (not picked_up[stop_ind] and (stop.count_needs("W") > 0 or stop.count_needs("L") > 0)): recursive_routes = assign_lift(route, buses, picked_up) recursive_routes.append(new_route) assert new_route.feasibility_check(verbose=True) return recursive_routes