@@ -370,8 +370,8 @@ def __init__(s, W, name, start_node, end_node, length, free_flow_speed=20, jam_d
370370 ----------
371371 W : object
372372 The world to which the link belongs.
373- name : str
374- The name of the link.
373+ name : str | None
374+ The name of the link. If None, the name is automatically generated as "{start_node.name}-{end_node.name}".
375375 start_node : str | Node
376376 The name of the start node of the link.
377377 end_node : str | Node
@@ -572,6 +572,8 @@ def __init__(s, W, name, start_node, end_node, length, free_flow_speed=20, jam_d
572572
573573 s .id = len (s .W .LINKS )
574574 s .name = name
575+ if s .name == None :
576+ s .name = s .start_node .name + "-" + s .end_node .name
575577 s .auto_rename = auto_rename
576578 if s .name in s .W .LINKS_NAME_DICT .keys ():
577579 if auto_rename :
@@ -959,10 +961,12 @@ def __init__(s, W, orig, dest, departure_time, name=None, route_pref=None, route
959961 else :
960962 s .route_pref = {l .id :route_pref [l ] for l in route_pref .keys ()}
961963
962- #these links will be always chosen or not chosen when choosing next link at each node
964+ #these links will be always chosen or not chosen when choosing next link at each node. This is not used anymore. keeping for backward compatibility
963965 s .links_prefer = [s .W .get_link (l ) for l in links_prefer ]
964966 s .links_avoid = [s .W .get_link (l ) for l in links_avoid ]
965967
968+ s .specified_route = None
969+
966970 #行き止まりに行ってしまったときにトリップを止める
967971 s .trip_abort = trip_abort
968972 s .flag_trip_aborted = 0
@@ -1135,6 +1139,11 @@ def enforce_route(s, route, set_avoid=False):
11351139 set_avoid : bool
11361140 If True, the vehicle only travel the links in `route` argument. This is very strict. If the route is not consistent (e.g., the route does not completely connect between the origin and the destination), it will raise an exception.
11371141 """
1142+ route = [s .W .get_link (l ) for l in route ]
1143+
1144+ s .specified_route = route
1145+
1146+ #for backward compatibility
11381147 s .links_prefer = [s .W .get_link (l ) for l in route ]
11391148 if set_avoid :
11401149 s .links_avoid = [s .W .get_link (l ) for l in s .W .LINKS if l not in s .links_prefer ]
@@ -1182,29 +1191,42 @@ def route_next_link_choice(s):
11821191 """
11831192 Select a next link from the current link.
11841193 """
1185- if s .dest != s .link .end_node :
1186- outlinks = list (s .link .end_node .outlinks .values ())
1194+ #print("aaa", end="")
1195+ if s .specified_route == None :
1196+ if s .dest != s .link .end_node :
1197+ outlinks = list (s .link .end_node .outlinks .values ())
11871198
1188- if len (outlinks ):
1199+ if len (outlinks ):
11891200
1190- #if links_prefer is given and available at the node, select only from the links in the list. if links_avoid is given, select links not in the list.
1191- if set (outlinks ) & set (s .links_prefer ):
1192- outlinks = sorted (set (outlinks ) & set (s .links_prefer ), key = lambda l :l .name )
1193- if set (outlinks ) & set (s .links_avoid ):
1194- outlinks = sorted (set (outlinks ) - set (s .links_avoid ), key = lambda l :l .name )
1201+ #if links_prefer is given and available at the node, select only from the links in the list. if links_avoid is given, select links not in the list.
1202+ if set (outlinks ) & set (s .links_prefer ):
1203+ outlinks = sorted (set (outlinks ) & set (s .links_prefer ), key = lambda l :l .name )
1204+ if set (outlinks ) & set (s .links_avoid ):
1205+ outlinks = sorted (set (outlinks ) - set (s .links_avoid ), key = lambda l :l .name )
11951206
1196- preference = np .array ([s .route_pref [l .id ] for l in outlinks ], dtype = float )
1197- if s .W .hard_deterministic_mode == False :
1198- if sum (preference ) > 0 :
1199- s .route_next_link = s .W .rng .choice (outlinks , p = preference / sum (preference ))
1207+ preference = np .array ([s .route_pref [l .id ] for l in outlinks ], dtype = float )
1208+ if s .W .hard_deterministic_mode == False :
1209+ if sum (preference ) > 0 :
1210+ s .route_next_link = s .W .rng .choice (outlinks , p = preference / sum (preference ))
1211+ else :
1212+ s .route_next_link = s .W .rng .choice (outlinks )
12001213 else :
1201- s .route_next_link = s .W .rng .choice (outlinks )
1202- else :
1203- s .route_next_link = max (zip (preference , outlinks ), key = lambda x :x [0 ])[1 ]
1214+ s .route_next_link = max (zip (preference , outlinks ), key = lambda x :x [0 ])[1 ]
12041215
1216+ else :
1217+ s .route_next_link = None
1218+ else :
1219+ outlinks = list (s .link .end_node .outlinks .values ())
1220+ if len (outlinks ):
1221+ number_of_traveled_links = len (s .log_t_link )- 1
1222+ if s .specified_route [number_of_traveled_links ] in outlinks :
1223+ s .route_next_link = s .specified_route [number_of_traveled_links ]
1224+ else :
1225+ raise ValueError (f"Vehicle { s .name } : specified route { s .specified_route } is inconsistent at the current link { s .link } . Debug info: { number_of_traveled_links = } , { outlinks = } " )
12051226 else :
12061227 s .route_next_link = None
12071228
1229+
12081230 def add_dest (s , dest , order = - 1 ):
12091231 """
12101232 Add a destination to the vehicle's destination list.
@@ -2700,6 +2722,9 @@ def __iter__(s):
27002722 def __len__ (s ):
27012723 return len (s .links )
27022724
2725+ def __getitem__ (s , index ):
2726+ return s .links [index ]
2727+
27032728 def __eq__ (self , other ):
27042729 """
27052730 Override `==` operator. If the links of two route are the same, then the routes are the same.
0 commit comments