def check_last_rescheduled_step(): # stop in last possible cell, if no way to target for i, agent in enumerate(env.agents): controller = controllers[i] if agent.status not in [RailAgentStatus.ACTIVE, RailAgentStatus.READY_TO_DEPART]: continue if agent_position_duration[i] is None or len(cached_ways[i]) == 0: continue pos = agent_way_position[i] if pos == len(cached_ways[i]): #last vertex in new way is not target - stay here to end of simulation if cached_ways[i][-1].vertex_idx != controller.target_vertex: locker.unlock(new_way[i][-1].vertex_idx, i, (new_way[i][-1].arrival_time, new_way[i][-1].departure_time + 1)) new_duration = (new_way[i][-1].arrival_time, INF_STEP) locker.lock(new_way[i][-1].vertex_idx, i, new_duration ) new_way[i][-1].wait_steps = INF_STEP new_way[i][-1].departure_time = new_duration[1] else: vertex_idx = cached_ways[i][pos].vertex_idx new_duration = (agent_position_duration[i][0], INF_STEP) locker.lock(vertex_idx, i, new_duration) new_way[i].append(AgentWayStep(vertex_idx=vertex_idx, direction=None, arrival_time=new_duration[0], departure_time=new_duration[1], wait_steps=INF_STEP, action=None, prev_way_id=-1))
def rescheduling_main(): # recalculate new duration for each agent on each cell of the cached way position_updated = True full_recalc_needed = False while position_updated: position_updated = False for i in range(len(controllers)): agent = env.agents[i] if (agent_way_position[i] >= len(cached_ways[i])) or agent_done(env, i): continue vertex_idx = cached_ways[i][agent_way_position[i]].vertex_idx duration = agent_position_duration[i] if agent_way_position[i] == len(cached_ways[i])-1: if vertex_idx == controllers[i].target_vertex: # target vertex new_way[i].append(AgentWayStep(vertex_idx=vertex_idx, direction=None, arrival_time=duration[0], departure_time=duration[1], wait_steps = 0, action = None, prev_way_id = -1)) locker.lock(vertex_idx, i, (duration[0], duration[1])) assert len(vertex_agent_order[vertex_idx]) and vertex_agent_order[vertex_idx][0] == i vertex_agent_order[vertex_idx].pop(0) agent_position_duration[i] = None agent_way_position[i] += 1 position_updated = True else: next_vertex_idx = cached_ways[i][agent_way_position[i] + 1].vertex_idx ticks_per_step = int(round(1 / env.agents[i].speed_data['speed'])) # if vertex_agent_order[next_vertex_idx][0] == i and vertex_agent_order[vertex_idx][0] == i: # possible move to next vertex if vertex_agent_order[next_vertex_idx][0] == i: # possible move to next vertex new_duration = (duration[0], max(duration[1], locker.last_time_step(next_vertex_idx, i))) # if agent_way_position[i]==0 and agent.speed_data['position_fraction'] > 0: # if new_duration != duration: # continue duration = new_duration #if not possible to reschedule right, do it with mistakes if locker.is_locked(vertex_idx, i , duration): d0 = duration[0] d1 = duration[1] ind = locker.equal_or_greater_index_end(vertex_idx, duration[0]) if ind>=0 and ind<len(locker.data[vertex_idx]): d0 = max(d0, locker.data[vertex_idx][ind][0][1]+1) ind = locker.equal_or_greater_index(vertex_idx, duration[0]) if ind >= 0 and ind < len(locker.data[vertex_idx]): d1 = min(d1, locker.data[vertex_idx][ind][0][0]) if d1<=d0: d1 = d0+1 print(f"Rescheduling mistake for train {i}. {duration[0]},{duration[1]} -> {d0}, {d1}") duration = (d0, d1) full_recalc_needed = True new_way[i].append(AgentWayStep(vertex_idx=vertex_idx, direction=None, arrival_time=duration[0], departure_time=duration[1], wait_steps=0, action=None, prev_way_id=-1)) locker.lock(vertex_idx, i, (duration[0], duration[1])) assert len(vertex_agent_order[vertex_idx]) and vertex_agent_order[vertex_idx][0] == i vertex_agent_order[vertex_idx].pop(0) # #bad situation... what can we do - the best we can # assert len(vertex_agent_order[vertex_idx]) # index = vertex_agent_order[vertex_idx].index(i) # if index>0: # print("Malfunction swapped order, ignore it for now") # full_recalc_needed = True # vertex_agent_order[vertex_idx].pop(index) position_updated = True agent_way_position[i] += 1 if agent_way_position[i] == len(cached_ways[i]) - 1: # next vertex is target duration = (duration[1], duration[1] + 1) else: duration = (duration[1], duration[1] + ticks_per_step) agent_position_duration[i] = duration return full_recalc_needed
def rescheduling_main(): # recalculate new duration for each agent on each cell of the cached way position_updated = True full_recalc_needed = False blocked_vertexes = set() for i, agent in enumerate(env.agents): if agent.status == RailAgentStatus.ACTIVE: controller = controllers[i] way = controller.get_cached_way() if len(way): # assert len(way) first_vertex = way[-1].vertex_idx if vertex_agent_order[first_vertex][0] != i: print('blocked at start', i, first_vertex) blocked_vertexes.add(first_vertex) # assert vertex_agent_order[first_vertex][0] == i # assert way[0].arrival_time <= step_idx, (way[0].arrival_time, step_idx) while position_updated: position_updated = False for i in range(len(controllers)): agent = env.agents[i] if (agent_way_position[i] >= len( cached_ways[i])) or agent_done(env, i): continue vertex_idx = cached_ways[i][agent_way_position[i]].vertex_idx duration = agent_position_duration[i] if vertex_idx in blocked_vertexes: continue if agent_way_position[i] == len(cached_ways[i]) - 1: if vertex_idx == controllers[ i].target_vertex: # target vertex new_way[i].append( AgentWayStep(vertex_idx=vertex_idx, direction=None, arrival_time=duration[0], departure_time=duration[1], wait_steps=0, action=None, prev_way_id=-1)) locker.lock(vertex_idx, i, (duration[0], duration[1])) # assert len(vertex_agent_order[vertex_idx]) and vertex_agent_order[vertex_idx][0] == i if not (len(vertex_agent_order[vertex_idx]) and vertex_agent_order[vertex_idx][0] == i): blocked_vertexes.add(vertex_idx) continue vertex_agent_order[vertex_idx].pop(0) agent_position_duration[i] = None agent_way_position[i] += 1 position_updated = True else: next_vertex_idx = cached_ways[i][agent_way_position[i] + 1].vertex_idx ticks_per_step = int( round(1 / env.agents[i].speed_data['speed'])) # if vertex_agent_order[next_vertex_idx][0] == i and vertex_agent_order[vertex_idx][0] == i: # possible move to next vertex if vertex_agent_order[next_vertex_idx][ 0] == i and next_vertex_idx not in blocked_vertexes: # possible move to next vertex new_duration = (duration[0], max( duration[1], locker.last_time_step( next_vertex_idx, i))) # if agent_way_position[i]==0 and agent.speed_data['position_fraction'] > 0: # if new_duration != duration: # continue duration = new_duration if not (len(vertex_agent_order[vertex_idx]) and vertex_agent_order[vertex_idx][0] == i): blocked_vertexes.add(vertex_idx) continue new_way[i].append( AgentWayStep(vertex_idx=vertex_idx, direction=None, arrival_time=duration[0], departure_time=duration[1], wait_steps=0, action=None, prev_way_id=-1)) locker.lock(vertex_idx, i, (duration[0], duration[1])) # assert len(vertex_agent_order[vertex_idx]) and vertex_agent_order[vertex_idx][0] == i vertex_agent_order[vertex_idx].pop(0) position_updated = True agent_way_position[i] += 1 if agent_way_position[i] == len( cached_ways[i]) - 1: # next vertex is target duration = (duration[1], duration[1] + 1) else: duration = (duration[1], duration[1] + ticks_per_step) agent_position_duration[i] = duration return full_recalc_needed