def assign(): print('\nBaseline Assignments') N = env.traci.vehicle.getIDCount() M = len(env.target_nodes) for n in range(N): # Determine which target is the least far away cost = [float(env.dist.cost(n, m)) for m in range(M)] min_cost = min(cost) itar = None for i, c in enumerate(cost): if c == min_cost: itar = i break continue print("Veh=%d Tar=%d Cost=%.3f" % (n, itar, min_cost)) # Then assign the route veh = env.vehicles_active[n] path = dict() # Path veh --> target path_veh2tar = dict() tar = env.target_nodes[itar] path_veh2tar['nids'] = nx.dijkstra_path(env.nx, veh['current edge']['to'], tar['id']) path_veh2tar['nids'].insert(0, veh['current edge']['from']) path_veh2tar['weight'], path_veh2tar['eids'] = nxops.path_info( env.nx, path_veh2tar['nids']) # path target --> dest path_tar2dest = dict() path_tar2dest['nids'] = nx.dijkstra_path(env.nx, tar['id'], veh['destination node']['id']) path_tar2dest['weight'], path_tar2dest['eids'] = nxops.path_info( env.nx, path_tar2dest['nids']) # Combine together path['nids'] = purr.flattenlist( [path_veh2tar['nids'], path_tar2dest['nids']]) path['weight'] = path_veh2tar['weight'] + path_tar2dest['weight'] path['eids'] = purr.flattenlist( [path_veh2tar['eids'], path_tar2dest['eids']]) # Update vehicle tracking data index = int(veh['id'][3:]) env.vehicles[index]['target nid'] = tar['id'] env.vehicles[index]['target eid'] = path['eids'][path['nids'].index( tar['id'])] env.vehicles[index]['diversion path length'] = path['weight'] env.vehicles[index]['shortest path length'] = veh['veh2dest weight'] # Route the vehicle with traci env.traci.vehicle.setRoute(veh['id'], path['eids']) continue print("Complete!") return
def set_route(tA): cDest = tA[0] utilities = tA[1] # Use this info to route. for x in range(env.nash_assigner.N): print('Veh=%d Tar=%.0f Util=%.3f'%(x,cDest[x],utilities[x])) veh = env.vehicles_active[x] path = dict() # Not worth the effort. Go home if np.isnan(cDest[x]): path['nids'] = nx.dijkstra_path(env.nx,veh['current edge']['to'],veh['destination node']['id']) path['nids'].insert(0,veh['current edge']['from']) path['weight'] , path['eids'] = nxops.path_info(env.nx,path['nids']) # Otherwise, go to the target else: # Path veh --> target path_veh2tar = dict() tar = env.target_nodes[int(cDest[x])] path_veh2tar['nids'] = nx.dijkstra_path(env.nx,veh['current edge']['to'],tar['id']) path_veh2tar['nids'].insert(0,veh['current edge']['from']) path_veh2tar['weight'] , path_veh2tar['eids'] = nxops.path_info(env.nx,path_veh2tar['nids']) # path target --> dest path_tar2dest = dict() path_tar2dest['nids'] = nx.dijkstra_path(env.nx,tar['id'],veh['destination node']['id']) path_tar2dest['weight'], path_tar2dest['eids'] = nxops.path_info(env.nx,path_tar2dest['nids']) # Combine together path['nids'] = purr.flattenlist([path_veh2tar['nids'],path_tar2dest['nids']]) path['weight'] = path_veh2tar['weight'] + path_tar2dest['weight'] path['eids'] = purr.flattenlist([path_veh2tar['eids'],path_tar2dest['eids']]) # Update vehicle tracking data index = int(veh['id'][3:]) env.vehicles[index]['target nid'] = tar['id'] env.vehicles[index]['target eid'] = path['eids'][path['nids'].index(tar['id'])] env.vehicles[index]['diversion path length'] = path['weight'] env.vehicles[index]['shortest path length'] = veh['veh2dest weight'] # Route the vehicle with traci try: env.traci.vehicle.setRoute(veh['id'],path['eids']) except env.traci.TraCIException: pass continue return
def shortest_path(iveh): src = env.vPs[iveh] dst = env.vPd[iveh] shortest_path = {'weight':None,'nids':None,'eids':None} shortest_path['nids'] = nx.dijkstra_path(env.nx,src['id'],dst['id']) shortest_path['weight'], shortest_path['eids'] = nxops.path_info(env.nx,shortest_path['nids']) return shortest_path
def random_shortest_path(): # Selected a path. It must be have a conenction between spawn and sink ntrys = 0 shortest_path = { 'weight': None, 'nids': None, 'eids': None } while True: # Pick a random spawn and sink edge spawn_edge = random.choice(env.spawn_edge) sink_edge = random.choice(env.sink_edge) # Determine the shortest path try: shortest_path['nids'] = nx.dijkstra_path(env.nx, spawn_edge['from'], sink_edge['to']) break except nx.NetworkXNoPath: ntrys += 1 print( "Cannont create a path between %s and %s... Trying again (%d)." % (spawn_edge['from'], sink_edge['to'], ntrys)) continue # At this point, it is assumed that the path is connected # Now the weight of the path and the edge eids of the path is determined shortest_path['weight'], shortest_path['eids'] = nxops.path_info( env.nx, shortest_path['nids']) return shortest_path
def add_nash(traci): # Vehicle ID vid = "veh%d" % (env.veh_id_counter) env.veh_id_counter += 1 # Selected a path. It must be have a conenction between spawn and sink ntrys = 0 shortest_path = { 'weight': None, 'nids': None, 'eids': None } while True: # Pick a random spawn and sink edge spawn_edge = random.choice(env.spawn_edge) sink_edge = random.choice(env.sink_edge) # Determine the shortest path try: shortest_path['nids'] = nxops.dijkstra(env.nx, spawn_edge['from'], sink_edge['to']) break except nx.NetworkXNoPath: ntrys += 1 print( "%s: Cannont create a path between %s and %s... Trying again (%d)." % (vid, spawn_edge['from'], sink_edge['to'], ntrys)) continue shortest_path['weight'], shortest_path['eids'] = nxops.path_info( env.nx, shortest_path['nids']) # Create a route with the path eids rid = "route%d" % (env.route_id_counter) env.route_id_counter += 1 traci.route.add(rid, shortest_path['eids']) # Add a vehicle traci.vehicle.add(vid, rid) # Add the destination node to list of sink nodes so it may be found later dest_node = purr.filterdicts(env.nodes, 'id', shortest_path['nids'][-1])[0] env.vehicles_dest.append(dest_node) # The nash equilibrium will have to be recalculated since another contestant is being introduced. env.recalculate_nash = True # Create the vehicle dictionary veh = { "id": vid, "source": spawn_edge['from'], "destination": sink_edge['to'], "shortest path length": shortest_path['weight'], "diversion path length": None, "sample time": None, "target nid": None, "target eid": None } env.vehicles.append(veh) return
def generate(colnames, rownames): weights = [] for irow, rn in enumerate(rownames): row = [] for icol, cn in enumerate(colnames): weight = float('inf') if not cn == rn: weight = nxops.path_info(env.nx, nx.dijkstra_path(env.nx, cn, rn))[0] row.append(weight) continue weights.append(row) continue spm = {'colnames': colnames, 'rownames': rownames, 'weights': weights} return spm
def generate(colnames, rownames): weights = [] n = 0 total = len(colnames) * len(rownames) for irow, rn in enumerate(rownames): row = [] for icol, cn in enumerate(colnames): weight = float('inf') if not cn == rn: weight = nxops.path_info(env.nx, nx.dijkstra_path(env.nx, cn, rn))[0] row.append(weight) n += 1 purr.update(n, total, "Generating SPM ") continue weights.append(row) continue spm = {'colnames': colnames, 'rownames': rownames, 'weights': weights} print() return spm
def get_assignments(): print("\nGetting Nash Assignments.") start = purr.now() # Get assigments index = env.traci.vehicle.getIDCount() - 1 t = env.nash_assigners[index].getAssignments() cDest = t[0] utilities = t[1] # Use this info to route. for x in range(env.nash_assigners[index].N): print('Veh=%d Tar=%.0f Util=%.3f' % (x, cDest[x], utilities[x])) veh = env.vehicles_active[x] path = dict() # Not worth the effort. Go home if np.isnan(cDest[x]): path['nids'] = nx.dijkstra_path(env.nx, veh['current edge']['to'], veh['destination node']['id']) path['nids'].insert(0, veh['current edge']['from']) path['weight'], path['eids'] = nxops.path_info( env.nx, path['nids']) # Otherwise, go to the target else: # Path veh --> target path_veh2tar = dict() tar = env.target_nodes[int(cDest[x])] path_veh2tar['nids'] = nx.dijkstra_path(env.nx, veh['current edge']['to'], tar['id']) path_veh2tar['nids'].insert(0, veh['current edge']['from']) path_veh2tar['weight'], path_veh2tar['eids'] = nxops.path_info( env.nx, path_veh2tar['nids']) # path target --> dest path_tar2dest = dict() path_tar2dest['nids'] = nx.dijkstra_path( env.nx, tar['id'], veh['destination node']['id']) path_tar2dest['weight'], path_tar2dest['eids'] = nxops.path_info( env.nx, path_tar2dest['nids']) # Combine together path['nids'] = purr.flattenlist( [path_veh2tar['nids'], path_tar2dest['nids']]) path['weight'] = path_veh2tar['weight'] + path_tar2dest['weight'] path['eids'] = purr.flattenlist( [path_veh2tar['eids'], path_tar2dest['eids']]) # Update vehicle tracking data index = int(veh['id'][3:]) env.vehicles[index]['target nid'] = tar['id'] env.vehicles[index]['target eid'] = path['eids'][ path['nids'].index(tar['id'])] env.vehicles[index]['diversion path length'] = path['weight'] env.vehicles[index]['shortest path length'] = veh[ 'veh2dest weight'] # Route the vehicle with traci env.traci.vehicle.setRoute(veh['id'], path['eids']) continue print("Complete after %.3f" % (purr.elapsed(start))) return
def update(): env.update_vehicle_info = False # Clean out the old object env.vehicles_active = [] # Refill total = len(env.vehicles) for i,v in enumerate(env.vehicles): veh = dict() # Who am I? veh['id'] = v['id'] # Where am I? veh['route index'] = env.traci.vehicle.getRouteIndex(veh['id']) # What is my route? veh['route id'] = env.traci.vehicle.getRouteID(veh['id']) # What is my sink node? veh['destination node'] = env.vehicles_dest[int(veh['id'][3:])] if veh['route index'] < 0: veh['route index'] = 0 veh['position on edge (m)'] = 0.000001 eid = env.traci.route.getEdges(veh['route id'])[0] else: # How far along the edge am I (m)? veh['position on edge (m)'] = env.traci.vehicle.getLanePosition(veh['id']) # What edge am I on? eid = env.traci.vehicle.getRoadID(veh['id']) # Obtain the edge object. Here we can have two cases: # 1. veh is at an intersection # 2. veh is on an edg # Veh is within an intersection. Assume the start of the next edge with a position on edge (m) of zero. if ':' in eid: veh['route'] = env.traci.route.getEdges(veh['route id']) eid = veh['route'][veh['route index']+1] veh['current edge'] = purr.filterdicts(env.edges,'id',eid)[0] veh['position on edge (m)'] = 0.000001 else: veh['current edge'] = purr.filterdicts(env.edges,'id',eid)[0] # How far am I along the edge (weight) veh['position on edge (s)'] = veh['position on edge (m)'] / float(veh['current edge']['speed']) # How much weight to the end of the edge? edge_candidates = env.nx.get_edge_data(veh['current edge']['from'],veh['current edge']['to']) for j in range(len(edge_candidates)): if veh['current edge']['id'] == edge_candidates[j]['id']: veh['weight remaining'] = edge_candidates[j]['weight'] - veh['position on edge (s)'] break continue # What is the weight of Veh --> Dest veh['veh2dest weight'] = veh['weight remaining'] + nxops.path_info(env.nx,nx.dijkstra_path(env.nx,veh['current edge']['to'],veh['destination node']['id']))[0] env.vehicles_active.append(veh) purr.update(i+1,total,"Updating vehicle location data ") # ~ env.recalculate_nash = True continue print() return
def recalculate(): env.recalculate_nash = False print() print("Retrieving spatial vehicle data...", end='') st = purr.now() vehicle.update_nash() print("Complete after %.3fs" % (purr.elapsed(st))) print("Recalculating target assignments...", end='') st = purr.now() N = len(env.vids_active) - 1 # ~ N = 10 env.nash_assigner = sysSim.nashAssigner(N=N, M=len(env.targets), R=200, tau=1, dist=env.dist) t = env.nash_assigner.getAssignments() print("Complete after %.3fs" % (purr.elapsed(st))) cDest = t[0] utilities = t[1] # ~ print('Assigining vehicles to new targets.') for x in range(env.nash_assigner.N): # ~ print('vehicle,target,utililty: (%d,%.0f,%.3f)'%(x,cDest[x],utilities[x])) veh = env.vehicles_active[x] path = dict() # Not worth the effort. Go home if np.isnan(cDest[x]): path['nids'] = nxops.dijkstra(env.nx, veh['current edge']['to'], veh['destination node']['id']) path['nids'].insert(0, veh['current edge']['from']) path['weight'], path['eids'] = nxops.path_info( env.nx, path['nids']) # Otherwise, go to the target else: # Path veh --> target path_veh2tar = dict() tar = env.target_nodes[int(cDest[x])] path_veh2tar['nids'] = nxops.dijkstra(env.nx, veh['current edge']['to'], tar['id']) path_veh2tar['nids'].insert(0, veh['current edge']['from']) path_veh2tar['weight'], path_veh2tar['eids'] = nxops.path_info( env.nx, path_veh2tar['nids']) # path target --> dest path_tar2dest = dict() path_tar2dest['nids'] = nxops.dijkstra( env.nx, tar['id'], veh['destination node']['id']) path_tar2dest['weight'], path_tar2dest['eids'] = nxops.path_info( env.nx, path_tar2dest['nids']) # Combine together path['nids'] = purr.flattenlist( [path_veh2tar['nids'], path_tar2dest['nids']]) path['weight'] = path_veh2tar['weight'] + path_tar2dest['weight'] path['eids'] = purr.flattenlist( [path_veh2tar['eids'], path_tar2dest['eids']]) # Update vehicle tracking data index = int(veh['id'][3:]) env.vehicles[index]['target nid'] = tar['id'] env.vehicles[index]['target eid'] = path['eids'][ path['nids'].index(tar['id'])] env.vehicles[index]['diversion path length'] = path['weight'] # Route the vehicle with traci env.traci.vehicle.setRoute(veh['id'], path['eids']) continue # ~ print('Dijkstra: Calls=%d Time=%.3fs Avg=%.3fs' % (env.fs_dijkstra['calls'],env.fs_dijkstra['time'],env.fs_dijkstra['time']/env.fs_dijkstra['calls'])) return
def add_baseline(traci): # Vehicle ID vid = "veh%d" % (env.veh_id_counter) env.veh_id_counter += 1 # Selected a path. It must be have a conenction between spawn and sink ntrys = 0 shortest_path = { 'weight': None, 'nids': None, 'eids': None } while True: # Pick a random spawn and sink edge spawn_edge = random.choice(env.spawn_edge) sink_edge = random.choice(env.sink_edge) # Determine the shortest path try: shortest_path['nids'] = nx.dijkstra_path(env.nx, spawn_edge['from'], sink_edge['to']) break except nx.NetworkXNoPath: ntrys += 1 print( "%s: Cannont create a path between %s and %s... Trying again (%d)." % (vid, spawn_edge['from'], sink_edge['to'], ntrys)) continue # At this point, it is assumed that the path is connected # Now the weight of the path and the edge eids of the path is determined shortest_path['weight'], shortest_path['eids'] = nxops.path_info( env.nx, shortest_path['nids']) # display the spawn and sink destions spawn_node, sink_node = purr.flattenlist( purr.batchfilterdicts( env.nodes, 'id', [shortest_path['nids'][0], shortest_path['nids'][-1]])) spawn_point = (float(spawn_node['x']), float(spawn_node['y'])) sink_point = (float(sink_node['x']), float(sink_node['y'])) # Find the optimal target point to visit path = nxops.naive_target_selection(env.nx, shortest_path['nids'], env.target_nodes) # Create a route with the path eids rid = "route%d" % (env.route_id_counter) env.route_id_counter += 1 traci.route.add(rid, path['path_eids']) # Add a vehicle traci.vehicle.add(vid, rid) # Determine the edge immediately after the node target_node_index = path['path_nids'].index(path['target_node']['id']) target_eid = path['path_eids'][target_node_index] # Create the vehicle dictionary veh = { "id": vid, "source": spawn_node['id'], "destination": sink_node['id'], "shortest path length": shortest_path['weight'], "diversion path length": path['weight'], "sample time": None, "target nid": path['target_node']['id'], "target eid": target_eid, "path": path } env.vehicles.append(veh) return