def create_route_and_stop_data_structures():
    """Creates and returns a list of Route objects and a dictionary of Stop objects 
    based on the subway data rerieved from the MBTA API but reduced to the salient data"""

    # Filter route data by type 0,1 to retrieve only subway routes
    # and only include 'long_name' attribute to reduce request size
    url = '/routes?filter[type]=0,1&fields[route]=long_name'
    route_data = get_data_from_api(url)

    route_objs = []  # List to contain all subway Route objects
    stop_objs = {
    }  # Dictionary to contain all subway Stop objects, with the name as the key
    for r in route_data:

        ############### Append to Route list ################

        route_id = r['id']
        route_name = r['attributes']['long_name']

        # Get stop data for each route (a specific route ID must
        # be referenced in order to get stop data with the route)
        url = '/stops?include=route&filter[route]={}'.format(route_id)
        stop_data = get_data_from_api(url)

        num_stops = len(stop_data)

        # Append new Route to list
        route_objs.append(route.Route(route_id, route_name, num_stops))

        ############### Add to Stop dictionary ################
        # Loop through all stops for each route, and create a dictionary entry for each new Stop.
        # Note: stops are listed in route-order.
        for s_ind in range(len(stop_data)):

            s = stop_data[s_ind]
            stop_id = s['id']
            stop_name = s['attributes']['name']

            # If stop not yet in dictionary, add it
            if stop_name not in stop_objs:
                stop_objs[stop_name] = stop.Stop(stop_id, stop_name)

            # Add the route to the stop's list of routes
            stop_objs[stop_name].add_route(route_name)

            # Add the connections to the stop's list of connections
            if s_ind != 0:  #if not first stop in route, add previous stop connection
                prev_stop_name = stop_data[s_ind - 1]['attributes']['name']
                stop_objs[stop_name].add_connection(
                    (prev_stop_name, route_name))
            if s_ind != len(
                    stop_data
            ) - 1:  #if not last stop in route, add next stop connection
                next_stop_name = stop_data[s_ind + 1]['attributes']['name']
                stop_objs[stop_name].add_connection(
                    (next_stop_name, route_name))

    return route_objs, stop_objs
Esempio n. 2
0
    def init_chk(self):
        self.chkpts = []
        n_chk = cf.N_INT_POINTS + 2
        for i in range(n_chk):
            res = cf.R_LENGTH * (i / (n_chk - 1))
            xy = Point(res, cf.MAX_DEV)
            dep_t = ((i / (n_chk - 1)) * cf.R_TIME * 60)

            self.chkpts.append(stop.Stop(i, xy, "chk", dep_t))
        self.next_stop_id = cf.N_INT_POINTS + 2
Esempio n. 3
0
    def init_chk(self):
        self.chkpts = []
        #Add beginning and endpoints to checkpoints
        n_chk = cf.N_INT_POINTS + 2
        for i in range(n_chk):
            #X-Coordinates of checkpoints are evenly spaced
            res = cf.R_LENGTH * (i / (n_chk - 1))
            xy = Point(res, cf.MAX_DEV)
            #Departure time are evenly spaced
            dep_t = ((i / (n_chk - 1)) * cf.R_TIME * 60)

            self.chkpts.append(stop.Stop(i, xy, "chk", dep_t))
        self.next_stop_id = cf.N_INT_POINTS + 2
Esempio n. 4
0
def stop_merge(demand_point, merge_stop, bus, t, sim):
    cur_stop = bus.stops_remaining[0]
    ddist_x = (merge_stop.xy.x - demand_point.xy.x) / 2
    ddist_y = (merge_stop.xy.y - demand_point.xy.y) / 2
    ddist = np.sum(np.abs([ddist_x, ddist_y]))
    max_dist = cf.W_SPEED * 2 * cf.MAX_MERGE_TIME / 60
    if (ddist > max_dist):
        return None
    walk_arr_t = t + (np.abs(ddist_x) + np.abs(ddist_y)) / (cf.W_SPEED / 3600.)
    bus_arr_t = t + bus.hold_time + (
        np.abs(merge_stop.xy.x - cur_stop.xy.x) +
        np.abs(merge_stop.xy.y - cur_stop.xy.y)) / (cf.BUS_SPEED / 3600.)
    if (bus_arr_t < walk_arr_t):
        return None

    new_stop = stop.Stop(
        merge_stop.id,
        Point(demand_point.xy.x + ddist_x, demand_point.xy.y + ddist_y),
        "merge", None)
    modify = False
    bus.stops_remaining[bus.stops_remaining.index(merge_stop)] = new_stop
    for p in bus.passengers_assigned.values():
        if p.o == merge_stop:
            p.o = new_stop
            modify = True
            merge_time = abs(p.o.xy.x - new_stop.xy.x) + abs(
                p.o.xy.y - new_stop.xy.y) / (cf.W_SPEED / 3600.)
            sim.output.pickup_add_walktime(p.id, merge_time)
        if p.d == merge_stop:
            p.d = new_stop
            modify = True
            merge_time = abs(p.d.xy.x - new_stop.xy.x) + abs(
                p.d.xy.y - new_stop.xy.y) / (cf.W_SPEED / 3600.)
            sim.output.dropoff_add_walktime(p.id, merge_time)
    for p in bus.passengers_on_board.values():
        if p.d == merge_stop:
            p.d = new_stop
            modify = True
            merge_time = abs(p.d.xy.x - new_stop.xy.x) + abs(
                p.d.xy.y - new_stop.xy.y) / (cf.W_SPEED / 3600.)
            sim.output.dropoff_add_walktime(p.id, merge_time)
    if (not modify):
        import pdb
        pdb.set_trace()
    print("MERGED FROM " + str(merge_stop.xy) + " TO " + str(new_stop.xy))
    return (new_stop, walk_arr_t - t)
def prd_merge_walk(demand, bus, t, chkpts, sim):
    t_now = t - bus.start_t
    if t_now > demand.o.dep_t:
        return None
    start_index = bus.stops_remaining.index(demand.o)
    costs_by_stop = {}
    for index, merge_stop in enumerate(bus.stops_remaining[start_index:]):
        index += start_index
        if (merge_stop.dep_t):
            continue
        if (index == 0):
            # if it is the first stop, then treat the current location as the previous stop
            prev_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
        else:
            prev_stop = bus.stops_remaining[index - 1]

        nxt_chk = None
        for s in bus.stops_remaining[index:]:
            if s.dep_t:
                nxt_chk = s
                break
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts) - cf.WAITING_TIME
        if st < 0:
            continue

        ddist_x = demand.o.xy.x - merge_stop.xy.x
        ddist_y = demand.o.xy.y - merge_stop.xy.y
        ddist = np.sum(np.abs([ddist_x, ddist_y]))

        max_walk_dist = cf.W_SPEED * (cf.MAX_WALK_TIME / 60
                                      )  # mph * (1 hr / 60 min)
        max_distance_possible = max_walk_dist * 2

        if ddist > max_distance_possible:
            pass
        else:
            new_d = Point(demand.d.xy.x + np.sign(ddist_x) * ddist_x / 2,
                          demand.d.xy.y + np.sign(ddist_y) * ddist_y / 2)
            walk_arr_t = t + (np.abs(new_d.x - demand.d.xy.x) +
                              np.abs(new_d.y - demand.d.xy.y)) / (cf.W_SPEED /
                                                                  3600.)
            bus_arr_t = t + bus.hold_time + (
                np.abs(new_d.x - prev_stop.xy.x) +
                np.abs(new_d.y - prev_stop.xy.y)) / (cf.BUS_SPEED / 3600.)
            if bus_arr_t <= walk_arr_t:
                pass
            else:
                new_d_stop = stop.Stop(sim.next_stop_id, new_d, "walk", None)
                sim.next_stop_id += 1
                old_d = demand.d
                demand.d = new_d_stop
                result = ins.feasible(demand, bus, t, chkpts, cost_only=True)
                if result:
                    min_ix, min_cost, min_nxt_chk = result
                    costs_by_stop[new_d_stop.id] = (new_d_stop, min_ix,
                                                    min_cost, min_nxt_chk,
                                                    bus_arr_t, walk_arr_t)
                demand.d = old_d
    min_ix = None
    min_stop = None
    min_nxt_chk = None
    min_cost = 9999
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]
            #make sure it was feasible
            print("MERGE || Bus Time: " + str(v[4]) + ", Walk Time: " +
                  str(v[5]))

    return (min_cost, min_stop, min_ix, min_nxt_chk)
