def find_shortest_path(cls, net, depart_time, start, end=None): if end != None and start == end: return {end.id: (None, 0.0, depart_time)} # creater a FIFO queue for searching queue = deque() # create containers with default values cost = defaultdict(constant_factory(float('+inf'))) time = defaultdict(constant_factory(float('+inf'))) prev = defaultdict(None) # set values for the start node cost[start.id] = 0.0 time[start.id] = depart_time queue.appendleft(start.id) # continue until the queue is empty while len(queue) > 0: # pop out the first object in the queue qtop = queue.pop() node = net.nodes[qtop] # relax each adjacent edges for edge in node.adj_edges: # get the traffic flow on the edge if Time.lessthan_maxtick(time[node.id]): edge_flow = net.flows[edge.id][time[node.id]] else: edge_flow = 0.0 # if the relaxation makes a shorter path travel_time = edge.calc_travel_time(edge_flow) travel_cost = edge.calc_travel_cost(travel_time) if cost[edge.tail.id] > cost[node.id] + travel_cost: # then update cost and time labels cost[edge.tail.id] = cost[node.id] + travel_cost time[edge.tail.id] = time[node.id] + travel_time # and save the edge on the shortest path prev[edge.tail.id] = edge # and append the expanded node to the queue queue.appendleft(edge.tail.id) # if end node is given, extract the shortest path to end node recursively if end != None: # if the end node is reached, there is at least one path # if the end node is not reached, the start and end nodes are not connected path = cls.create_shortest_path(start, end, prev, time) if end.id in prev else None return {end.id: (path, cost[end.id], time[end.id])} else: # if end node is not given, extract the shortest paths from start to all the other nodes paths = cls.create_all_shortest_paths(start, prev, time) # no path is defined for a ring and the travel time/cost is zero tuples = {start.id: (None, 0.0, depart_time)} for id_ in paths: # wrap the path, cost and time in a tuple # note that time[id_] is the arrival time at node[id_] # that is, time[id_] = depart_time + travel_time tuples[id_] = (paths[id_], cost[id_], time[id_]) return tuples
def individual_schedule(cls, demand, network, land, router, population): # save in-home activity into a local variable home = demand.activities["home"] for hh in population.households[:2]: if hh.id % 100 == 0: print " %d." % hh.id logger.info((hh, hh.program)) for person in itertools.chain(hh.adults, hh.children): logger.info((person, person.program, person.get_residence())) # save the person's residence into a local variable residence = person.get_residence() # a dict with default value +inf state_utils = defaultdict(constant_factory(float('-inf'))) # initialize the absorbing states for elapsed in xrange(Time.MAXTICK + 1): if home.within_time_window(Time.MAXTICK - elapsed): # absorbing states consists of maximum tick and in-home activity absorbing_state = (Time.MAXTICK, home, residence, elapsed, None, None) state_utils[absorbing_state] = 0.0 for state in cls.individual_states(person, land): tick, activity, position, elapsed, joint, todo = state # logger.debug(("state:", state)) for trans in cls.individual_transitions( person, network, land, router, *state): next_activity, destination, path, travel_cost, arrival_time = trans # logger.debug(("trans:", trans)) # elapsed time depends on the activity transition if next_activity == activity and position == destination: next_elapsed = elapsed + 1 else: next_elapsed = 0 # transition to the next state next_state = (arrival_time, next_activity, destination, next_elapsed, None, None) # logger.debug(("next state:", next_state)) # skip, if the arrival time is too late or the state is not feasible if arrival_time > Time.MAXTICK or next_state not in state_utils: continue # get activity utility activity_util = demand.get_activity_util( activity, tick, elapsed) # calculate state utility state_util = activity_util - travel_cost + Config.discount * state_utils[ next_state] # the maximum state utility and the associated choice if state_utils[state] < state_util: state_utils[state] = state_util person.transitions[state] = next_state # logger.debug(pformat(person.transitions)) # the initial state starts at the mid night and in home current_state = (0, home, residence, 0, None, None) person.states.append(current_state) while current_state[0] < Time.MAXTICK: current_state = person.transitions[current_state] person.states.append(current_state) logger.info(pformat(person.states))
def individual_schedule(cls, demand, network, land, router, population): # save in-home activity into a local variable home = demand.activities["home"] for hh in population.households[:2]: if hh.id % 100 == 0: print " %d." % hh.id logger.info((hh, hh.program)) for person in itertools.chain(hh.adults, hh.children): logger.info((person, person.program, person.get_residence())) # save the person's residence into a local variable residence = person.get_residence() # a dict with default value +inf state_utils = defaultdict(constant_factory(float('-inf'))) # initialize the absorbing states for elapsed in xrange(Time.MAXTICK + 1): if home.within_time_window(Time.MAXTICK - elapsed): # absorbing states consists of maximum tick and in-home activity absorbing_state = (Time.MAXTICK, home, residence, elapsed, None, None) state_utils[absorbing_state] = 0.0 for state in cls.individual_states(person, land): tick, activity, position, elapsed, joint, todo = state # logger.debug(("state:", state)) for trans in cls.individual_transitions(person, network, land, router, *state): next_activity, destination, path, travel_cost, arrival_time = trans # logger.debug(("trans:", trans)) # elapsed time depends on the activity transition if next_activity == activity and position == destination: next_elapsed = elapsed + 1 else: next_elapsed = 0 # transition to the next state next_state = (arrival_time, next_activity, destination, next_elapsed, None, None) # logger.debug(("next state:", next_state)) # skip, if the arrival time is too late or the state is not feasible if arrival_time > Time.MAXTICK or next_state not in state_utils: continue # get activity utility activity_util = demand.get_activity_util(activity, tick, elapsed) # calculate state utility state_util = activity_util - travel_cost + Config.discount * state_utils[next_state] # the maximum state utility and the associated choice if state_utils[state] < state_util: state_utils[state] = state_util person.transitions[state] = next_state # logger.debug(pformat(person.transitions)) # the initial state starts at the mid night and in home current_state = (0, home, residence, 0, None, None) person.states.append(current_state) while current_state[0] < Time.MAXTICK: current_state = person.transitions[current_state] person.states.append(current_state) logger.info(pformat(person.states))