Esempio n. 6
0
 def add_stop(self, stop_id, stop_name, time, seq, lat, lon):
     stop = s.Stop(stop_id, stop_name, time, seq, lat, lon)
     self.stops.insert(0, stop)
Esempio n. 7
0
import stop
import sys
from PyQt4 import QtGui

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = QtGui.QMainWindow()

    ui = stop.Stop()

    vbox = QtGui.QVBoxLayout()
    wid = QtGui.QWidget()

    vbox.addWidget(ui)
    wid.setLayout(vbox)

    window.setCentralWidget(wid)
    window.resize(300, 300)

    window.show()

    app.exec_()
Esempio n. 8
0
def rpd_walk(demand, bus, t, chkpts, sim):
    t_now = t - bus.start_t

    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    add_faux = [faux_stop] + bus.stops_remaining
    try:
        max_possible_ix = add_faux.index(demand.d)
    # weve already passed their checkpoint, not possible
    except ValueError:
        return None

    costs_by_stop = {}
    for ix, (cur_stop, next_stop) in enumerate(
            zip(add_faux[:max_possible_ix], bus.stops_remaining)):

        nxt_chk = None
        for s in bus.stops_remaining[ix:]:
            if s.dep_t:
                nxt_chk = s
                break
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts) - cf.WAITING_TIME
        if st < 0:
            continue
        daqx = demand.o.xy.x - cur_stop.xy.x
        daqy = demand.o.xy.y - cur_stop.xy.y
        dqbx = next_stop.xy.x - demand.o.xy.x
        dqby = next_stop.xy.y - demand.o.xy.y
        dabx = next_stop.xy.x - cur_stop.xy.x
        daby = next_stop.xy.y - cur_stop.xy.y
        ddist = np.sum(np.abs([daqx, daqy, dqbx, dqby])) - np.sum(
            np.abs([dabx, daby]))
        ddist_x = np.sum(np.abs([daqx, dqbx])) - np.abs(dabx)
        ddist_y = np.sum(np.abs([daqy, dqby])) - np.abs(daby)

        # initial walk direction
        walk_dir = 'x' if ddist_x > ddist_y else ddist_y
        max_walk_dist = cf.W_SPEED * (cf.MAX_WALK_TIME / 60
                                      )  # mph * (1 hr / 60 min)
        max_drive_dist = st * (cf.BUS_SPEED / 3600)
        # make sure we can actually cover the distance
        if 2 * max_walk_dist + max_drive_dist < ddist:
            print("max walk dist in {} mins is {}".format(
                cf.MAX_WALK_TIME, max_walk_dist))
            print("max drive dist is {}".format(max_drive_dist))
            print("ddist is {}".format(ddist))
            continue

        if walk_dir == 'x':
            walk_dist = np.min([ddist_x / 2, max_walk_dist])
            if walk_dist < max_walk_dist and ddist_y > 0:
                new_o = Point(
                    demand.o.xy.x + np.sign(ddist_x) * walk_dist,
                    demand.o.xy.y + np.sign(ddist_y) *
                    np.min([max_walk_dist - walk_dist, ddist_y]))
            else:
                new_o = Point(demand.o.xy.x + np.sign(ddist_x) * walk_dist,
                              demand.o.xy.y)
        else:
            walk_dist = np.min([ddist_y / 2, max_walk_dist])
            if walk_dist < max_walk_dist and ddist_x > 0:
                new_o = Point(
                    demand.o.xy.x + np.sign(ddist_x) * walk_dist,
                    demand.o.xy.y + np.sign(ddist_y) *
                    np.min([max_walk_dist - walk_dist, ddist_y / 2]))
            else:
                new_o = Point(demand.o.xy.x,
                              np.sign(ddist_y) * walk_dist + demand.o.xy.y)

        walk_arr_t = t + (np.abs(new_o.x - demand.o.xy.x) +
                          np.abs(new_o.y - demand.o.xy.y)) / (cf.W_SPEED /
                                                              3600.)
        #TODO: make sure that the walker arrives before the bus
        # what we need to write is something that computes exactly
        # when the bus would arrive based on where we are inserting this
        # stop.
        # THIS IS CURRENTLY BROKEN & only works for this test example!!
        bus_arr_t = t + bus.hold_time + (np.abs(cur_stop.xy.x - new_o.x) +
                                         np.abs(new_o.y - cur_stop.xy.y)) / (
                                             cf.BUS_SPEED / 3600.)
        if bus_arr_t <= walk_arr_t:
            print(bus_arr_t)
            print(walk_arr_t)
            print("doesnt work")
            continue

        new_o_stop = stop.Stop(sim.next_stop_id, new_o, "walk", None)
        sim.next_stop_id += 1
        old_o = demand.o
        demand.o = new_o_stop
        min_ix, min_cost, min_nxt_chk = ins.feasible(demand,
                                                     bus,
                                                     t,
                                                     chkpts,
                                                     cost_only=True)
        demand.o = old_o
        costs_by_stop[new_o_stop.id] = (new_o_stop, min_ix, min_cost,
                                        min_nxt_chk)

    min_ix = None
    min_stop = None
    old_stop = None
    min_nxt_chk = None
    min_cost = 99999
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]

    if min_stop:
        old_stop = demand.o
        demand.o = min_stop
        bus.stops_remaining.insert(min_ix, min_stop)
        bus.avail_slack_times[min_nxt_chk[0].id] -= min_nxt_chk[1]
        bus.passengers_assigned[demand.id] = demand

    # we return the old stop for visualization purposes.
    # when we plot, the passengers 'o' has been set to
    # the new origin, so we want to plot where they initially
    # were before they walked
    return old_stop
def rprd_feasible(demand, bus, t, chkpts):
    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    add_faux = [faux_stop] + bus.stops_remaining
    min_cost = 99999999
    min_indices = None
    min_chks = None
    for ix, (cur_stop, next_stop) in enumerate(zip(add_faux, add_faux[1:])):
        ddist, daqx, dqbx = check_distance(demand.o, cur_stop, next_stop)
        delta_t = -cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)
        #print("delta_t is {}".format(delta_t))

        nxt_chk = None
        for s in bus.stops_remaining[ix:]:
            if s.dep_t:
                nxt_chk = s
                break

        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)
        if delta_t > st:
            continue

        # c2, c3: backtracking
        if daqx < 0 and np.abs(daqx) > cf.MAX_BACK:
            continue

        if dqbx < 0 and np.abs(dqbx) > cf.MAX_BACK:
            continue

        outer_cost = calculate_cost(bus, nxt_chk, ix, delta_t, ddist)

        potential_dests = [demand.o] + bus.stops_remaining[ix:]
        for ix2, (cur_2, next_2) in enumerate(
                zip(potential_dests, potential_dests[1:])):
            ddist_2, daqx_2, dqbx_2 = check_distance(demand.o, cur_2, next_2)
            delta_t_2 = cf.WAITING_TIME + ddist_2 / (cf.BUS_SPEED / 3600)

            nxt_chk_2 = None
            for s in potential_dests[ix2 + 1:]:
                if s.typ == "chk":
                    nxt_chk_2 = s
                    break
            if nxt_chk_2 == nxt_chk:
                st2 = st - delta_t
            else:
                st2 = bus.usable_slack_time(t, nxt_chk_2.id, chkpts)

            if delta_t_2 > st2:
                continue

            # c2, c3: backtracking
            if daqx_2 < 0 and np.abs(daqx_2) > cf.MAX_BACK:
                continue

            if dqbx_2 < 0 and np.abs(dqbx_2) > cf.MAX_BACK:
                continue

            inner_cost = calculate_cost(bus, nxt_chk, ix + ix2, delta_t_2,
                                        ddist_2)
            total_cost = outer_cost + inner_cost
            if total_cost < min_cost:
                min_cost = total_cost
                min_indices = (ix, ix2)
                min_chks = (nxt_chk, delta_t, nxt_chk_2, delta_t_2)

    if min_indices is not None:
        ix1, ix2 = min_indices
        bus.passengers_assigned[demand.id] = demand
        bus.stops_remaining.insert(ix1 + ix2, demand.d)
        bus.stops_remaining.insert(ix1, demand.o)
        bus.avail_slack_times[min_chks[0].id] -= min_chks[1]
        bus.avail_slack_times[min_chks[2].id] -= min_chks[3]
        #print("bus {} has st {} before {}".format(bus.id, bus.avail_slack_times[min_chks[0].id], min_chks[0].id))
        #print("bus {} has st {} before {}".format(bus.id, bus.avail_slack_times[min_chks[2].id], min_chks[2].id))
        #print("stops remaining is {}".format(bus.stops_remaining))

    return min_indices
Esempio n. 10
0
def check_normal(demand_point,
                 bus,
                 t,
                 chkpts,
                 sim,
                 origin=None,
                 destination=None,
                 dem=None,
                 cost_only=False):
    #addes current location as fake stop
    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    # if origin is not possible, return
    if (origin):
        t_now = t - bus.start_t
        if origin.typ == "chk" and t_now > origin.dep_t:
            return None
    # Get next checkpoint as last possible stop
    remaining_stops = [faux_stop] + bus.stops_remaining
    nxt_chk = faux_stop
    start_index = 0
    end_index = 0
    for ix, s in enumerate(remaining_stops):
        if s.dep_t:
            if demand_point.xy.x > s.xy.x:
                nxt_chk = s
                end_index = ix
            else:
                break
    ix = end_index
    #Get first checkpoint if possible, current location otherwise.
    while ix > 0:
        ix -= 1
        if remaining_stops[ix].dep_t:
            start_index = ix
            break

    min_cost = 99999999
    min_ix = None
    min_nxt_chk = None
    nxt_chk = None
    min_time = cf.MAX_WALK_TIME
    time = 0
    extra_time = 0

    for ix, (cur_stop, next_stop) in enumerate(
            zip(remaining_stops[start_index:end_index],
                remaining_stops[start_index + 1:])):
        #get next checkpoint for slack time
        for s in remaining_stops[start_index + ix + 1:]:
            if s.dep_t:
                nxt_chk = s
                break
        ddist, daqx, dqbx = added_distance(demand_point, cur_stop, next_stop)
        delta_t = cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)
        #if cost only, we are looking for the time until pickup
        if (cost_only):
            dabx = next_stop.xy.x - cur_stop.xy.x
            daby = next_stop.xy.y - cur_stop.xy.y
            #include hold time? -- not implemented
            extra_time = np.sum(np.abs([dabx, daby])) / (cf.BUS_SPEED / 3600)
        #check if the stop is valid
        if (not check_feasible(daqx, dqbx, delta_t, st)):
            time += extra_time
            continue
        #check possibility of merging with nearby stop
        if (cf.ALLOW_MERGE and not cost_only and ix != 0):
            new_stop = check_merge(demand_point, cur_stop, bus, t)
            if (new_stop):
                return (0, new_stop[0], ix + start_index + extra, (nxt_chk, 0),
                        True, new_stop[1])
        #check if this is the quickest pickup for cost only(walking)
        if (cost_only):
            if (time + delta_t < min_time):
                min_time = time + delta_t
            else:
                time += extra_time
        else:
            #calculate the cost of the stop
            cost = calculate_cost(bus, nxt_chk, ix + start_index, delta_t,
                                  ddist)
            if cost < min_cost:
                min_cost = cost
                min_ix = ix + start_index + extra
                min_nxt_chk = (nxt_chk, delta_t)
    if (cost_only):
        return min_time
    if (min_ix is None):
        return None
    else:
        return min_cost, demand_point, min_ix, min_nxt_chk, False
Esempio n. 11
0
def rpd_feasible(demand, bus, t, chkpts, cost_only=False):

    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    add_faux = [faux_stop] + bus.stops_remaining
    try:
        max_possible_ix = add_faux.index(demand.d)
    # weve already passed their checkpoint, not possible
    except ValueError:
        return None

    min_cost = 99999999
    min_ix = None
    min_nxt_chk = None
    # now consider inserting between every stop
    for ix, (cur_stop, next_stop) in enumerate(zip(add_faux[:max_possible_ix], bus.stops_remaining)):

        daqx = demand.o.xy.x - cur_stop.xy.x 
        daqy = demand.o.xy.y - cur_stop.xy.y 
        dqbx = next_stop.xy.x - demand.o.xy.x
        dqby = next_stop.xy.y - demand.o.xy.y
        dabx = next_stop.xy.x - cur_stop.xy.x
        daby = next_stop.xy.y - cur_stop.xy.y
        ddist = np.sum(np.abs([daqx, daqy, dqbx, dqby])) - np.sum(np.abs([dabx, daby]))

        # WAITING_TIME: there is an amount of time that the bus
        # spends sitting at each stop while the passenger
        # loads and unloads
        delta_t = cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)

        # now, get the next checkpoint based on where
        # we're trying to insert this stop
        nxt_chk = None;
        for s in bus.stops_remaining[ix:]:
            # you could also use the stop 'typ' here
            # but only checkpoints get instantiated
            # with a dep_t value
            if s.dep_t:
                nxt_chk = s
                break

        # first: make sure we have enough slack time
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)
        #print("st is {}".format(st))
        if delta_t > st:
            continue

        # c2, c3: backtracking
        if daqx < 0 and np.abs(daqx) > cf.MAX_BACK:
            continue
        
        if dqbx < 0 and np.abs(dqbx) > cf.MAX_BACK:
            continue


        # now we have confirmed its feasible, compute cost


        # first, compute how much extra wait time
        # passengers will have (paper talks about this)
        delta_WT = 0
        for p in bus.passengers_assigned.values():
            if p.type not in {"RPD", "RPRD"}:
                continue

            oix = bus.stops_remaining.index(p.o)
            if oix < bus.stops_remaining.index(nxt_chk) and oix > ix:
                #print(str(p) + " must wait longer because of this assignment")
                delta_WT += delta_t

        
        # initialize to include this customer
        # for some reason
        # (from the paper)
        delta_RT = delta_t
        for p in list(bus.passengers_on_board.values()) + list(bus.passengers_assigned.values()):
            try:
                dix = bus.stops_remaining.index(p.d)
            except ValueError:
                import pdb; pdb.set_trace()

            try:
                oix = bus.stops_remaining.index(p.o)
            except ValueError:
                oix = 0

            # some psasengers travel longer
            if bus.stops_remaining.index(nxt_chk) >= dix:
                #print(str(p) + " is arriving later because of this dropoff insertion")
                delta_RT += delta_t

            # some passengers are picked up later so they travel less time
            if p.type in {"RPD", "RPRD"} and oix > ix and dix > bus.stops_remaining.index(nxt_chk):
                #print(str(p) + " saves travel time because picked up later")
                delta_RT -= delta_t

        cost = w1 * (ddist) + w2 * delta_RT + w3 * delta_WT
        if cost < min_cost:
            min_cost = cost
            min_ix = ix
            min_nxt_chk = (nxt_chk, delta_t)

    # TODO: each function will need a cost_only parameter
    # to check for walking w/o altering state
    if min_ix is not None and not cost_only:
        bus.passengers_assigned[demand.id] = demand
        bus.stops_remaining.insert(min_ix, demand.o)
        bus.avail_slack_times[min_nxt_chk[0].id] -= min_nxt_chk[1]
        #print("bus {} has st {} before {}".format(bus.id, bus.avail_slack_times[min_nxt_chk[0].id], min_nxt_chk[0].id))
        #print("stops remaining is {}".format(bus.stops_remaining))
    elif min_ix is None:
        return None

    return min_ix, min_cost, min_nxt_chk
Esempio n. 12
0
def rprd_feasible(demand, bus, t, chkpts):
    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    add_faux = [faux_stop] + bus.stops_remaining
    min_cost = 99999999
    min_indices = None
    min_chks = None
    for ix, (cur_stop, next_stop) in enumerate(zip(add_faux, add_faux[1:])):
        daqx = demand.o.xy.x - cur_stop.xy.x 
        daqy = demand.o.xy.y - cur_stop.xy.y 
        dqbx = next_stop.xy.x - demand.o.xy.x
        dqby = next_stop.xy.y - demand.o.xy.y
        dabx = next_stop.xy.x - cur_stop.xy.x
        daby = next_stop.xy.y - cur_stop.xy.y
        ddist = np.sum(np.abs([daqx, daqy, dqbx, dqby])) - np.sum(np.abs([dabx, daby]))
        #print("ddist is {}".format(ddist))
        delta_t = -cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)
        #print("delta_t is {}".format(delta_t))

        nxt_chk = None
        for s in bus.stops_remaining[ix:]:
            if s.dep_t:
                nxt_chk = s
                break
        prv_chk = chkpts[nxt_chk.id - 1]

        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)

        if delta_t > st:
            continue

        # c2, c3: backtracking
        if daqx < 0 and np.abs(daqx) > cf.MAX_BACK:
            continue
        
        if dqbx < 0 and np.abs(dqbx) > cf.MAX_BACK:
            continue

        delta_WT = 0
        for p in bus.passengers_assigned.values():
            if p.type not in {"RPD", "RPRD"}:
                continue

            oix = bus.stops_remaining.index(p.o)
            if oix < bus.stops_remaining.index(nxt_chk) and oix > ix:
                #print(str(p) + " must wait longer because of this assignment")
                delta_WT += delta_t

        
        #print("delta_wt is {}".format(delta_WT))
        # initialize to include this customer
        # for some reason
        delta_RT = delta_t
        for p in list(bus.passengers_on_board.values()) + list(bus.passengers_assigned.values()):
            try:
                dix = bus.stops_remaining.index(p.d)
            except:
                import pdb; pdb.set_trace()
            try:
                oix = bus.stops_remaining.index(p.o)
            except ValueError:
                oix = 0
            if bus.stops_remaining.index(nxt_chk) >= dix:
                #print(str(p) + " is arriving later because of this dropoff insertion")
                delta_RT += delta_t
            if p.type in {"RPD", "RPRD"} and oix > ix and dix > bus.stops_remaining.index(nxt_chk):
                #print(str(p) + " saves travel time because picked up later")
                delta_RT -= delta_t

        outer_cost = w1 * (ddist) + w2 * delta_RT + w3 * delta_WT

        potential_dests = [demand.o] + bus.stops_remaining[ix:]
        for ix2, (cur_2, next_2) in enumerate(zip(potential_dests, potential_dests[1:])):
            daqx_2 = demand.d.xy.x - cur_2.xy.x 
            daqy_2 = demand.d.xy.y - cur_2.xy.y 
            dqbx_2 = next_2.xy.x - demand.d.xy.x
            dqby_2 = next_2.xy.y - demand.d.xy.y
            dabx_2 = next_2.xy.x - cur_2.xy.x
            daby_2 = next_2.xy.y - cur_2.xy.y
            ddist_2 = np.sum(np.abs([daqx_2, daqy_2, dqbx_2, dqby_2])) - np.sum(np.abs([dabx_2, daby_2]))
            #print("-=-=-=-")
            #print("ddist is {}".format(ddist))
            delta_t_2 = cf.WAITING_TIME + ddist_2 / (cf.BUS_SPEED / 3600)
            #print("delta_t is {}".format(delta_t))

            nxt_chk_2 = None
            for s in potential_dests[ix2 + 1:]:
                if s.typ == "chk":
                    nxt_chk_2 = s
                    break
            if nxt_chk_2 == nxt_chk:
                st2 = st - delta_t
            else:
                st2 = bus.usable_slack_time(t, nxt_chk_2.id, chkpts)
            
            if delta_t_2 > st2:
                continue

            # c2, c3: backtracking
            if daqx_2 < 0 and np.abs(daqx_2) > cf.MAX_BACK:
                continue
            
            if dqbx_2 < 0 and np.abs(dqbx_2) > cf.MAX_BACK:
                continue

            delta_WT_2 = 0
            for p in bus.passengers_assigned.values():
                if p.type not in {"RPD", "RPRD"}:
                    continue

                oix = bus.stops_remaining.index(p.o)
                if oix < bus.stops_remaining.index(nxt_chk) and oix > ix2 + ix:
                    #print(str(p) + " must wait longer because of this assignment")
                    delta_WT_2 += delta_t_2

            
            #print("delta_wt is {}".format(delta_WT))
            # initialize to include this customer
            # for some reason
            delta_RT_2 = delta_t_2
            for p in list(bus.passengers_on_board.values()) + list(bus.passengers_assigned.values()):
                dix = bus.stops_remaining.index(p.d)
                try:
                    oix = bus.stops_remaining.index(p.o)
                except ValueError:
                    oix = 0
                if bus.stops_remaining.index(nxt_chk) >= dix:
                    #print(str(p) + " is arriving later because of this dropoff insertion")
                    delta_RT_2 += delta_t_2
                if p.type in {"RPD", "RPRD"} and oix > ix2 + ix and dix > bus.stops_remaining.index(nxt_chk):
                    #print(str(p) + " saves travel time because picked up later")
                    delta_RT_2 -= delta_t_2

            #print("delta_rt is {}".format(delta_RT))

            inner_cost = w1 * (ddist) + w2 * delta_RT + w3 * delta_WT
            total_cost = outer_cost + inner_cost
            if total_cost < min_cost:
                min_cost = total_cost
                min_indices = (ix, ix2)
                min_chks = (nxt_chk, delta_t, nxt_chk_2, delta_t_2)
    
    if min_indices is not None:
        ix1, ix2 = min_indices
        bus.passengers_assigned[demand.id] = demand
        bus.stops_remaining.insert(ix1 + ix2, demand.d)
        bus.stops_remaining.insert(ix1, demand.o)
        bus.avail_slack_times[min_chks[0].id] -= min_chks[1]
        bus.avail_slack_times[min_chks[2].id] -= min_chks[3]
        #print("bus {} has st {} before {}".format(bus.id, bus.avail_slack_times[min_chks[0].id], min_chks[0].id))
        #print("bus {} has st {} before {}".format(bus.id, bus.avail_slack_times[min_chks[2].id], min_chks[2].id))
        #print("stops remaining is {}".format(bus.stops_remaining))

    return min_indices
Esempio n. 13
0
def check_origin_walk(demand, bus, t, chkpts, sim, dest):
    #add current location to as a fake stop
    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    add_faux = [faux_stop] + bus.stops_remaining
    start_index = 0
    end_index = 0
    for ix, s in enumerate(add_faux):
        if s.dep_t:
            if demand.o.xy.x > s.xy.x:
                start_index = end_index
                end_index = ix
            else:
                start_index = end_index
                end_index = ix
                break
    #get the cost for each demand to walk to each stop
    costs_by_stop = {}
    for ix, (cur_stop, next_stop) in enumerate(zip(add_faux[start_index:end_index], bus.stops_remaining[start_index:end_index])):
        nxt_chk = None;
        #next checkpoint for slack time calculations
        for s in bus.stops_remaining[ix:]:
            if s.dep_t:
                nxt_chk = s
                break
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)
        if st < 0:
            continue
        #check distance and arrival times
        ddist, ddist_x, ddist_y = stats.check_distance(demand.o, cur_stop, next_stop)
        max_walk_dist = stats.get_max_walk_distance(bus, demand.d, t, chkpts, sim)
        max_drive_dist = max((st - cf.WAITING_TIME) * (cf.BUS_SPEED / 3600), 0)
        max_distance_possible = max_walk_dist + max_drive_dist
        if ddist <= max_distance_possible:
            xdist, ydist = stats.calculate_closest_walk(demand.o, cur_stop, next_stop)
            #prioritizes the longer distance
            if ddist_y < ddist_x:
                walk_dist = ddist_x - max_drive_dist
                new_o = Point(demand.o.xy.x +  np.sign(xdist)* walk_dist,
                              demand.o.xy.y + np.sign(ydist) * np.min([max_walk_dist - walk_dist, ddist_y]))
            else:
                #prioritizes driving over walking
                walk_dist = ddist_y - max_drive_dist
                new_o = Point(demand.o.xy.x +  np.sign(xdist)* np.min([max_walk_dist - walk_dist, ddist_x]),
                              demand.o.xy.y + np.sign(ydist) * walk_dist)
            walk_arr_t = t + (np.abs(new_o.x - demand.o.xy.x) + np.abs(new_o.y - demand.o.xy.y)) / (cf.W_SPEED / 3600.)
            ####BUS ARRIAVAL TIME
            if (t < 0):              
                prev_t = 0
            else:
                prev_t = t

            bus_arr_t = prev_t + stats.get_bus_arrival_time(new_o, bus, add_faux, start_index, ix)
            if bus_arr_t < walk_arr_t:
                pass
            else: 
                #record cost of walking to this new stop
                new_o_stop = stop.Stop(sim.next_stop_id, new_o, "walk", None)
                sim.next_stop_id += 1
                ddist, x, y = stats.added_distance(new_o_stop, cur_stop, next_stop)
                delta_t = cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)
                if (not stats.check_feasible(x, y, delta_t, st)):
                    continue
                min_cost = stats.calculate_cost(bus, nxt_chk, ix, delta_t, ddist)
                costs_by_stop[new_o_stop.id] =  (new_o_stop, ix, min_cost, (nxt_chk, delta_t), walk_arr_t)
                if (ix >= len(bus.stops_remaining) or ix < 0):
                    import pdb; pdb.set_trace();
                    
    #compare all available stops to find minimum cost one.
    min_ix = None
    min_stop = None
    min_nxt_chk = None
    min_cost = 9999
    min_time = None
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]
            min_time = walk_arr_t - t
    #debugging
    if (min_stop):
        print("WALK || " + str(min_stop.xy.x) + "," + str(min_stop.xy.y) + "cost: " + str(min_cost))
    return (min_cost, min_stop, min_ix, min_nxt_chk, min_time)
def check_destination_walk(demand, bus, t, chkpts, sim, ori):
    stops_remaining = bus.stops_remaining
    start_index = 0
    extra = 0

    if (ori):
        t_now = t - bus.start_t
        #check we are not past origin point
        if ori.typ == "chk" and t_now > ori.dep_t:
            return (None, None, None, None)
    for ix, s in enumerate(add_faux):
        if s.dep_t:
            if demand.o.xy.x > s.xy.x:
                end_index = ix
            else:
                break
    ix = end_index
    while ix > 0:
        ix -= 1
        if add_faux[ix].dep_t:
            start_index = ix
            if start_index == 0:
                stops_remaining = [bus.stops_visited[-1]] + bus.stops_remaining
                exta = -1
            break

    costs_by_stop = {}
    #methodology is identical to origin walking
    for ix, (cur_stop, next_stop) in enumerate(
            zip(stops_remaining[start_index:end_index - 1],
                stops_remaining[start_index + 1:end_index])):
        nxt_chk = None
        for s in stops_remaining[start_index + ix:]:
            if s.dep_t:
                nxt_chk = s
                break
        if (nxt_chk == None):
            import pdb
            pdb.set_trace()
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)
        ddist, daqx, dqbx = stats.added_distance(demand.d, cur_stop, next_stop)
        if st < 0:
            continue
        elif (daqx < 0 and np.abs(daqx) > cf.MAX_BACK):
            continue
        elif (dqbx < 0 and np.abs(dqbx) > cf.MAX_BACK):
            continue
        ddist, ddist_x, ddist_y = stats.check_distance(demand.d, cur_stop,
                                                       next_stop)
        walk_dir = 'x' if ddist_x > ddist_y else ddist_y
        max_walk_dist = stats.get_max_walk_distance(bus, demand.d, t, chkpts,
                                                    sim)
        max_drive_dist = (st - cf.WAITING_TIME) * (cf.BUS_SPEED / 3600)
        max_distance_possible = max_walk_dist * 2 + max_drive_dist
        if ddist <= max_distance_possible:
            xdist, ydist = stats.calculate_closest_walk(
                demand.d, cur_stop, next_stop)
            if walk_dir == 'x':
                dist = min(ddist_x, xdist)
                walk_dist = np.sign(dist) * (np.abs(dist - max_drive_dist / 2))
                new_d = Point(
                    demand.d.xy.x + np.sign(ddist_x) * walk_dist,
                    demand.d.xy.y + np.sign(ddist_y) * np.abs(
                        np.min(
                            [max_walk_dist - walk_dist,
                             min(ddist_y, ydist)])))
            else:
                dist = min(ddist_y, ydist)
                walk_dist = np.sign(dist) * (np.abs(dist - max_drive_dist / 2))
                new_d = Point(
                    demand.d.xy.x + np.sign(ddist_x) * np.abs(
                        np.min(
                            [max_walk_dist - walk_dist,
                             min(ddist_x, xdist)])),
                    demand.d.xy.y + np.sign(ddist_y) * walk_dist)
            walk_arr_t = t + (np.abs(new_d.x - demand.d.xy.x) +
                              np.abs(new_d.y - demand.d.xy.y)) / (cf.W_SPEED /
                                                                  3600.)
            bus_arr_t = t + bus.hold_time + (
                np.abs(cur_stop.xy.x - new_d.x) +
                np.abs(new_d.y - cur_stop.xy.y)) / (cf.BUS_SPEED / 3600.)
            if bus_arr_t > walk_arr_t:
                new_d_stop = stop.Stop(sim.next_stop_id, new_d, "walk", None)
                sim.next_stop_id += 1
                ddist, x, y = stats.added_distance(new_d_stop, cur_stop,
                                                   next_stop)
                delta_t = cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)
                if (not stats.check_feasible(x, y, delta_t, st)):
                    continue
                min_cost = stats.calculate_cost(bus, nxt_chk, ix + start_index,
                                                delta_t, ddist)
                costs_by_stop[new_d_stop.id] = (new_d_stop,
                                                ix + start_index + extra,
                                                min_cost, (nxt_chk, delta_t),
                                                walk_arr_t - t)

    min_ix = None
    min_stop = None
    min_nxt_chk = None
    min_cost = 9999
    min_t = None
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]
            min_t = v[4]
    if (min_ix and min_ix + 1 >= len(stops_remaining)):
        import pdb
        pdb.set_trace()
    if (min_stop):
        print("WALK || MAX: " + str(max_walk_dist))
    return (min_cost, min_stop, min_ix, min_nxt_chk, min_t)
def rpd_merge_walk(demand, bus, t, chkpts, sim):
    #when we are merging stops together we do not want to merge with the faux stop.
    try:
        #finds the last index where the demand is
        max_possible_ix = bus.stops_remaining.index(demand.d)
    # weve already passed their checkpoint, not possible
    except ValueError:
        return None

    costs_by_stop = {}
    #check all other stops as candidates for merging
    for index, merge_stop in enumerate(bus.stops_remaining[:max_possible_ix]):
        #cannot merge with checkpoints
        if (merge_stop.dep_t):
            continue
        if (index == 0):
            # if it is the first stop, then treat the current location as the previous stop
            prev_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
        else:
            prev_stop = bus.stops_remaining[index - 1]

        nxt_chk = None
        for s in bus.stops_remaining[index:]:
            if s.dep_t:
                nxt_chk = s
                break
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts) - cf.WAITING_TIME
        if st < 0:
            continue

        ddist_x = demand.o.xy.x - merge_stop.xy.x
        ddist_y = demand.o.xy.y - merge_stop.xy.y
        ddist = np.sum(np.abs([ddist_x, ddist_y]))

        # initial walk direction - pick the shortest walking direction
        max_walk_dist = cf.W_SPEED * (cf.MAX_WALK_TIME / 60
                                      )  # mph * (1 hr / 60 min)

        max_distance_possible = max_walk_dist * 2  #Furthest two stops may be brought together.
        if ddist > max_distance_possible:
            pass
        else:
            new_o = Point(demand.o.xy.x + np.sign(ddist_x) * ddist_x / 2,
                          demand.o.xy.y + np.sign(ddist_y) * ddist_y / 2)
            walk_arr_t = t + (np.abs(new_o.x - demand.o.xy.x) +
                              np.abs(new_o.y - demand.o.xy.y)) / (cf.W_SPEED /
                                                                  3600.)
            bus_arr_t = t + bus.hold_time + (
                np.abs(new_o.x - prev_stop.xy.x) +
                np.abs(new_o.y - prev_stop.xy.y)) / (cf.BUS_SPEED / 3600.)
            if bus_arr_t <= walk_arr_t:
                pass
            else:
                new_o_stop = stop.Stop(sim.next_stop_id, new_o, "walk", None)
                sim.next_stop_id += 1
                old_o = demand.o
                demand.o = new_o_stop
                result = ins.feasible(demand, bus, t, chkpts, cost_only=True)
                if result:
                    min_ix, min_cost, min_nxt_chk = result
                    costs_by_stop[new_o_stop.id] = (new_o_stop, min_ix,
                                                    min_cost, min_nxt_chk,
                                                    bus_arr_t, walk_arr_t)
                demand.o = old_o
    min_ix = None
    min_stop = None
    min_nxt_chk = None
    min_cost = 9999
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]
            #make sure it was feasible
            print("MERGE || Bus Time: " + str(v[4]) + ", Walk Time: " +
                  str(v[5]))

    return (min_cost, min_stop, min_ix, min_nxt_chk)
Esempio n. 16
0
def prd_walk(demand, bus, t, chkpts, sim):
    t_now = t - bus.start_t
    # weve already passed this stop
    if t_now > demand.o.dep_t:
        return None
    try:
        earliest_ix = bus.stops_remaining.index(demand.o)
    except ValueError:
        earliest_ix = -1

    if earliest_ix == -1:
        stops_slice = [bus.stops_visited[-1]] + bus.stops_remaining
    else:
        stops_slice = bus.stops_remaining[earliest_ix:]

    costs_by_stop = {}
    for ix, (cur_stop,
             next_stop) in enumerate(zip(stops_slice, stops_slice[1:])):
        nxt_chk = None
        for s in bus.stops_remaining[ix:]:
            #if it is a checkpoint (finds the enxt checkpoint)
            if s.dep_t:
                nxt_chk = s
                break

        st = bus.usable_slack_time(t, nxt_chk.id, chkpts) - cf.WAITING_TIME
        if st < 0:
            continue
        ddist, ddist_x, ddist_y = check_distance(demand.d, cur_stop, next_stop)

        walk_dir = 'x' if ddist_x > ddist_y else ddist_y
        max_walk_dist = cf.W_SPEED * (cf.MAX_WALK_TIME / 60
                                      )  # mph * (1 hr / 60 min)
        max_drive_dist = st * (cf.BUS_SPEED / 3600)

        xdist, ydist = calculate_closest_walk(demand.d, cur_stop, next_stop)
        if walk_dir == 'x':
            walk_dist = min(ddist_x, xdist) - max_drive_dist
            new_d = Point(
                demand.d.xy.x + np.sign(ddist_x) * walk_dist,
                demand.d.xy.y + np.sign(ddist_y) *
                np.min([max_walk_dist - walk_dist,
                        min(ddist_y, ydist)]))
        else:
            walk_dist = min(ddist_y, ydist) - max_drive_dist
            new_d = Point(
                demand.d.xy.x + np.sign(ddist_x) *
                np.min([max_walk_dist - walk_dist,
                        min(ddist_x, xdist)]),
                demand.d.xy.y + np.sign(ddist_y) * walk_dist)
        walk_arr_t = t + (np.abs(new_d.x - demand.d.xy.x) +
                          np.abs(new_d.y - demand.d.xy.y)) / (cf.W_SPEED /
                                                              3600.)
        bus_arr_t = t + bus.hold_time + (np.abs(cur_stop.xy.x - new_d.x) +
                                         np.abs(new_d.y - cur_stop.xy.y)) / (
                                             cf.BUS_SPEED / 3600.)
        if bus_arr_t <= walk_arr_t:
            #print("Bus time: " + str( bus_arr_t) + ", Walk time: " + str(walk_arr_t))
            continue
        else:
            new_d_stop = stop.Stop(sim.next_stop_id, new_d, "walk", None)
            sim.next_stop_id += 1
            old_d = demand.d
            demand.d = new_d_stop
            #check that new stop is feasible
            result = ins.feasible(demand, bus, t, chkpts, cost_only=True)
            if result:
                min_ix, min_cost, min_nxt_chk = result
                costs_by_stop[new_d_stop.id] = (new_d_stop, min_ix, min_cost,
                                                min_nxt_chk, bus_arr_t,
                                                walk_arr_t)
            demand.d = old_d

    min_ix = None
    min_stop = None
    old_stop = None
    min_nxt_chk = None
    min_cost = 9999
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]
            print("Bus Time: " + str(v[4]) + ", Walk Time: " + str(v[5]))

    if min_stop:
        old_stop = demand.d
        demand.d = min_stop
        bus.stops_remaining.insert(min_ix, min_stop)
        bus.avail_slack_times[min_nxt_chk[0].id] -= min_nxt_chk[1]
        bus.passengers_assigned[demand.id] = demand
    return old_stop
Esempio n. 17
0
        channel = ctx.author.voice.channel
        video = Video(url)
        musics[ctx.guild] = []
        client = await channel.connect()
        play_song(client, musics[ctx.guild], video)


@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        await ctx.send("Cette commande n'existe pas.")
    elif isinstance(error, commands.MissingRequiredArgument):
        await ctx.send("Il manque un argument.")
    elif isinstance(error, commands.MissingPermissions):
        await ctx.send(
            "Vous n'avez pas les permissions pour faire cette commande.")
    elif isinstance(error.original, discord.Forbidden):
        await ctx.send(
            "Je n'ai pas les permissions nécéssaires pour faire cette commmande"
        )


bot.add_cog(stop.Stop(bot))
bot.add_cog(skip.Skip(bot))
bot.add_cog(resume.Resume(bot))
bot.add_cog(pause.Pause(bot))
bot.add_cog(helpCommands.Help(bot))
bot.add_cog(moderation.Moderation(bot))

bot.run("TOKEN")
Esempio n. 18
0
def rpd_walk(demand, bus, t, chkpts, sim):
    #treat the bus's current location as a stop.
    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    #list of all current stops in the queue
    add_faux = [faux_stop] + bus.stops_remaining
    try:
        #finds the last index where the demand is
        max_possible_ix = add_faux.index(demand.d)
    # weve already passed their checkpoint, not possible
    except ValueError:
        return None

    costs_by_stop = {}
    #zips (all stops before last index, stops remaining) -> every consequtive pair
    for ix, (cur_stop, next_stop) in enumerate(
            zip(add_faux[:max_possible_ix], bus.stops_remaining)):

        nxt_chk = None
        for s in bus.stops_remaining[ix:]:
            #if it is a checkpoint (finds the enxt checkpoint)
            if s.dep_t:
                nxt_chk = s
                break
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts) - cf.WAITING_TIME
        if st < 0:
            continue
        ddist, ddist_x, ddist_y = check_distance(demand.o, cur_stop, next_stop)

        # initial walk direction
        walk_dir = 'x' if ddist_x > ddist_y else ddist_y
        max_walk_dist = cf.W_SPEED * (cf.MAX_WALK_TIME / 60
                                      )  # mph * (1 hr / 60 min)
        max_drive_dist = st * (cf.BUS_SPEED / 3600)
        # make sure we can actually cover the distance

        #[ASK] why was max_walk_dist multipled by 2
        max_distance_possible = max_walk_dist + max_drive_dist
        if ddist > max_distance_possible:
            #if it is beyond max distance, then we cannot walk there
            #print("Max distance is: " + str(max_distance_possible) + " ddist is {}".format(ddist))
            pass
        else:
            """
            if walk_dir == 'x':
                #walk distance is either halfway to the stop or its maximum walking distance
                walk_dist = np.min([ddist_x / 2, max_walk_dist])
                #if we have left over max walk distance, we can allow them to travel the y direction as well
                if walk_dist < max_walk_dist and ddist_y > 0:
                    new_o = Point(demand.o.xy.x +  np.sign(ddist_x)* walk_dist,
                                  demand.o.xy.y + np.sign(ddist_y) * np.min([max_walk_dist - walk_dist, ddist_y]))
                else:
                    new_o = Point(demand.o.xy.x +  np.sign(ddist_x)* walk_dist, demand.o.xy.y)
            else:
                walk_dist = np.min([ddist_y / 2, max_walk_dist])
                if walk_dist < max_walk_dist and ddist_x > 0:
                    new_o = Point(demand.o.xy.x +  np.sign(ddist_x)* walk_dist,
                                  demand.o.xy.y + np.sign(ddist_y) * np.min([max_walk_dist - walk_dist, ddist_y / 2]))
                else:
                    new_o = Point(demand.o.xy.x,
                                  np.sign(ddist_y)* walk_dist +  demand.o.xy.y)
            """
            #distance from the stops
            #ddist_x/ddist_y is accurate when the demand in inbetween the two stops.
            #xdist/ydist is accurate when the demand falls outside the bounds.
            xdist, ydist = calculate_closest_walk(demand.o, cur_stop,
                                                  next_stop)
            if walk_dir == 'x':
                #the stop is not currently feasible so we will have to walk the difference
                walk_dist = min(ddist_x, xdist) - max_drive_dist
                #if we have left over max walk distance, we can allow them to travel the y direction as well
                new_o = Point(
                    demand.o.xy.x + np.sign(ddist_x) * walk_dist,
                    demand.o.xy.y + np.sign(ddist_y) *
                    np.min([max_walk_dist - walk_dist,
                            min(ddist_y, ydist)]))
            else:
                walk_dist = min(ddist_y, ydist) - max_drive_dist
                new_o = Point(
                    demand.o.xy.x + np.sign(ddist_x) *
                    np.min([max_walk_dist - walk_dist,
                            min(ddist_x, xdist)]),
                    demand.o.xy.y + np.sign(ddist_y) * walk_dist)

            walk_arr_t = t + (np.abs(new_o.x - demand.o.xy.x) +
                              np.abs(new_o.y - demand.o.xy.y)) / (cf.W_SPEED /
                                                                  3600.)
            #TODO: make sure that the walker arrives before the bus
            # what we need to write is something that computes exactly
            # when the bus would arrive based on where we are inserting this
            # stop.
            # THIS IS CURRENTLY BROKEN & only works for this test example!!
            bus_arr_t = t + bus.hold_time + (
                np.abs(cur_stop.xy.x - new_o.x) +
                np.abs(new_o.y - cur_stop.xy.y)) / (cf.BUS_SPEED / 3600.)
            if bus_arr_t <= walk_arr_t:
                #The passenger is there after the bus leaves
                #print("Bus time: " + str( bus_arr_t) + ", Walk time: " + str(walk_arr_t))
                pass
            else:
                new_o_stop = stop.Stop(sim.next_stop_id, new_o, "walk", None)
                sim.next_stop_id += 1
                old_o = demand.o
                demand.o = new_o_stop
                #check that new stop is feasible
                result = ins.feasible(demand, bus, t, chkpts, cost_only=True)
                if result:
                    min_ix, min_cost, min_nxt_chk = result
                    costs_by_stop[new_o_stop.id] = (new_o_stop, min_ix,
                                                    min_cost, min_nxt_chk,
                                                    bus_arr_t, walk_arr_t)
                demand.o = old_o

    min_ix = None
    min_stop = None
    min_nxt_chk = None
    min_cost = 9999
    for k, v in costs_by_stop.items():
        if v[2] < min_cost:
            min_stop = v[0]
            min_ix = v[1]
            min_cost = v[2]
            min_nxt_chk = v[3]

            print("WALK || Bus Time: " + str(v[4]) + ", Walk Time: " +
                  str(v[5]))

    # we return the old stop for visualization purposes.
    # when we plot, the passengers 'o' has been set to
    # the new origin, so we want to plot where they initially
    # were before they walked
    return (min_cost, min_stop, min_ix, min_nxt_chk)
def rpd_feasible(demand, bus, t, chkpts, cost_only=False):
    faux_stop = stop.Stop(-1, bus.cur_xy, "fake", None)
    add_faux = [faux_stop] + bus.stops_remaining
    try:
        max_possible_ix = add_faux.index(demand.d)
    # weve already passed their checkpoint, not possible
    except ValueError:
        return None

    min_cost = 99999999
    min_ix = None
    min_nxt_chk = None
    # now consider inserting between every stop
    for ix, (cur_stop, next_stop) in enumerate(
            zip(add_faux[:max_possible_ix], bus.stops_remaining)):

        ddist, daqx, dqbx = check_distance(demand.o, cur_stop, next_stop)

        # WAITING_TIME: there is an amount of time that the bus
        # spends sitting at each stop while the passenger
        # loads and unloads
        delta_t = cf.WAITING_TIME + ddist / (cf.BUS_SPEED / 3600)

        # now, get the next checkpoint based on where
        # we're trying to insert this stop
        nxt_chk = None
        for s in bus.stops_remaining[ix:]:
            # you could also use the stop 'typ' here
            # but only checkpoints get instantiated
            # with a dep_t value
            if s.dep_t:
                nxt_chk = s
                break

        # first: make sure we have enough slack time
        st = bus.usable_slack_time(t, nxt_chk.id, chkpts)
        #print("st is {}".format(st))
        if delta_t > st:
            continue

        # c2, c3: backtracking
        if daqx < 0 and np.abs(daqx) > cf.MAX_BACK:
            continue

        if dqbx < 0 and np.abs(dqbx) > cf.MAX_BACK:
            continue
        # now we have confirmed its feasible, compute cost

        cost = calculate_cost(bus, nxt_chk, ix, delta_t, ddist)
        if cost < min_cost:
            min_cost = cost
            min_ix = ix
            min_nxt_chk = (nxt_chk, delta_t)

    # TODO: each function will need a cost_only parameter
    # to check for walking w/o altering state
    if min_ix is not None and not cost_only:
        bus.passengers_assigned[demand.id] = demand
        bus.stops_remaining.insert(min_ix, demand.o)
        bus.avail_slack_times[min_nxt_chk[0].id] -= min_nxt_chk[1]
        #print("bus {} has st {} before {}".format(bus.id, bus.avail_slack_times[min_nxt_chk[0].id], min_nxt_chk[0].id))
        #print("stops remaining is {}".format(bus.stops_remaining))
    elif min_ix is None:
        return None

    return min_ix, min_cost, min_nxt_chk
Esempio n. 20
0
def query(input_date, input_route):

    # TO DO: Implement exception handling!
    F_dates = open("data/calendar_dates.txt", 'rt')
    reader_dates = csv.reader(F_dates)
    F_trips = open("data/trips.txt", 'rt')
    reader_trips = csv.reader(F_trips)
    F_times = open("data/stop_times.txt", 'rt')
    reader_times = csv.reader(F_times)
    F_stops = open("data/stops.txt", 'rt')
    reader_stops = csv.reader(F_stops)

    # Make sure the date is in range.
    for date in reader_dates:
        if input_date == date[0]: break
    if input_date != date[0]:
        return "Error: Date out of range"

    out_date_blocks = "output/trips/" + input_date + "_trips.txt"
    F_date_blocks = open(out_date_blocks, 'w')
    writer_date_blocks = csv.writer(F_date_blocks)
    out_date_stops = "output/stops/" + input_date + "_stops.txt"
    F_date_stops = open(out_date_stops, 'w')
    writer_date_stops = csv.writer(F_date_stops)

    trip = next(reader_trips)
    times1 = next(reader_times)
    stop = next(reader_stops)
    # Write headers
    writer_date_blocks.writerow([
        trip[6], trip[2], trip[5], trip[3], "origin", times1[2], "destination",
        times1[1]
    ])  # Header
    writer_date_stops.writerow(
        [stop[0], stop[1], times1[2], times1[4], stop[2], stop[3]])
    times1 = next(reader_times)

    blocks = []  # List of blocks
    temp_block = b.Block()  # A single block element
    trip_count = 0
    for trip in reader_trips:
        # Move to the selected date
        if input_date != "" and trip[1] != input_date: continue

        trip_count += 1
        new_trip = t.Trip(trip[6], trip[2], trip[5], trip[3], "", "", "", "",
                          trip[7])
        temp_stop_list = []

        while times1[0] != trip[2]:
            times2 = times1
            try:
                times1 = next(reader_times)
            except StopIteration:
                break

        # Only interested in the stop times at the origin and destination.
        # Since stop times are listed in reverse chronological order,
        # the first line for each trip is the arrival time,
        # and the last line for each trip is the departure time.
        arrival = times1[1]
        destin_id = times1[3]
        while times1[0] == trip[2]:
            new_stop = s.Stop(times1[3], "", times1[2], times1[4], "", "")
            temp_stop_list.insert(0, new_stop)
            times2 = times1
            try:
                times1 = next(reader_times)
            except StopIteration:
                break
        depart = times2[1]
        origin_id = times2[3]

        origin = "null"
        destin = "null"

        while origin == "null" or destin == "null" or len(temp_stop_list) != 0:
            try:
                stop = next(reader_stops)
                if stop[0] == origin_id: origin = stop[1]
                if stop[0] == destin_id: destin = stop[1]
                for temp_stop in temp_stop_list:
                    if stop[0] == temp_stop.stop_id:
                        temp_stop_list.remove(temp_stop)
                        temp_stop.stop_name = stop[1]
                        temp_stop.lat = stop[2]
                        temp_stop.lon = stop[3]
                        new_trip.add_stop_ref(temp_stop)
            except StopIteration:
                F_stops.seek(0)

        new_trip.update_origin(origin, depart)
        new_trip.update_destin(destin, arrival)

        if temp_block.get_bid() == "null" or temp_block.get_bid() == trip[6]:
            temp_block.add_trip_ref(new_trip)
        else:
            blocks.insert(0, temp_block)
            temp_block = b.Block()
            temp_block.add_trip_ref(new_trip)
    # Make sure to add the last block
    blocks.insert(0, temp_block)

    for block in blocks:
        block.write_block(writer_date_blocks)
        block.write_stops(writer_date_stops)

    F_dates.close()
    F_trips.close()
    F_times.close()
    F_stops.close()
    F_date_blocks.close()
    F_date_stops.close()

    return ("Found %d trips. Check output folder." % (trip_count))