diff --git a/aicrowd.json b/aicrowd.json index fae008f5d9dde9ddfa218d3d2ae47573fe80e426..c7c8e156dea73d2a09246fd32a0a379744a42011 100644 --- a/aicrowd.json +++ b/aicrowd.json @@ -3,6 +3,6 @@ "grader_id": "aicrowd_flatland_challenge_2019", "authors": ["mugurelionut"], "description": "Flatland Challenge Agent - various techniques.", - "debug" : true + "debug" : false } diff --git a/r2sol-old.cc b/r2sol-old.cc deleted file mode 100644 index 20f210bdd70ac9a58926b6b22ed6ef3cee13afbe..0000000000000000000000000000000000000000 --- a/r2sol-old.cc +++ /dev/null @@ -1,2381 +0,0 @@ -#include "r2sol.h" -#undef NDEBUG -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <algorithm> -#include <memory> -#include <mutex> -#include <thread> - -#include <algorithm> -#include <vector> - -using namespace std; - -#define DEBUG_LEVEL 0//2 - -#define DBG(debug_level, ...) \ - { \ - if (debug_level <= DEBUG_LEVEL) { \ - fprintf(stderr, __VA_ARGS__); \ - fflush(stderr); \ - } \ - } - -#define HMAX 151 -#define NMAX 201 -#define MAXNODES 3000 -#define TMAX 2567 -#define MAX_NUM_THREADS 1//4 -#define MAX_CTURNS 5 -#define INF 1000000000 -#define ZERO 0.000001 -#define ONE 0.999999 -#define USE_SPACING_TO_AVOID_DEADLOCKS 1 -#define USE_STRICT_SPACING_TO_AVOID_DEADLOCKS 0 -#define MIN_TINIT_FOR_SAVE_DATA_FOR_REPLAY 1000000 - -class Xor128 { - public: - void reset(unsigned int seed) { - xx = seed; - yy = 362436069; - zz = 521288629; - uu = 786232308; - } - - inline unsigned int rand() { - unsigned int t = (xx ^ (xx << 11)); - xx = yy; - yy = zz; - zz = uu; - return (uu = (uu ^ (uu >> 19)) ^ (t ^ (t >> 8))); - } - - private: - unsigned int xx, yy, zz, uu; -}; - -double GetTime() { - return 1.0 * clock() / CLOCKS_PER_SEC; -} - -const int DROW[4] = {-1, 0, +1, 0}; -const int DCOL[4] = {0, +1, 0, -1}; - -namespace SOLVE { - -FILE* fin; -char fname[128]; -int H, W, T, TEST, N, TINIT; -double TSTART; - -struct Node { - int row, col; -} node[MAXNODES]; - -int cell_to_node[HMAX][HMAX], nnodes; -int next[MAXNODES][4][4]; -int revnext[MAXNODES][4][4]; - -int target_node_agents[MAXNODES][NMAX], num_target_node_agents[MAXNODES]; - -void ReadTransitionsMap() { - int has_transition_map; - fscanf(fin, "%d", &has_transition_map); - if (!has_transition_map) return; - fscanf(fin, "%d %d", &H, &W); - DBG(2, "[ReadTransitionsMap] has_transition_map=%d H=%d W=%d\n", has_transition_map, H, W); - assert(1 <= H && H < HMAX && 1 <= W && W < HMAX); - for (int i = 0; i < H; ++i) { - for (int j = 0; j < W; ++j) { - cell_to_node[i][j] = -2; - } - } - nnodes = 0; - T = TMAX - 7; - //T = 8 * (H + W + 20); - int row, col, o1, o2, num_transitions = 0; - while (fscanf(fin, "%d %d %d %d", &row, &col, &o1, &o2) == 4) { - if (row < 0 || col < 0 || o1 < 0 || o2 < 0) break; - DBG(4, "row=%d/%d col=%d/%d o1=%d o2=%d nnodes=%d\n", row, H, col, W, o1, o2, nnodes); - assert(0 <= row && row < H); - assert(0 <= col && col < W); - assert(0 <= o1 && o1 < 4); - assert(0 <= o2 && o2 < 4); - if (cell_to_node[row][col] < 0) { - assert(nnodes < MAXNODES); - auto& new_node = node[nnodes]; - new_node.row = row; - new_node.col = col; - auto& next_nnodes = next[nnodes]; - auto& revnext_nnodes = revnext[nnodes]; - for (int tmpo1 = 0; tmpo1 <= 3; ++tmpo1) { - auto& next_nnodes_tmpo1 = next_nnodes[tmpo1]; - auto& revnext_nnodes_tmpo1 = revnext_nnodes[tmpo1]; - for (int tmpo2 = 0; tmpo2 <= 3; ++tmpo2) { - next_nnodes_tmpo1[tmpo2] = revnext_nnodes_tmpo1[tmpo2] = -1; - } - } - num_target_node_agents[nnodes] = 0; - cell_to_node[row][col] = nnodes++; - } - const auto& v1 = cell_to_node[row][col]; - const int rnext = row + DROW[o2], cnext = col + DCOL[o2]; - assert(0 <= rnext && rnext < H); - assert(0 <= cnext && cnext < W); - if (cell_to_node[rnext][cnext] < 0) { - assert(nnodes < MAXNODES); - auto& new_node = node[nnodes]; - new_node.row = rnext; - new_node.col = cnext; - auto& next_nnodes = next[nnodes]; - auto& revnext_nnodes = revnext[nnodes]; - for (int tmpo1 = 0; tmpo1 <= 3; ++tmpo1) { - auto& next_nnodes_tmpo1 = next_nnodes[tmpo1]; - auto& revnext_nnodes_tmpo1 = revnext_nnodes[tmpo1]; - for (int tmpo2 = 0; tmpo2 <= 3; ++tmpo2) { - next_nnodes_tmpo1[tmpo2] = revnext_nnodes_tmpo1[tmpo2] = -1; - } - } - num_target_node_agents[nnodes] = 0; - cell_to_node[rnext][cnext] = nnodes++; - } - const auto& v2 = cell_to_node[rnext][cnext]; - next[v1][o1][o2] = v2; - revnext[v2][o2][o1] = v1; - ++num_transitions; - } - DBG(0, "[ReadTransitionsMap] num_transitions=%d nnodes=%d/%d\n", num_transitions, nnodes, H * W); -} - -enum HowIGotHere { - INVALID = -1, - OUTSIDE_SRC = 0, - ENTERED_SRC = 1, - STARTED_MOVING = 2, - CONTINUED_MOVING = 3, - WAITED = 4, - MALFUNCTIONED = 5, -}; - -enum RailAgentStatus { - READY_TO_DEPART = 0, - ACTIVE = 1, - DONE = 2, - DONE_REMOVED = 3, -}; - -enum RailEnvActions { - DO_NOTHING = 0, - MOVE_LEFT = 1, - MOVE_FORWARD = 2, - MOVE_RIGHT = 3, - STOP_MOVING = 4, -}; - -struct PathElem { - int node, o, moving_to_node, moving_to_o, num_partial_turns; - HowIGotHere how_i_got_here; - - void PrintDebug(int t = -1) { - DBG(0, "t=%d poz=(%d %d) moving_to=(%d %d) npturns=%d how=%d\n", t, node, o, moving_to_node, moving_to_o, num_partial_turns, how_i_got_here); - } -}; - -struct Path { - struct PathElem p[TMAX]; - int tmax; -}; - -void CopyPath(const Path& src, Path* dst) { - dst->tmax = src.tmax; - if (src.tmax >= TINIT) memcpy(&dst->p[TINIT], &src.p[TINIT], (src.tmax - TINIT + 1) * sizeof(PathElem)); -} - -struct Agent { - int aid, poz_row, poz_col, poz_o, poz_node, target_row, target_col, target_node, malfunc, nr_malfunc, cturns; - double speed, poz_frac; - int inside_poz, fresh_malfunc, moving_to_node, moving_to_o; - RailAgentStatus status; -} agent[NMAX], tmp_agent; - -int cturns_agents[MAX_CTURNS][NMAX], num_cturns_agents[MAX_CTURNS]; - -int MAX_DONE_AGENTS; -double MIN_COST; -struct Path path[NMAX], ipath[NMAX]; - -int checkpoints[NMAX][TMAX], checkpoints_o[NMAX][TMAX], checkpoints_t[NMAX][TMAX], checkpoints_cnt[NMAX][TMAX], num_checkpoints[NMAX], tcheckpoints[NMAX][TMAX], next_checkpoint[NMAX]; - -vector<pair<int, int>> ipath_visiting_order[MAXNODES]; - -void RepopulateVisitingOrders() { - for (int node = 0; node < nnodes; ++node) ipath_visiting_order[node].clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_t_aid = checkpoints_t[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - for (int idx = next_checkpoint[aid]; idx < num_checkpoints_aid; ++idx) - ipath_visiting_order[checkpoints_aid[idx]].push_back({checkpoints_t_aid[idx], aid}); - } - for (int node = 0; node < nnodes; ++node) { - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - sort(ipath_visiting_order_node.begin(), ipath_visiting_order_node.end()); - } -} - -int covered_by[MAX_NUM_THREADS][TMAX][MAXNODES], is_covered[MAX_NUM_THREADS][TMAX][MAXNODES], is_covered_idx[MAX_NUM_THREADS], can_reach_idx[MAX_NUM_THREADS], can_reach[MAX_NUM_THREADS][TMAX][MAXNODES][4], can_reach_with_t1[MAX_NUM_THREADS][TMAX][MAXNODES][4]; -int tmax_at_poz_node[MAX_NUM_THREADS][NMAX]; - -void CheckAgent(int aid) { - auto& agent_aid = agent[aid]; - const auto& path = ipath[aid]; - if (path.tmax < TINIT) { - assert(agent_aid.status == DONE_REMOVED); - return; - } - - const auto& path_elem = path.p[TINIT]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) { - assert(!agent_aid.inside_poz); - assert(agent_aid.status == READY_TO_DEPART); - return; - } - - if (agent_aid.inside_poz) { - auto& next_checkpoint_aid = next_checkpoint[aid]; - assert(next_checkpoint_aid < num_checkpoints[aid]); - if (checkpoints[aid][next_checkpoint_aid] == agent_aid.poz_node) { - assert(checkpoints_o[aid][next_checkpoint_aid] == agent_aid.poz_o); - ++next_checkpoint_aid; - } - } - - const auto& is_covered_idx_0 = is_covered_idx[0]; - auto& is_covered_0 = is_covered[0]; - - if (agent_aid.fresh_malfunc) { - if (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING) { - assert(0 <= agent_aid.moving_to_node && agent_aid.moving_to_node < nnodes); - assert(0 <= agent_aid.moving_to_o && agent_aid.moving_to_o < nnodes); - if (path_elem.num_partial_turns >= 1) { - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - (path_elem.num_partial_turns - 1) * agent_aid.speed) < ZERO); - } else { - assert(next[agent_aid.poz_node][agent_aid.poz_o][path_elem.o] == path_elem.node); - assert(agent_aid.poz_frac >= (agent_aid.cturns - 1) * agent_aid.speed - ZERO); - } - } else { - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - path_elem.num_partial_turns * agent_aid.speed) < ZERO); - } - } else if (is_covered_0[TINIT][path_elem.node] == is_covered_idx_0) { - assert((path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING || path_elem.how_i_got_here == ENTERED_SRC) && path_elem.num_partial_turns == 0); - if (path_elem.how_i_got_here == ENTERED_SRC) assert(!agent_aid.inside_poz); - else { - assert(agent_aid.inside_poz); - assert(agent_aid.poz_frac >= ONE); - assert(agent_aid.moving_to_node == path_elem.node); - assert(agent_aid.moving_to_o == path_elem.o); - } - } else if (path.tmax == TINIT) { - assert(!agent_aid.inside_poz); - assert(agent_aid.status == DONE_REMOVED); - assert(agent_aid.moving_to_node == path_elem.node); - agent_aid.moving_to_node = agent_aid.moving_to_o = -1; - } else { - assert(agent_aid.inside_poz); - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - path_elem.num_partial_turns * agent_aid.speed) < ZERO); - if (0 <= agent_aid.moving_to_node && agent_aid.moving_to_node < nnodes && path_elem.num_partial_turns == 0 && - (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) { - assert(agent_aid.moving_to_node == path_elem.node); - assert(agent_aid.moving_to_o == path_elem.o); - agent_aid.moving_to_node = agent_aid.moving_to_o = -1; - } - if (path_elem.num_partial_turns == 0 && (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) - assert(agent_aid.moving_to_node < 0); - } - - if (agent_aid.inside_poz) is_covered_0[TINIT][agent_aid.poz_node] = is_covered_idx_0; -} - -bool reschedule; -int num_done_agents, num_planned, num_reschedules, num_adjust_ipaths; -int num_adjust_ipaths_without_full_plan_regeneration; - -int important_row[2 * NMAX], important_col[2 * NMAX]; -char visited[2 * NMAX]; - -void DFSMarkCities(int aid) { - visited[aid] = 1; - static const int kMaxDiff = 2; - for (int aid2 = 0; aid2 < 2 * N; ++aid2) { - if (visited[aid2]) continue; - if (abs(important_row[aid] - important_row[aid2]) <= kMaxDiff && abs(important_col[aid] - important_col[aid2]) <= kMaxDiff) - DFSMarkCities(aid2); - } -} - -void EstimateT() { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - important_row[2 * aid] = agent_aid.poz_row; - important_col[2 * aid] = agent_aid.poz_col; - important_row[2 * aid + 1] = agent_aid.target_row; - important_col[2 * aid + 1] = agent_aid.target_col; - visited[2 * aid] = visited[2 * aid + 1] = 0; - } - int num_cities = 0; - for (int aid = 0; aid < 2 * N; ++aid) { - if (visited[aid]) continue; - DFSMarkCities(aid); - ++num_cities; - } - if (1.0 * N / num_cities < 20.0 - 1e-6) - TEST = (int)(8.0 * (H + W + 1.0 * N / num_cities)); - else - TEST = 8 * (H + W + 20); - DBG(0, "(estimated) num_cities=%d TEST=%d\n", num_cities, TEST); -} - -void ReadAgentsData(bool replay_mode = false) { - fscanf(fin, "%d %d", &N, &TINIT); - DBG(2, "[ReadAgentsData] N=%d TINIT=%d/%d\n", N, TINIT, T); - assert(1 <= N && N < NMAX); - if (replay_mode) { - fscanf(fin, "%d %d %d", &num_reschedules, &num_planned, &num_adjust_ipaths_without_full_plan_regeneration); - reschedule = TINIT == 0; - } else if (TINIT == 0) { - reschedule = true; - num_reschedules = 0; - num_adjust_ipaths = 0; - num_adjust_ipaths_without_full_plan_regeneration = 0; - num_planned = N; - } else reschedule = false; - if (num_planned == 0) return; - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) num_cturns_agents[cturns] = 0; - num_done_agents = 0; - num_planned = TINIT == 0 ? N : 0; - ++is_covered_idx[0]; - for (int aid = 0; aid < N; ++aid) { - int has_path_data = 0, has_moving_to_data = 0, status = -1; - fscanf(fin, "%d %d %d %d %d %d %lf %lf %d %d %d %d %d %d", &tmp_agent.aid, &tmp_agent.poz_row, &tmp_agent.poz_col, &tmp_agent.poz_o, &tmp_agent.target_row, &tmp_agent.target_col, &tmp_agent.speed, &tmp_agent.poz_frac, &tmp_agent.malfunc, &tmp_agent.nr_malfunc, &status, &tmp_agent.fresh_malfunc, &has_moving_to_data, &has_path_data); - assert(aid == tmp_agent.aid); - assert(status == READY_TO_DEPART || status == ACTIVE || status == DONE || status == DONE_REMOVED); - tmp_agent.status = (RailAgentStatus) status; - tmp_agent.poz_node = cell_to_node[tmp_agent.poz_row][tmp_agent.poz_col]; - tmp_agent.target_node = cell_to_node[tmp_agent.target_row][tmp_agent.target_col]; - tmp_agent.cturns = 0; - while (tmp_agent.cturns * tmp_agent.speed < ONE) ++tmp_agent.cturns; - tmp_agent.inside_poz = tmp_agent.status != READY_TO_DEPART && tmp_agent.status != DONE_REMOVED; - - auto& agent_aid = agent[aid]; - if (has_moving_to_data) { - int row, col; - fscanf(fin, "%d %d %d", &row, &col, &tmp_agent.moving_to_o); - if (row < 0 && col < 0) { - tmp_agent.moving_to_node = -1; - assert(tmp_agent.moving_to_o < 0); - } else { - tmp_agent.moving_to_node = cell_to_node[row][col]; - assert(0 <= tmp_agent.moving_to_node && tmp_agent.moving_to_node < nnodes); - assert(0 <= tmp_agent.moving_to_o && tmp_agent.moving_to_o <= 3); - } - } else if (TINIT == 0) tmp_agent.moving_to_node = tmp_agent.moving_to_o = -1; - else { - tmp_agent.moving_to_node = agent_aid.moving_to_node; - tmp_agent.moving_to_o = agent_aid.moving_to_o; - } - - if (TINIT >= 1) { - if (!replay_mode) tmp_agent.fresh_malfunc |= (tmp_agent.nr_malfunc > agent_aid.nr_malfunc); - reschedule |= tmp_agent.fresh_malfunc; - if (tmp_agent.status == DONE_REMOVED) ++num_done_agents; - } - memcpy(&agent_aid, &tmp_agent, sizeof(Agent)); - - if (replay_mode || TINIT == 0) target_node_agents[agent_aid.target_node][num_target_node_agents[agent_aid.target_node]++] = aid; - - auto& ipath_aid = ipath[aid]; - if (has_path_data) { - fscanf(fin, "%d", &ipath_aid.tmax); - for (int t = TINIT; t <= ipath_aid.tmax; ++t) { - auto& new_path_elem = ipath_aid.p[t]; - int poz_row, poz_col, moving_to_row, moving_to_col, how_i_got_here = -1; - fscanf(fin, "%d %d %d %d %d %d %d %d", &poz_row, &poz_col, &new_path_elem.o, &moving_to_row, &moving_to_col, &new_path_elem.moving_to_o, &new_path_elem.num_partial_turns, &how_i_got_here); - assert(0 <= poz_row && poz_row < H && 0 <= poz_col && poz_col < W); - new_path_elem.node = cell_to_node[poz_row][poz_col]; - assert(0 <= new_path_elem.node && new_path_elem.node < nnodes); - if (moving_to_row >= 0 && moving_to_col >= 0) - new_path_elem.moving_to_node = cell_to_node[moving_to_row][moving_to_col]; - else new_path_elem.moving_to_node = -1; - assert(how_i_got_here == OUTSIDE_SRC || how_i_got_here == ENTERED_SRC || how_i_got_here == STARTED_MOVING || how_i_got_here == CONTINUED_MOVING || how_i_got_here == WAITED || how_i_got_here == MALFUNCTIONED); - new_path_elem.how_i_got_here = (HowIGotHere) how_i_got_here; - } - auto& num_checkpoints_aid = num_checkpoints[aid]; - fscanf(fin, "%d", &num_checkpoints_aid); - ++num_checkpoints_aid; - auto& checkpoints_aid = checkpoints[aid]; - auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_t_aid = checkpoints_t[aid]; - next_checkpoint[aid] = 1; - for (int cid = 1; cid < num_checkpoints_aid; ++cid) { - int row, col; - fscanf(fin, "%d %d %d %d", &row, &col, &checkpoints_o_aid[cid], &checkpoints_t_aid[cid]); - checkpoints_aid[cid] = cell_to_node[row][col]; - assert(0 <= checkpoints_aid[cid] && checkpoints_aid[cid] < nnodes); - } - if (agent_aid.inside_poz) { - checkpoints_aid[0] = agent_aid.poz_node; - checkpoints_o_aid[0] = agent_aid.poz_o; - } else { - checkpoints_aid[0] = checkpoints_o_aid[0] = -1; - } - checkpoints_t_aid[0] = TINIT; - } else if (TINIT == 0) { - // Initialize the path with fully waiting outside. - ipath_aid.tmax = T; - for (int t = 0; t <= T; ++t) { - auto& new_path_elem = ipath_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - num_checkpoints[aid] = next_checkpoint[aid] = 1; - checkpoints[aid][0] = checkpoints_o[aid][0] = -1; - } - - if (ipath_aid.tmax >= TINIT && ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node && agent_aid.status != DONE_REMOVED) - ++num_planned; - - DBG(2, "\nTINIT=%d aid=%d: poz=(%d %d %d):%d inside_poz=%d target=(%d %d):%d moving_to_node=%d:(%d %d) moving_to_o=%d cturns=%d speed=%.6lf poz_frac=%.6lf malf=%d nr_malf=%d status=%d fresh_malf=%d\n", TINIT, agent_aid.aid, agent_aid.poz_row, agent_aid.poz_col, agent_aid.poz_o, agent_aid.poz_node, agent_aid.inside_poz, agent_aid.target_row, agent_aid.target_col, agent_aid.target_node, agent_aid.moving_to_node, node[agent_aid.moving_to_node].row, node[agent_aid.moving_to_node].col, agent_aid.moving_to_o, agent_aid.cturns, agent_aid.speed, agent_aid.poz_frac, agent_aid.malfunc, agent_aid.nr_malfunc, agent_aid.status, agent_aid.fresh_malfunc); - - assert(0 <= agent_aid.poz_row && agent_aid.poz_row < H); - assert(0 <= agent_aid.poz_col && agent_aid.poz_col < W); - assert(0 <= agent_aid.poz_node && agent_aid.poz_node < nnodes); - assert(0 <= agent_aid.poz_o && agent_aid.poz_o <= 3); - assert(0 <= agent_aid.target_row && agent_aid.target_row < H); - assert(0 <= agent_aid.target_col && agent_aid.target_col < W); - assert(0 <= agent_aid.target_node && agent_aid.target_node < nnodes); - assert(agent_aid.cturns < MAX_CTURNS); - cturns_agents[agent_aid.cturns][num_cturns_agents[agent_aid.cturns]++] = aid; - - if (TINIT >= 1) { - CheckAgent(aid); - DBG(2, " still moving_to_node=%d:(%d %d) moving_to_o=%d\n", agent_aid.moving_to_node, node[agent_aid.moving_to_node].row, node[agent_aid.moving_to_node].col, agent_aid.moving_to_o); - } - } - - if (TINIT == 0 || replay_mode) { - if (TINIT == 0) EstimateT(); - else fscanf(fin, "%d", &T); - } - - //exit(1); -} - -struct ShortestPathQueueElement { - int node, o; -} qshpath[MAXNODES * 4]; - -int dmin[NMAX][MAXNODES][4], prev_node[NMAX][MAXNODES][4], prev_o[NMAX][MAXNODES][4]; - -void ComputeShortestPaths(int aid) { - auto& dmin_aid = dmin[aid]; - auto& prev_node_aid = prev_node[aid]; - auto& prev_o_aid = prev_o[aid]; - for (int node = 0; node < nnodes; ++node) { - auto& dmin_aid_node = dmin_aid[node]; - for (int o = 0; o <= 3; ++o) dmin_aid_node[o] = INF; - } - int qli = 0, qls = -1; - const auto& agent_aid = agent[aid]; - for (int o = 0; o <= 3; ++o) { - auto& new_queue_elem = qshpath[++qls]; - new_queue_elem.node = agent_aid.target_node; - new_queue_elem.o = o; - dmin_aid[agent_aid.target_node][o] = 0; - } - while (qli <= qls) { - const auto& qelem = qshpath[qli++]; - const auto& node1 = qelem.node; - const auto& o1 = qelem.o; - const int dnew = dmin_aid[node1][o1] + agent_aid.cturns; - const auto& revnext_node1_o1 = revnext[node1][o1]; - for (int o2 = 0; o2 <= 3; ++o2) { - const auto& node2 = revnext_node1_o1[o2]; - if (node2 < 0) continue; - if (dnew < dmin_aid[node2][o2]) { - dmin_aid[node2][o2] = dnew; - auto& new_queue_elem = qshpath[++qls]; - new_queue_elem.node = node2; - new_queue_elem.o = o2; - prev_node_aid[node2][o2] = node1; - prev_o_aid[node2][o2] = o1; - } - } - } -} - -void ComputeShortestPaths() { - for (int aid = 0; aid < N; ++aid) ComputeShortestPaths(aid); -} - -Xor128 xor128[MAX_NUM_THREADS]; -int perm[MAX_NUM_THREADS][NMAX]; -char pused[MAX_NUM_THREADS][NMAX]; - -struct HeapElement { - int t, node, t1, est_tmin; - char o; - - bool IsSmaller(const HeapElement& other) const { - return est_tmin < other.est_tmin || (est_tmin == other.est_tmin && t1 > other.t1); - } -} heap[MAX_NUM_THREADS][TMAX * MAXNODES * 4]; - -int heap_size[MAX_NUM_THREADS]; - -inline void Swap(HeapElement h[], int poza, int pozb) { - auto& a = h[poza]; - auto& b = h[pozb]; - const HeapElement tmp = a; - a = b; - b = tmp; -} - -inline void PushUp(HeapElement h[], int poz) { - while (poz > 1) { - const int parent = poz >> 1; - auto& h_poz = h[poz]; - auto& h_parent = h[parent]; - if (h_poz.IsSmaller(h_parent)) { - Swap(h, poz, parent); - poz = parent; - } else - break; - } -} - -inline void PushDown(HeapElement h[], int& hsize, int poz) { - while (1) { - const int lchild = poz << 1; - if (lchild > hsize) break; - auto& h_lchild = h[lchild]; - auto& h_poz = h[poz]; - const int rchild = lchild + 1; - if (rchild <= hsize) { - auto& h_rchild = h[rchild]; - if (h_lchild.IsSmaller(h_rchild)) { - if (h_lchild.IsSmaller(h_poz)) { - Swap(h, lchild, poz); - poz = lchild; - } else - break; - } else { - if (h_rchild.IsSmaller(h_poz)) { - Swap(h, rchild, poz); - poz = rchild; - } else - break; - } - } else { - if (h_lchild.IsSmaller(h_poz)) { - Swap(h, lchild, poz); - poz = lchild; - } else - break; - } - } -} - -inline void InsertIntoHeap(HeapElement h[], int& hsize, int t, int node, int o, int t1, int est_tmin) { - auto& new_element = h[++hsize]; - new_element.t = t; - new_element.node = node; - new_element.o = o; - new_element.t1 = t1; - new_element.est_tmin = est_tmin; - PushUp(h, hsize); -} - -inline void ExtractMinFromHeap(HeapElement h[], int& hsize, int& t, int& node, int& o, int& t1) { - assert(hsize >= 1); - auto& min_element = h[1]; - t = min_element.t; - node = min_element.node; - o = min_element.o; - t1 = min_element.t1; - min_element = h[--hsize]; - if (hsize >= 1) PushDown(h, hsize, 1); -} - -struct Path tmp_path[MAX_NUM_THREADS][NMAX], tmp_path2[MAX_NUM_THREADS][NMAX]; -mutex m; - -struct PrevState { - int node, t; - char o; - HowIGotHere type; -} prev[MAX_NUM_THREADS][TMAX][MAXNODES][4]; - - -void CopyTmpPathToPath(int tid) { - // The mutex must be held before calling this function. - const auto& tmp_path_tid = tmp_path[tid]; - for (int aid = 0; aid < N; ++aid) { - auto& path_aid = path[aid]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) { - path_aid.tmax = -1; - continue; - } - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CopyPath(tmp_path_tid_aid, &path_aid); - } -} - -void RecomputeCheckpoints() { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - auto& num_checkpoints_aid = num_checkpoints[aid]; - - if (agent_aid.status == DONE_REMOVED) { - num_checkpoints_aid = next_checkpoint[aid] = 0; - continue; - } - - const auto& ipath_aid = ipath[aid]; - assert(ipath_aid.tmax > TINIT); - if (ipath_aid.p[ipath_aid.tmax].node != agent_aid.target_node) { - // This path hasn't been updated. We should keep the previously computed checkpoints. - continue; - } - - num_checkpoints_aid = next_checkpoint[aid] = 1; - - auto& checkpoints_aid = checkpoints[aid]; - auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_t_aid = checkpoints_t[aid]; - - if (agent_aid.inside_poz) { - checkpoints_aid[0] = agent_aid.poz_node; - checkpoints_o_aid[0] = agent_aid.poz_o; - } else { - checkpoints_aid[0] = checkpoints_o_aid[0] = -1; - } - - for (int t = TINIT + 1; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - if (path_elem.how_i_got_here == ENTERED_SRC || path_elem.node != checkpoints_aid[num_checkpoints_aid - 1]) { - checkpoints_aid[num_checkpoints_aid] = path_elem.node; - checkpoints_o_aid[num_checkpoints_aid] = path_elem.o; - checkpoints_t_aid[num_checkpoints_aid] = t; - ++num_checkpoints_aid; - } - } - } -} - -bool CanEnterCell(int aid, int t, int from, int to, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - assert(t > TINIT); - assert(0 <= to && to < nnodes); - const auto& agent_aid = agent[aid]; - const auto& is_covered1 = is_covered[t][to]; - const auto& is_covered2 = is_covered[t - 1][to]; - const auto& aid1 = covered_by[t][to]; - const auto& aid2 = covered_by[t - 1][to]; - - if (agent_aid.target_node == to) { - if (is_covered1 == is_covered_idx && aid1 < aid) return false; - if (is_covered2 == is_covered_idx && aid2 > aid) return false; - //if (USE_SPACING_TO_AVOID_DEADLOCKS && is_covered1 == is_covered_idx && (agent_aid.cturns >= 2 || agent[aid2].cturns >= 2)) return false; - } else { - if (is_covered1 == is_covered_idx) return false; - if (is_covered2 == is_covered_idx && aid2 > aid) return false; - if (from >= 0) { - const auto& is_covered3 = is_covered[t][from]; - const auto& aid3 = covered_by[t][from]; - if (is_covered2 == is_covered_idx && is_covered3 == is_covered_idx && aid2 == aid3) return false; - if (is_covered3 == is_covered_idx && aid3 < aid) return false; - } - if (t + 1 < T) { - const auto& is_covered4 = is_covered[t + 1][to]; - const auto& aid4 = covered_by[t + 1][to]; - if (is_covered4 == is_covered_idx && aid4 < aid) return false; - } - const auto& target_node_agents_to = target_node_agents[to]; - const auto& num_target_node_agents_to = num_target_node_agents[to]; - for (int idx = num_target_node_agents_to - 1; idx >= 0; --idx) { - const auto& aid5 = target_node_agents_to[idx]; - const auto& agent_aid5 = agent[aid5]; - if (agent_aid5.status == DONE_REMOVED) continue; - const auto& tmp_path_aid5 = tmp_path[aid5]; - assert(tmp_path_aid5.tmax > TINIT); - if (aid5 > aid && tmp_path_aid5.tmax == t && tmp_path_aid5.p[t].node == to) return false; - //if (USE_SPACING_TO_AVOID_DEADLOCKS && tmp_path_aid5.tmax == t && tmp_path_aid5.p[t].node == to && (agent_aid.cturns >= 2 || agent_aid5.cturns >= 2)) return false; - if (aid5 < aid && tmp_path_aid5.tmax == t + 1 && tmp_path_aid5.p[t + 1].node == to) return false; - } - } - - return true; -} - -inline bool IsFreeTimeWindow(int aid, int t1, int t2, int node, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - for (int t = t1; t <= t2; ++t) if (!CanEnterCell(aid, t, node, node, covered_by, is_covered, is_covered_idx, tmp_path)) return false; - return true; -} - -int tend_ongoing_move[NMAX]; - -bool OverlapsOngoingMove(int t1, int t2, int node, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[], int tmax_at_poz_node[]) { - if (!USE_SPACING_TO_AVOID_DEADLOCKS) return false; - - if (t1 < tend_ongoing_move[node]) return true; - //if (t2 <= tend_ongoing_move[node]) return true; - - const int min_tstart = t2;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? t2 : t1; - //const int min_tstart = t1;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? t2 : t1; - - const int aid_t1 = is_covered[t1][node] == is_covered_idx ? covered_by[t1][node] : -1; - - for (int tend = t2 + 1; tend <= t2 + 3 && tend <= T; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid = covered_by[tend][node]; - const auto& agent_aid = agent[aid]; - if (tend - agent_aid.cturns < min_tstart && (aid != aid_t1 || is_covered[tend - 1][node] != is_covered_idx)) return true; - } - } - - if (USE_STRICT_SPACING_TO_AVOID_DEADLOCKS) { - for (int tend = t1 + 1; tend <= t2; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid_tend = covered_by[tend][node]; - if (aid_tend != aid_t1 || is_covered[tend - 1][node] != is_covered_idx) return true; - } - } - } - - /*for (int tend = t2 + 1; tend <= t2 + 3 && tend <= T; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid = covered_by[tend][node]; - const auto& agent_aid = agent[aid]; - if (tend - agent_aid.cturns < t2) return true; - } - } - for (int tend = t1 + 1; tend <= t2; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid_tend = covered_by[tend][node]; - const auto& curr_node_aid_tend = agent[aid_tend].poz_node; - if (curr_node_aid_tend != node || tmax_at_poz_node[aid_tend] < tend) return true; - } - }*/ - - - /*const auto& target_node_agents_node = target_node_agents[node]; - const auto& num_target_node_agents_node = num_target_node_agents[node]; - for (int idx = num_target_node_agents_node - 1; idx >= 0; --idx) { - const auto& aid5 = target_node_agents_node[idx]; - const auto& agent_aid5 = agent[aid5]; - if (agent_aid5.status == DONE_REMOVED) continue; - const auto& tmp_path_aid5 = tmp_path[aid5]; - assert(tmp_path_aid5.tmax > TINIT); - if (tmp_path_aid5.p[tmp_path_aid5.tmax].node == agent_aid5.target_node && t1 < tmp_path_aid5.tmax && tmp_path_aid5.tmax <= t2) { - return true; - } - }*/ - - return false; -} - -bool FindBestPath(int aid, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, int can_reach[][MAXNODES][4], int& can_reach_idx, int can_reach_with_t1[][MAXNODES][4], HeapElement h[], int& hsize, PrevState prev[][MAXNODES][4], Path tmp_path[], Path* tmp_path2, int tmax_at_poz_node[]) { - const auto& agent_aid = agent[aid]; - auto& tmp_path_aid = tmp_path[aid]; - - hsize = 0; - - ++can_reach_idx; - const auto& target_node = agent_aid.target_node; - const auto& cturns = agent_aid.cturns; - const auto& dmin_aid = dmin[aid]; - - int t1 = TINIT, t2 = TINIT, rnode = -1, ro = -1; - - if (!agent_aid.inside_poz) { - rnode = agent_aid.poz_node; - ro = agent_aid.poz_o; - t1 = TINIT + max(agent_aid.malfunc - 1, 0); - for (int tstart = t1; tstart < T; ++tstart) { - if (!CanEnterCell(aid, tstart + 1, -1, rnode, covered_by, is_covered, is_covered_idx, tmp_path)) continue; - int t2 = tstart + 1; - const int est_tmin = t2 + dmin_aid[rnode][ro]; - if (est_tmin > T) break; - can_reach[t2][rnode][ro] = can_reach_idx; - can_reach_with_t1[t2][rnode][ro] = tstart + 1; - auto& new_prev = prev[t2][rnode][ro]; - new_prev.t = new_prev.node = new_prev.o = -1; - InsertIntoHeap(h, hsize, t2, rnode, ro, tstart + 1, est_tmin); - } - } else { - t1 = TINIT; - rnode = agent_aid.poz_node; - ro = agent_aid.poz_o; - int moving_to_node = agent_aid.moving_to_node, moving_to_o = agent_aid.moving_to_o; - while (t1 + 1 <= tmp_path_aid.tmax && tmp_path_aid.p[t1 + 1].how_i_got_here == MALFUNCTIONED) { - ++t1; - if (!CanEnterCell(aid, t1, rnode, rnode, covered_by, is_covered, is_covered_idx, tmp_path)) return false; - } - if (t1 >= T) return false; - if (t1 != TINIT + agent_aid.malfunc) { - DBG(0, "!!! [FindBestPath] aid=%d TINIT=%d malfunc=%d t1=%d/%d/%d\n", aid, TINIT, agent_aid.malfunc, t1, TINIT + agent_aid.malfunc, T); - exit(1); - } - memcpy(&tmp_path2->p[TINIT], &tmp_path_aid.p[TINIT], (t1 - TINIT + 1) * sizeof(PathElem)); - t2 = t1; - if (moving_to_node >= 0) { - bool finished_moving = false; - while (t2 < T && rnode == agent_aid.poz_node) { - const auto& prev_path_elem = tmp_path2->p[t2]; - auto& next_path_elem = tmp_path2->p[t2 + 1]; - if (prev_path_elem.num_partial_turns + 1 < agent_aid.cturns || !CanEnterCell(aid, t2 + 1, rnode, moving_to_node, covered_by, is_covered, is_covered_idx, tmp_path)) { - memcpy(&next_path_elem, &prev_path_elem, sizeof(PathElem)); - ++next_path_elem.num_partial_turns; - next_path_elem.how_i_got_here = CONTINUED_MOVING; - } else { - next_path_elem.node = moving_to_node; - next_path_elem.o = moving_to_o; - next_path_elem.moving_to_node = next_path_elem.moving_to_o = -1; - next_path_elem.num_partial_turns = 0; - next_path_elem.how_i_got_here = CONTINUED_MOVING; - finished_moving = true; - } - ++t2; - } - if (finished_moving) { - rnode = moving_to_node; - ro = moving_to_o; - } - if (OverlapsOngoingMove(TINIT, t2, moving_to_node, covered_by, is_covered, is_covered_idx, tmp_path, tmax_at_poz_node)) - return false; - } - const int est_tmin = t2 + dmin_aid[rnode][ro]; - if (est_tmin <= T) { - can_reach[t2][rnode][ro] = can_reach_idx; - can_reach_with_t1[t2][rnode][ro] = t1; - auto& new_prev = prev[t2][rnode][ro]; - new_prev.t = new_prev.node = new_prev.o = -1; - InsertIntoHeap(h, hsize, t2, rnode, ro, t1, est_tmin); - } - } - - int TMIN = T + 1, best_o = -1, best_node = -1, best_t1 = -1; - - if (tmp_path_aid.tmax < TINIT || tmp_path_aid.p[tmp_path_aid.tmax].node == agent_aid.target_node) TMIN = tmp_path_aid.tmax; - - while (hsize >= 1) { - int t, node, o, ct1; - ExtractMinFromHeap(h, hsize, t, node, o, ct1); - assert(0 <= t && t <= T); - assert(can_reach[t][node][o] == can_reach_idx); - if (ct1 != can_reach_with_t1[t][node][o]) continue; - if (/*best_node == target_node &&*/ t + dmin_aid[node][o] > TMIN) break; - if (t > T) continue; - - /*if (t == T && (best_node < 0 || (best_node >= 0 && best_node != target_node && best_t1 < ct1))) { - TMIN = t; - best_node = node; - best_o = o; - best_t1 = ct1; - }*/ - - // Case 1: Wait. - if (t + 1 <= TMIN && t + 1 <= T && CanEnterCell(aid, t + 1, node, node, covered_by, is_covered, is_covered_idx, tmp_path) && - (can_reach[t + 1][node][o] != can_reach_idx || can_reach_with_t1[t + 1][node][o] < ct1) && - (agent_aid.inside_poz || t > ct1)) { - can_reach[t + 1][node][o] = can_reach_idx; - can_reach_with_t1[t + 1][node][o] = ct1; - auto& new_prev = prev[t + 1][node][o]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = WAITED; - const int est_tmin = t + 1 + dmin_aid[node][o]; - if (best_node != target_node || est_tmin <= TMIN) InsertIntoHeap(h, hsize, t + 1, node, o, ct1, est_tmin); - } - - const int tarrive_node2 = t + cturns; - if (tarrive_node2 > TMIN || tarrive_node2 > T) continue; - if (!IsFreeTimeWindow(aid, t + 1, tarrive_node2 - 1, node, covered_by, is_covered, is_covered_idx, tmp_path)) continue; - - // Case 2: Move. - const auto& next_node_o = next[node][o]; - for (int onext = 0; onext <= 3; ++onext) { - const auto& node2 = next_node_o[onext]; - if (node2 >= 0 && node2 < nnodes && CanEnterCell(aid, tarrive_node2, node, node2, covered_by, is_covered, is_covered_idx, tmp_path) && - (can_reach[tarrive_node2][node2][onext] != can_reach_idx || can_reach_with_t1[tarrive_node2][node2][onext] < ct1)) { - if (OverlapsOngoingMove(t, tarrive_node2, node2, covered_by, is_covered, is_covered_idx, tmp_path, tmax_at_poz_node)) - continue; - if (node2 != target_node) { - can_reach[tarrive_node2][node2][onext] = can_reach_idx; - can_reach_with_t1[tarrive_node2][node2][onext] = ct1; - auto& new_prev = prev[tarrive_node2][node2][onext]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = STARTED_MOVING; - const int est_tmin = tarrive_node2 + dmin_aid[node2][onext]; - if (best_node != target_node || est_tmin <= TMIN) InsertIntoHeap(h, hsize, tarrive_node2, node2, onext, ct1, est_tmin); - } else { - can_reach[tarrive_node2][node2][onext] = can_reach_idx; - can_reach_with_t1[tarrive_node2][node2][onext] = ct1; - auto& new_prev = prev[tarrive_node2][node2][onext]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = STARTED_MOVING; - if (best_node != target_node || tarrive_node2 < TMIN || (tarrive_node2 == TMIN && best_t1 < ct1)) { - TMIN = tarrive_node2; - best_node = target_node; - best_o = onext; - best_t1 = ct1; - } - } - } - } - } - - //if (agent_aid.inside_poz) assert(best_o >= 0); - if (best_o < 0) return false; - if (best_node != target_node && !agent_aid.inside_poz) { - tmp_path_aid.tmax = T; - for (int t = TINIT; t <= T; ++t) { - auto& new_path_elem = tmp_path_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - return true; - } - - //assert(best_node == target_node); - - tmp_path_aid.tmax = TMIN; - int ct = TMIN, cnode = best_node, co = best_o; - while (1) { - assert(can_reach[ct][cnode][co] == can_reach_idx); - assert(ct >= can_reach_with_t1[ct][cnode][co]); - const auto& cprev = prev[ct][cnode][co]; - if (cprev.t < 0) break; - if (cprev.type == WAITED || cprev.type == MALFUNCTIONED) { - // Wait 1 unit. - auto& new_path_elem = tmp_path_aid.p[ct]; - new_path_elem.node = cnode; - new_path_elem.o = co; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = cprev.type; - } else { - assert(cprev.type == STARTED_MOVING); - // Move cturns units. - int num_partial_turns = 0; - - for (int tmove = cprev.t; tmove < ct; ++tmove) { - auto& new_path_elem = tmp_path_aid.p[tmove + 1]; - ++num_partial_turns; - if (num_partial_turns < agent_aid.cturns) { - new_path_elem.node = cprev.node; - new_path_elem.o = cprev.o; - new_path_elem.moving_to_node = cnode; - new_path_elem.moving_to_o = co; - new_path_elem.num_partial_turns = num_partial_turns; - new_path_elem.how_i_got_here = num_partial_turns == 1 ? STARTED_MOVING : CONTINUED_MOVING; - } else { - new_path_elem.node = cnode; - new_path_elem.o = co; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = num_partial_turns == 1 ? STARTED_MOVING : CONTINUED_MOVING; - } - } - } - ct = cprev.t; - cnode = cprev.node; - co = cprev.o; - } - - if (!agent_aid.inside_poz) { - for (int t = TINIT + 1; t < ct; ++t) { - auto& new_path_elem = tmp_path_aid.p[t]; - new_path_elem.node = rnode; - new_path_elem.o = ro; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - auto& new_path_elem = tmp_path_aid.p[ct]; - new_path_elem.node = rnode; - new_path_elem.o = ro; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = ENTERED_SRC; - } else { - memcpy(&tmp_path_aid.p[TINIT], &tmp_path2->p[TINIT], (t2 - TINIT + 1) * sizeof(PathElem)); - } - - return true; -} - -bool updated_best_solution; -int rerun; - -vector<pair<int, int>> shpaths_sorted; - -void CoverPath(int aid, const Path& path, int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - for (int t = TINIT; t <= path.tmax; ++t) { - const auto& path_elem = path.p[t]; - if (path_elem.how_i_got_here != OUTSIDE_SRC && path_elem.node != agent_aid.target_node) { - assert(is_covered[t][path_elem.node] != is_covered_idx); - is_covered[t][path_elem.node] = is_covered_idx; - covered_by[t][path_elem.node] = aid; - } - } -} - -void UncoverPath(int aid, const Path& path, int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - for (int t = TINIT; t <= path.tmax; ++t) { - const auto& path_elem = path.p[t]; - if (path_elem.how_i_got_here != OUTSIDE_SRC && path_elem.node != agent_aid.target_node) { - assert(is_covered[t][path_elem.node] == is_covered_idx && covered_by[t][path_elem.node] == aid); - is_covered[t][path_elem.node] = 0; - } - } -} - -void CoverPath1(int aid, const Path& path, int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz) return; - for (int t = TINIT; t <= T; ++t) { - assert(is_covered[t][agent_aid.poz_node] != is_covered_idx); - is_covered[t][agent_aid.poz_node] = is_covered_idx; - covered_by[t][agent_aid.poz_node] = aid; - } -} - -void UncoverPath1(int aid, const Path& path, int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz) return; - for (int t = TINIT; t <= T; ++t) { - assert(is_covered[t][agent_aid.poz_node] == is_covered_idx && covered_by[t][agent_aid.poz_node] == aid); - is_covered[t][agent_aid.poz_node] = 0; - } -} - -bool RunConsistencyChecks(Path path[], const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, bool crash_on_error = true) { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& path_aid = path[aid]; - for (int t = TINIT + 1; t <= path_aid.tmax; ++t) { - const auto& path_elem = path_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - const auto& is_covered1 = is_covered[t][path_elem.node]; - const auto& is_covered2 = is_covered[t - 1][path_elem.node]; - const auto& aid1 = covered_by[t][path_elem.node]; - const auto& aid2 = covered_by[t - 1][path_elem.node]; - if (path_elem.node == agent_aid.target_node) { - if (is_covered1 == is_covered_idx) { - const bool ok = aid1 > aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - if (is_covered2 == is_covered_idx) { - const bool ok = aid2 < aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - } else { - Agent* agent_aid1 = is_covered1 != is_covered_idx ? nullptr : &agent[aid1]; - if (is_covered1 == is_covered_idx && aid1 != aid && agent_aid1->target_node != path_elem.node) { - DBG(0, "!!! [RunConsistencyChecks] aid=%d t=%d node=%d cov=%d how=%d\n", aid, t, path_elem.node, covered_by[t][path_elem.node], path_elem.how_i_got_here); - if (crash_on_error) exit(1); - return false; - } - - const auto& target_node_agents_node = target_node_agents[path_elem.node]; - const auto& num_target_node_agents_node = num_target_node_agents[path_elem.node]; - for (int idx = num_target_node_agents_node - 1; idx >= 0; --idx) { - const auto& aid3 = target_node_agents_node[idx]; - const auto& agent_aid3 = agent[aid3]; - if (agent_aid3.status == DONE_REMOVED) continue; - const auto& path_aid3 = path[aid3]; - bool ok = path_aid3.tmax > TINIT; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - if (path_aid3.tmax == t && path_aid3.p[t].node == path_elem.node) { - ok = aid3 < aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - if (path_aid3.tmax == t + 1 && path_aid3.p[t].node == path_elem.node) { - ok = aid3 > aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - } - - Agent* agent_aid2 = is_covered2 != is_covered_idx ? nullptr : &agent[aid2]; - if (t > TINIT && is_covered2 == is_covered_idx && aid2 > aid && agent_aid2->target_node != path_elem.node) { - DBG(0, "!!! [RunConsistencyChecks] aid=%d t=%d node=%d cov_t-1=%d(target=%d)\n", aid, t, path_elem.node, aid2, agent_aid2->target_node); - if (crash_on_error) exit(1); - return false; - } - } - - if (path_elem.num_partial_turns >= agent_aid.cturns && (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) { - bool ok = path_elem.moving_to_node >= 0; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - if ((is_covered[t][path_elem.moving_to_node] != is_covered_idx && - (is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx || - covered_by[t - 1][path_elem.moving_to_node] <= aid)) || - (is_covered[t][path_elem.moving_to_node] == is_covered_idx && - covered_by[t][path_elem.moving_to_node] >= aid && - (is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx || - covered_by[t - 1][path_elem.moving_to_node] != covered_by[t][path_elem.moving_to_node]))) { - DBG(0, "!!! [RunConsistencyChecks] Agent in motion can enter next cell, but doesn't: aid=%d t=%d node=%d->%d npt=%d/%d cov_t=%d cov_t-1=%d\n", aid, t, path_elem.node, path_elem.moving_to_node, path_elem.num_partial_turns, agent_aid.cturns, is_covered[t][path_elem.moving_to_node] != is_covered_idx ? -1 : covered_by[t][path_elem.moving_to_node], is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx ? -1 : covered_by[t - 1][path_elem.moving_to_node]); - if (crash_on_error) exit(1); - return false; - } - } - } - } - return true; -} - -vector<pair<pair<int, int>, int>> tmoves[MAXNODES]; - -void CheckNonDeadlockPaths() { - return; - if (!USE_SPACING_TO_AVOID_DEADLOCKS) return; - for (int node = 0; node < nnodes; ++node) tmoves[node].clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - - int curr_node = agent_aid.poz_node; - int next_node = agent_aid.moving_to_node; - int tdeparture = TINIT, tarrival = -1; - - for (int t = TINIT + 1; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - if (next_node < 0) { - if (path_elem.node != curr_node) { - next_node = path_elem.node; - tdeparture = t - 1; - } else if (path_elem.moving_to_node >= 0) { - next_node = path_elem.moving_to_node; - tdeparture = t - 1; - } - } - if (path_elem.node == next_node) { - tarrival = t; - if (next_node != agent_aid.target_node) { - tmoves[next_node].push_back({{tarrival, tdeparture}, aid}); - } - curr_node = next_node; - next_node = -1; - } - } - } - for (int node = 0; node < nnodes; ++node) { - auto& tmoves_node = tmoves[node]; - if (tmoves_node.empty()) continue; - sort(tmoves_node.begin(), tmoves_node.end()); - int prev_tarrival = -1, prev_tdeparture = -1, prev_aid = -1; - for (const auto& tuple : tmoves_node) { - const auto& tarrival = tuple.first.first; - const auto& tdeparture = tuple.first.second; - const auto& aid = tuple.second; - if (prev_tarrival > tdeparture) { - DBG(0, "!!! [CheckNonDeadlockPaths] node=%d: aid=%d ct=%d tdep=%d tarr=%d target=%d | aid2=%d ct2=%d tdep2=%d tarr2=%d target2=%d\n", node, aid, agent[aid].cturns, tdeparture, tarrival, agent[aid].target_node, prev_aid, agent[prev_aid].cturns, prev_tdeparture, prev_tarrival, agent[prev_aid].target_node); - DBG(0, " tend_ongoing_move[node]=%d\n", tend_ongoing_move[node]); - exit(1); - } - prev_tarrival = tarrival; - prev_tdeparture = tdeparture; - prev_aid = aid; - } - } -} - -double SCORE_EXPONENT1, SCORE_EXPONENT2; -double MAX_TMAX_WEIGHT; - -#define GetScore(t) (t <= TEST ? pow(1.0 * t / TEST, SCORE_EXPONENT1) : pow(1.0 * t / TEST, SCORE_EXPONENT2)) - -/*void RandomPermutations(int tid, int ntries) { - auto& pused_tid = pused[tid]; - auto& perm_tid = perm[tid]; - auto& xor128_tid = xor128[tid]; - auto& covered_by_tid = covered_by[tid]; - auto& is_covered_tid = is_covered[tid]; - auto& is_covered_idx_tid = is_covered_idx[tid]; - auto& can_reach_tid = can_reach[tid]; - auto& can_reach_idx_tid = can_reach_idx[tid]; - auto& can_reach_with_t1_tid = can_reach_with_t1[tid]; - auto& heap_tid = heap[tid]; - auto& heap_size_tid = heap_size[tid]; - auto& prev_tid = prev[tid]; - auto& tmp_path_tid = tmp_path[tid]; - auto& tmp_path2_tid = tmp_path2[tid]; - auto& tmax_at_poz_node_tid = tmax_at_poz_node[tid]; - - if (tid == 0) { - shpaths_sorted.clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - shpaths_sorted.push_back({agent_aid.malfunc + dmin[aid][agent_aid.poz_node][agent_aid.poz_o], aid}); - } - sort(shpaths_sorted.begin(), shpaths_sorted.end()); - } - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - CopyPath(ipath[aid], &tmp_path_tid[aid]); - } - - int last_trial_update = -1, last_idx_update = -1; - - for (int trial = 1; trial <= ntries; ++trial) { - if (tid == 0 && trial <= 1) { - if (trial == 2) reverse(shpaths_sorted.begin(), shpaths_sorted.end()); - for (int i = 0; i < N; ++i) perm_tid[i] = shpaths_sorted[i].second; - } else { - for (int i = 0; i < N; ++i) pused_tid[i] = 0; - int idx = 0; - if ((0&&trial & 3) >= 2) { - for (int i = 0; i < N; ++i) { - do { - perm_tid[idx] = xor128_tid.rand() % N; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } else if (0&&(trial & 3) == 1) { - for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } else { - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } - } - ++is_covered_idx_tid; - for (int aid = 0; aid < N; ++aid) { - auto& tmax_at_poz_node_tid_aid = tmax_at_poz_node_tid[aid]; - tmax_at_poz_node_tid_aid = -1; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - if (agent_aid.inside_poz) { - tmax_at_poz_node_tid_aid = TINIT; - for (int t = TINIT + 1; t <= tmp_path_tid_aid.tmax; ++t) { - const auto& path_elem = tmp_path_tid_aid.p[t]; - if (path_elem.node != agent_aid.poz_node) break; - tmax_at_poz_node_tid_aid = t; - } - } - } - for (int idx = 0; idx < N; ++idx) { - const auto& aid = perm_tid[idx]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - UncoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - const int curr_tmax = tmp_path_tid_aid.tmax; - FindBestPath(aid, covered_by_tid, is_covered_tid, is_covered_idx_tid, can_reach_tid, can_reach_idx_tid, can_reach_with_t1_tid, heap_tid, heap_size_tid, prev_tid, tmp_path_tid, &tmp_path2_tid[aid], tmax_at_poz_node_tid); - if (tmp_path_tid_aid.tmax < curr_tmax) { - last_trial_update = trial; - last_idx_update = idx; - } - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - auto& tmax_at_poz_node_tid_aid = tmax_at_poz_node_tid[aid]; - tmax_at_poz_node_tid_aid = -1; - if (agent_aid.inside_poz) { - tmax_at_poz_node_tid_aid = TINIT; - for (int t = TINIT + 1; t <= tmp_path_tid_aid.tmax; ++t) { - const auto& path_elem = tmp_path_tid_aid.p[t]; - if (path_elem.node != agent_aid.poz_node) break; - tmax_at_poz_node_tid_aid = t; - } - } - } - } - - if (RunConsistencyChecks(tmp_path_tid, covered_by_tid, is_covered_tid, is_covered_idx_tid, false)) { - int num_done_agents = 0; - double cost = 0.0, max_tmax = 0.0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - assert(tmp_path_tid_aid.tmax > TINIT); - if (tmp_path_tid_aid.tmax > TINIT && tmp_path_tid_aid.tmax <= T && tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node == agent_aid.target_node) { - ++num_done_agents; - cost += pow(tmp_path_tid_aid.tmax, kScoreExponent); - if (tmp_path_tid_aid.tmax > max_tmax) max_tmax = tmp_path_tid_aid.tmax; - } - } - cost += max_tmax * kMaxTmaxWeight; - { - lock_guard<mutex> guard(m); - DBG(3, "[RandomPermutations] rerun=%d tid=%d ltu=%d/%d liu=%d/%d nda=%d/%d cost=%.6lf: maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, last_trial_update, ntries, last_idx_update, N - 1, num_done_agents, num_planned, cost, MAX_DONE_AGENTS, num_planned, MIN_COST, GetTime() - TSTART); - if (num_done_agents > MAX_DONE_AGENTS || (num_done_agents == MAX_DONE_AGENTS && cost < MIN_COST - 1e-6)) { - MAX_DONE_AGENTS = num_done_agents; - MIN_COST = cost; - updated_best_solution = true; - CopyTmpPathToPath(tid); - DBG(0, "[RandomPermutations] rerun=%d tid=%d ltu=%d/%d liu=%d/%d nda=%d/%d cost=%.6lf: maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, last_trial_update, ntries, last_idx_update, N - 1, num_done_agents, num_planned, cost, MAX_DONE_AGENTS, num_planned, MIN_COST, GetTime() - TSTART); - CheckNonDeadlockPaths(); - } - } - } -} -*/ - -void RandomPermutations(int tid, int ntries) { - auto& pused_tid = pused[tid]; - auto& perm_tid = perm[tid]; - auto& xor128_tid = xor128[tid]; - auto& covered_by_tid = covered_by[tid]; - auto& is_covered_tid = is_covered[tid]; - auto& is_covered_idx_tid = is_covered_idx[tid]; - auto& can_reach_tid = can_reach[tid]; - auto& can_reach_idx_tid = can_reach_idx[tid]; - auto& can_reach_with_t1_tid = can_reach_with_t1[tid]; - auto& heap_tid = heap[tid]; - auto& heap_size_tid = heap_size[tid]; - auto& prev_tid = prev[tid]; - auto& tmp_path_tid = tmp_path[tid]; - auto& tmp_path2_tid = tmp_path2[tid]; - auto& tmax_at_poz_node_tid = tmax_at_poz_node[tid]; - - if (tid == 0) { - shpaths_sorted.resize(N); - for (int aid = 0; aid < N; ++aid) { - shpaths_sorted[aid].second = aid; - const auto& agent_aid = agent[aid]; - shpaths_sorted[aid].first = agent_aid.malfunc + dmin[aid][agent_aid.poz_node][agent_aid.poz_o]; - } - sort(shpaths_sorted.begin(), shpaths_sorted.end()); - } - - for (int trial = 1; trial <= ntries; ++trial) { - if (tid == 0 && trial <= 1) { - for (int i = 0; i < N; ++i) perm_tid[i] = shpaths_sorted[i].second; - reverse(shpaths_sorted.begin(), shpaths_sorted.end()); - } else { - for (int i = 0; i < N; ++i) pused_tid[i] = 0; - int idx = 0; - if (0&&(trial & 1) == 1) { - for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } else { - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } - } - ++is_covered_idx_tid; - for (int aid = 0; aid < N; ++aid) { - auto& tmax_at_poz_node_tid_aid = tmax_at_poz_node_tid[aid]; - tmax_at_poz_node_tid_aid = -1; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CopyPath(ipath[aid], &tmp_path_tid_aid); - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - if (agent_aid.inside_poz) { - tmax_at_poz_node_tid_aid = TINIT; - for (int t = TINIT + 1; t <= tmp_path_tid_aid.tmax; ++t) { - const auto& path_elem = tmp_path_tid_aid.p[t]; - if (path_elem.node != agent_aid.poz_node) break; - tmax_at_poz_node_tid_aid = t; - } - } - } - bool inconsistent = false; - for (int idx = 0; idx < N; ++idx) { - const auto& aid = perm_tid[idx]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - UncoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - if (!FindBestPath(aid, covered_by_tid, is_covered_tid, is_covered_idx_tid, can_reach_tid, can_reach_idx_tid, can_reach_with_t1_tid, heap_tid, heap_size_tid, prev_tid, tmp_path_tid, &tmp_path2_tid[aid], tmax_at_poz_node_tid)) { - //inconsistent = true; - //break; - } - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - } - if (!inconsistent && RunConsistencyChecks(tmp_path_tid, covered_by_tid, is_covered_tid, is_covered_idx_tid, false)) { - int num_done_agents = 0; - double cost = 0.0; - int max_tmax = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - assert(tmp_path_tid_aid.tmax > TINIT); - if (tmp_path_tid_aid.tmax > TINIT && tmp_path_tid_aid.tmax <= T && tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node == agent_aid.target_node) { - ++num_done_agents; - cost += GetScore(tmp_path_tid_aid.tmax); - if (tmp_path_tid_aid.tmax > max_tmax) max_tmax = tmp_path_tid_aid.tmax; - } - } - if (num_done_agents >= 1) cost /= num_done_agents; - - { - lock_guard<mutex> guard(m); - if (num_done_agents > MAX_DONE_AGENTS || (num_done_agents == MAX_DONE_AGENTS && cost < MIN_COST - 1e-6)) { - MAX_DONE_AGENTS = num_done_agents; - MIN_COST = cost; - updated_best_solution = true; - CopyTmpPathToPath(tid); - DBG(0, "[RandomPermutations] rerun=%d tid=%d trial=%d/%d maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, trial, ntries, MAX_DONE_AGENTS, num_planned, MIN_COST, GetTime() - TSTART); - } - } - } - } -} - -bool any_best_solution_updates; - -void RegenerateFullPlan() { - ++num_reschedules; - any_best_solution_updates = false; - updated_best_solution = true; - rerun = 0; - - const int kMaxReruns = 4;//2; - - while (updated_best_solution && rerun < kMaxReruns) { - updated_best_solution = false; - ++rerun; - - for (int node = 0; node < nnodes; ++node) tend_ongoing_move[node] = TINIT; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz || agent_aid.status == DONE_REMOVED) continue; - if (agent_aid.moving_to_node >= 0) { - const auto& ipath_aid = ipath[aid]; - const auto& first_path_elem = ipath_aid.p[TINIT]; - assert(ipath_aid.tmax >= TINIT); - tend_ongoing_move[agent_aid.moving_to_node] = TINIT + agent_aid.malfunc + max(0, agent_aid.cturns - first_path_elem.num_partial_turns); - } - } - - int max_threads = thread::hardware_concurrency(); - if (max_threads > MAX_NUM_THREADS) max_threads = MAX_NUM_THREADS; - DBG(2, "max_threads=%d\n", max_threads); - - if (N >= 2) { - thread** th = nullptr; - if (max_threads >= 2) th = new thread*[max_threads - 1]; - - // Random Permutations. - const int kNumRandomPermutations = TINIT == 0 ? 20 /*10*/ : 12 /*6*/; - if (max_threads >= 2) { - for (int tid = 0; tid + 1 < max_threads; ++tid) th[tid] = new thread([tid, kNumRandomPermutations]{ - RandomPermutations(tid, kNumRandomPermutations); - }); - } - RandomPermutations(max_threads - 1, kNumRandomPermutations); - if (max_threads >= 2) { - for (int tid = 0; tid + 1 < max_threads; ++tid) { - auto& th_tid = th[tid]; - th_tid->join(); - delete th_tid; - } - delete th; - } - } else RandomPermutations(0, 1); - - if (updated_best_solution) { - for (int aid = 0; aid < N; ++aid) CopyPath(path[aid], &ipath[aid]); - any_best_solution_updates = true; - } - } - - if (any_best_solution_updates) RecomputeCheckpoints(); -} - -int nodecnt[MAXNODES], nodecnt_marked[MAXNODES], nodecnt_marked_idx; -char is_free[MAXNODES]; - -int next_aidx[NMAX], next_vidx[MAXNODES]; - -void SwapVisitingOrder(int aid1, int idx1, int aid2) { - const auto& checkpoints_aid1 = checkpoints[aid1]; - const auto& checkpoints_aid2 = checkpoints[aid2]; - const int node = checkpoints_aid1[idx1]; - int idx2 = next_aidx[aid2] - 1; - while (idx2 >= 0 && checkpoints_aid2[idx2] != node) --idx2; - assert(idx2 >= 0); - const auto& num_checkpoints_aid1 = num_checkpoints[aid1]; - const auto& num_checkpoints_aid2 = num_checkpoints[aid2]; - const auto& checkpoints_cnt_aid1 = checkpoints_cnt[aid1]; - const auto& checkpoints_cnt_aid2 = checkpoints_cnt[aid2]; - - int num_swaps = 0; - while (idx1 < num_checkpoints_aid1 && idx2 < num_checkpoints_aid2 && checkpoints_aid1[idx1] == checkpoints_aid2[idx2]) { - int vidx1 = -1, cnt1 = 0, vidx2 = -1, cnt2 = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[checkpoints_aid1[idx1]]; - for (int idx = 0; idx < ipath_visiting_order_node.size() && (vidx1 < 0 || vidx2 < 0); ++idx) { - const auto& elem_pair = ipath_visiting_order_node[idx]; - if (elem_pair.second == aid1) { - ++cnt1; - if (cnt1 == checkpoints_cnt_aid1[idx1]) vidx1 = idx; - } - if (elem_pair.second == aid2) { - ++cnt2; - if (cnt2 == checkpoints_cnt_aid2[idx2]) vidx2 = idx; - } - } - assert(vidx1 >= 0 && vidx2 >= 0); - assert(vidx1 > vidx2); - ipath_visiting_order_node[vidx1].second = aid2; - ipath_visiting_order_node[vidx2].second = aid1; - ++idx1; - ++idx2; - ++num_swaps; - } - - /*for (int node = 0; node < nnodes; ++node) { - int vidx1 = -1, cnt1 = 0, vidx2 = -1, cnt2 = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - for (int idx = 0; idx < ipath_visiting_order_node.size() && (vidx1 < 0 || vidx2 < 0); ++idx) { - const auto& elem_pair = ipath_visiting_order_node[idx]; - if (elem_pair.second == aid1) vidx1 = idx; - if (elem_pair.second == aid2) vidx2 = idx; - } - if (vidx1 >= 0 && vidx2 >= 0) { - ipath_visiting_order_node[vidx1].second = aid2; - ipath_visiting_order_node[vidx2].second = aid1; - ++num_swaps; - } - }*/ - - DBG(2, "[SwapVisitingOrder] aid1=%d aid2=%d idx1=%d num_swaps=%d\n", aid1, aid2, idx1, num_swaps); - - //exit(1); -} - -#define QMOD 255 -int qaid[QMOD + 1]; - -bool AdjustIPaths() { - /*for (int aid = 0; aid < N; ++aid) { - if (aid == 46) { - const auto& ipath_aid = ipath[aid]; - for (int t = max(TINIT, 795); t <= 805 && t <= ipath_aid.tmax; ++t) { - const auto& elem = ipath_aid.p[t]; - DBG(0, "aid=%d t=%d node=%d npt=%d\n", aid, t, elem.node, elem.num_partial_turns); - } - } - }*/ - - ++num_adjust_ipaths; - - nodecnt_marked_idx = 0; - for (int node = 0; node < nnodes; ++node) { - ipath_visiting_order[node].clear(); - nodecnt_marked[node] = 0; - } - - int max_tmax = 0; - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - auto& path_aid = path[aid]; - if (agent_aid.status == DONE_REMOVED) { - CopyPath(ipath_aid, &path_aid); - continue; - } - - if (ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node && ipath_aid.tmax > max_tmax) max_tmax = ipath_aid.tmax; - - auto& new_path_elem = path_aid.p[TINIT]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.num_partial_turns = 0; - while (fabs(agent_aid.poz_frac - new_path_elem.num_partial_turns * agent_aid.speed) >= ZERO) - ++new_path_elem.num_partial_turns; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - if (agent_aid.inside_poz) { - const auto& first_expected_step = ipath_aid.p[TINIT]; - if (new_path_elem.num_partial_turns >= 1) { - if (first_expected_step.num_partial_turns >= 1) { - if (agent_aid.fresh_malfunc) - assert(first_expected_step.num_partial_turns >= new_path_elem.num_partial_turns); - assert(first_expected_step.node == agent_aid.poz_node); - assert(first_expected_step.o == agent_aid.poz_o); - new_path_elem.moving_to_node = first_expected_step.moving_to_node; - new_path_elem.moving_to_o = first_expected_step.moving_to_o; - assert(0 <= new_path_elem.moving_to_node && new_path_elem.moving_to_node < nnodes); - assert(0 <= new_path_elem.moving_to_o && new_path_elem.moving_to_o < nnodes); - } else { - assert(new_path_elem.num_partial_turns >= agent_aid.cturns - 1); - assert(first_expected_step.node != agent_aid.poz_node || first_expected_step.o != agent_aid.poz_o); - assert(first_expected_step.moving_to_node < 0); - assert(first_expected_step.moving_to_o < 0); - new_path_elem.moving_to_node = first_expected_step.node; - new_path_elem.moving_to_o = first_expected_step.o; - } - } - if (agent_aid.fresh_malfunc) new_path_elem.how_i_got_here = MALFUNCTIONED; - else new_path_elem.how_i_got_here = first_expected_step.how_i_got_here; - } else new_path_elem.how_i_got_here = OUTSIDE_SRC; - - const int tmin = TINIT + max(0, agent_aid.malfunc - (agent_aid.inside_poz ? 0 : 1)); - for (int t = TINIT + 1; t <= tmin && t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = agent_aid.inside_poz ? MALFUNCTIONED : OUTSIDE_SRC; - } - - const auto& next_checkpoint_aid = next_checkpoint[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - - if (next_checkpoint_aid == num_checkpoints_aid) { - assert(!agent_aid.inside_poz); - continue; - } - - assert(1 <= next_checkpoint_aid && next_checkpoint_aid < num_checkpoints_aid); - - auto& tcheckpoints_aid = tcheckpoints[aid]; - tcheckpoints_aid[next_checkpoint_aid - 1] = path_aid.tmax = tmin; - - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_cnt_aid = checkpoints_cnt[aid]; - - ++nodecnt_marked_idx; - - if (agent_aid.inside_poz) { - nodecnt_marked[agent_aid.poz_node] = nodecnt_marked_idx; - nodecnt[agent_aid.poz_node] = checkpoints_cnt_aid[next_checkpoint_aid - 1] = 1; - assert(checkpoints_aid[next_checkpoint_aid - 1] == agent_aid.poz_node); - } - - for (int cid = next_checkpoint_aid; cid < num_checkpoints_aid; ++cid) { - const auto& node = checkpoints_aid[cid]; - if (nodecnt_marked[node] != nodecnt_marked_idx) { - nodecnt_marked[node] = nodecnt_marked_idx; - nodecnt[node] = 0; - } - checkpoints_cnt_aid[cid] = ++nodecnt[node]; - } - } - - RepopulateVisitingOrders(); - - auto& is_covered_0 = is_covered[0]; - auto& is_covered_idx_0 = is_covered_idx[0]; - auto& covered_by_0 = covered_by[0]; - - bool updated_visiting_order = true; - int nelems = 0; - - while (updated_visiting_order) { - updated_visiting_order = false; - ++is_covered_idx_0; - - for (int node = 0; node < nnodes; ++node) is_free[node] = 1; - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - next_aidx[aid] = next_checkpoint[aid]; - auto& path_aid = path[aid]; - const int tmin = TINIT + max(0, agent_aid.malfunc - (agent_aid.inside_poz ? /*1*/ 0 : /*2*/ 1)); - for (int t = TINIT + 1; t <= tmin && t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = agent_aid.inside_poz ? MALFUNCTIONED : OUTSIDE_SRC; - if (agent_aid.inside_poz) { - assert(is_covered_0[t][new_path_elem.node] != is_covered_idx_0); - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - } - } - - path_aid.tmax = tmin; - - if (agent_aid.inside_poz) { - is_free[agent_aid.poz_node] = 0; - is_covered_0[TINIT][agent_aid.poz_node] = is_covered_idx_0; - covered_by_0[TINIT][agent_aid.poz_node] = aid; - } - } - - int qli = 0, qls = 0; - - for (int node = 0; node < nnodes; ++node) { - next_vidx[node] = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - if (ipath_visiting_order_node.empty()) continue; - for (auto& elem_pair : ipath_visiting_order_node) elem_pair.first = TINIT; - const auto& aid_0 = ipath_visiting_order_node[0].second; - if (is_free[node] && checkpoints[aid_0][next_aidx[aid_0]] == node) { - qaid[qls] = aid_0; - qls = (qls + 1) & QMOD; - } - } - - nelems = 0; - - int tmin_incomplete = -1, aid_incomplete = -1; - - while (qli != qls) { - ++nelems; - - const auto& aid = qaid[qli]; - const auto& agent_aid = agent[aid]; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& tcheckpoints_aid = tcheckpoints[aid]; - auto& next_aidx_aid = next_aidx[aid]; - const auto& next_checkpoint_aid = next_checkpoint[aid]; - assert(next_checkpoint_aid <= next_aidx_aid && next_aidx_aid < num_checkpoints[aid]); - const auto& curr_node = checkpoints_aid[next_aidx_aid - 1]; - const auto& next_node = checkpoints_aid[next_aidx_aid]; - - qli = (qli + 1) & QMOD; - - assert(0 <= next_node && next_node < nnodes); - assert(is_free[next_node]); - if (curr_node >= 0) assert(!is_free[curr_node]); - - const auto& t_curr_node = tcheckpoints_aid[next_aidx_aid - 1]; - const auto& next_o = checkpoints_o_aid[next_aidx_aid]; - - auto& next_vidx_next_node = next_vidx[next_node]; - auto& ipath_visiting_order_next_node = ipath_visiting_order[next_node]; - assert(next_vidx_next_node < ipath_visiting_order_next_node.size()); - assert(ipath_visiting_order_next_node[next_vidx_next_node].second == aid); - - int tend_move = ipath_visiting_order_next_node[next_vidx_next_node].first; - - //const bool print_debug = (aid == 76 || aid == 24) && (curr_node == 117 || next_node == 117); - const bool print_debug = false; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-A] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tend_move=%d(init) \n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tend_move); - - auto& path_aid = path[aid]; - - if (next_aidx_aid > next_checkpoint_aid && path_aid.tmax <= T) assert(path_aid.p[path_aid.tmax].num_partial_turns == 0); - - const int move_duration = max(1, curr_node < 0 ? 1 : (next_aidx_aid == next_checkpoint_aid ? agent_aid.cturns - path_aid.p[TINIT].num_partial_turns : agent_aid.cturns)); - int tstart_move = tend_move - move_duration; - if (tstart_move < t_curr_node) tstart_move = t_curr_node; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-B] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tstart_move=%d tend_move=%d move_duration=%d\n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tstart_move, tend_move, move_duration); - - assert(path_aid.tmax == t_curr_node); - if (t_curr_node <= T && curr_node >= 0) assert(path_aid.p[t_curr_node].node == curr_node); - int t = t_curr_node + 1; - - tend_move = tstart_move + move_duration; - - if (!agent_aid.inside_poz && next_aidx_aid == next_checkpoint_aid) { - for (; t <= tstart_move; ++t) { - assert(path_aid.tmax == t - 1); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - } - assert(t == tend_move); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = ENTERED_SRC; - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - assert(t == tend_move); - } - ++t; - } - - if (curr_node >= 0) { - if (path_aid.p[TINIT].num_partial_turns >= 1) assert(agent_aid.moving_to_node >= 0); - if (next_aidx_aid > next_checkpoint_aid || /*path_aid.p[TINIT].num_partial_turns == 0*/ agent_aid.moving_to_node < 0) { - for (; t <= tstart_move; ++t) { - assert(path_aid.tmax == t - 1); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = WAITED; - assert(new_path_elem.num_partial_turns == 0); - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - } - } - } - int num_partial_turns = next_aidx_aid > next_checkpoint_aid ? 0 : path_aid.p[TINIT].num_partial_turns; - for (; 1; ++t) { - assert(path_aid.tmax == t - 1); - assert(t > TINIT); - path_aid.tmax = t; - PathElem* new_path_elem = nullptr; - if (t <= T) new_path_elem = &path_aid.p[t]; - if (new_path_elem != nullptr) memcpy(new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - ++num_partial_turns; - if (print_debug) DBG(0, " aid=%d t=%d/%d npt=%d\n", aid, t, tend_move, num_partial_turns); - if (new_path_elem != nullptr) { - new_path_elem->num_partial_turns = num_partial_turns; - if (new_path_elem->num_partial_turns == 1) new_path_elem->how_i_got_here = STARTED_MOVING; - else new_path_elem->how_i_got_here = CONTINUED_MOVING; - new_path_elem->moving_to_node = next_node; - new_path_elem->moving_to_o = next_o; - if (new_path_elem->num_partial_turns >= 2) { - if (print_debug) DBG(0, " prev_moving_to=(%d %d)\n", path_aid.p[t - 1].moving_to_node, path_aid.p[t - 1].moving_to_o); - assert(path_aid.p[t - 1].moving_to_node == next_node); - assert(path_aid.p[t - 1].moving_to_o == next_o); - } - } - if (num_partial_turns >= agent_aid.cturns) { - if (t >= tend_move) { - if (new_path_elem != nullptr) { - new_path_elem->node = next_node; - new_path_elem->o = next_o; - new_path_elem->moving_to_node = new_path_elem->moving_to_o = -1; - new_path_elem->num_partial_turns = 0; - if (new_path_elem->node != agent_aid.target_node) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - } - } - tend_move = t; - ++t; - break; - } else if (new_path_elem != nullptr) { - if (print_debug) DBG(0, " >>> is_cov_next_node=%d cov_by=%d\n", is_covered_0[t][next_node] == is_covered_idx_0, covered_by_0[t][next_node]); - if ((is_covered_0[t][next_node] != is_covered_idx_0 && - (is_covered_0[t - 1][next_node] != is_covered_idx_0 || - covered_by_0[t - 1][next_node] < aid)) || - (is_covered_0[t][next_node] == is_covered_idx_0 && covered_by_0[t][next_node] > aid && - (is_covered_0[t - 1][next_node] != is_covered_idx_0 || - covered_by_0[t - 1][next_node] != covered_by_0[t][next_node]))) { - DBG(0, "||| [AdjustIPaths] Agent in motion cannot wait for delayed agent: aid=%d next_aidx_aid=%d nextcp=%d tend=%d t=%d curr_node=%d:(%d %d) next_node=%d:(%d %d) next_vidx_next_node=%d target_node=%d:(%d %d) nelems=%d\n", aid, next_aidx_aid, next_checkpoint[aid], tend_move, t, curr_node, node[curr_node].row, node[curr_node].col, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, agent_aid.target_node, node[agent_aid.target_node].row, node[agent_aid.target_node].col, nelems); - assert(next_vidx_next_node >= 1); - const int prev_aid = ipath_visiting_order_next_node[next_vidx_next_node - 1].second; - DBG(0, " prev_aid=%d\n", prev_aid); - SwapVisitingOrder(aid, next_aidx_aid, prev_aid); - updated_visiting_order = true; - break; - } - if (new_path_elem->node != agent_aid.target_node) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - } - } - } else if (new_path_elem != nullptr) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - assert(num_partial_turns >= 1); - assert(0 <= new_path_elem->moving_to_node && new_path_elem->moving_to_node < nnodes); - } - } - } - - if (updated_visiting_order) break; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-C] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tstart_move=%d tend_move=%d move_duration=%d\n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tstart_move, tend_move, move_duration); - - if (t != tend_move + 1) { - DBG(0, "!!!A aid=%d next_aidx_aid=%d curr_node=%d curr_npt=%d curr_how=%d next_node=%d tstart_move=%d tend_move=%d t=%d: last_path_elem=(node=%d npt=%d/%d how=%d)\n", aid, next_aidx_aid, curr_node, path_aid.p[t_curr_node].num_partial_turns, path_aid.p[t_curr_node].how_i_got_here, next_node, tstart_move, tend_move, t, path_aid.p[path_aid.tmax].node, path_aid.p[path_aid.tmax].num_partial_turns, agent_aid.cturns, path_aid.p[path_aid.tmax].how_i_got_here); - exit(1); - } - - assert(path_aid.tmax == tend_move); - if (tend_move <= T && path_aid.p[tend_move].node != next_node) { - DBG(0, "!!!B aid=%d next_aidx_aid=%d curr_node=%d curr_npt=%d curr_how=%d next_node=%d tstart_move=%d tend_move=%d: last_path_elem=(node=%d npt=%d/%d how=%d)\n", aid, next_aidx_aid, curr_node, path_aid.p[t_curr_node].num_partial_turns, path_aid.p[t_curr_node].how_i_got_here, next_node, tstart_move, tend_move, path_aid.p[path_aid.tmax].node, path_aid.p[path_aid.tmax].num_partial_turns, agent_aid.cturns, path_aid.p[path_aid.tmax].how_i_got_here); - exit(1); - } - - tcheckpoints_aid[next_aidx_aid] = tend_move; - if (curr_node >= 0) is_free[curr_node] = 1; - is_free[next_node] = 0; - ++next_aidx_aid; - ++next_vidx_next_node; - - if (next_aidx_aid < num_checkpoints[aid]) { - const auto& next2_node = checkpoints_aid[next_aidx_aid]; - auto& next_vidx2_next2_node = next_vidx[next2_node]; - auto& ipath_visiting_order_next2_node = ipath_visiting_order[next2_node]; - if (next2_node != curr_node && ipath_visiting_order_next2_node[next_vidx2_next2_node].second == aid && is_free[next2_node]) { - qaid[qls] = aid; - qls = (qls + 1) & QMOD; - } - } else if (next_node == agent_aid.target_node) { - // Free up next_node right away. - is_free[next_node] = 1; - if (next_vidx_next_node < ipath_visiting_order_next_node.size()) { - const auto& aid1 = ipath_visiting_order_next_node[next_vidx_next_node].second; - const auto& path_aid1 = path[aid1]; - const auto& last_path_elem = path_aid1.p[path_aid1.tmax]; - int tend_move_aid1 = tend_move + (aid1 < aid && agent[aid1].target_node != next_node ? 1 : 0); - const auto& agent_aid1 = agent[aid1]; - if (USE_SPACING_TO_AVOID_DEADLOCKS && last_path_elem.num_partial_turns == 0 && (next_aidx[aid1] > next_checkpoint[aid1] || agent[aid1].moving_to_node < 0)) { - const int min_tstart = tend_move;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? tend_move : t_curr_node; - assert(t_curr_node < tend_move); - if (tend_move_aid1 - agent_aid1.cturns < min_tstart) tend_move_aid1 = min_tstart + agent_aid1.cturns; - } - ipath_visiting_order_next_node[next_vidx_next_node].first = tend_move_aid1; - if (checkpoints[aid1][next_aidx[aid1]] == next_node) { - qaid[qls] = aid1; - qls = (qls + 1) & QMOD; - } - } - } - - if (curr_node >= 0) { - const auto& next_vidx_curr_node = next_vidx[curr_node]; - auto& ipath_visiting_order_curr_node = ipath_visiting_order[curr_node]; - if (next_vidx_curr_node < ipath_visiting_order_curr_node.size()) { - const auto& aid1 = ipath_visiting_order_curr_node[next_vidx_curr_node].second; - const auto& path_aid1 = path[aid1]; - const auto& last_path_elem = path_aid1.p[path_aid1.tmax]; - int tend_move_aid1 = tend_move + (aid1 < aid ? 1 : 0); - const auto& agent_aid1 = agent[aid1]; - if (USE_SPACING_TO_AVOID_DEADLOCKS && last_path_elem.num_partial_turns == 0 && (next_aidx[aid1] > next_checkpoint[aid1] || agent[aid1].moving_to_node < 0)) { - const int min_tstart = t_curr_node;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? tend_move : t_curr_node; - assert(t_curr_node < tend_move); - if (tend_move_aid1 - agent_aid1.cturns < min_tstart) tend_move_aid1 = min_tstart + agent_aid1.cturns; - } - ipath_visiting_order_curr_node[next_vidx_curr_node].first = tend_move_aid1; - if (checkpoints[aid1][next_aidx[aid1]] == curr_node) { - qaid[qls] = aid1; - qls = (qls + 1) & QMOD; - } - } - } - } - - DBG(2, "[AdjustIPaths] nelems=%d updvis=%d\n", nelems, updated_visiting_order); - if (updated_visiting_order) continue; - - if (aid_incomplete < 0) { - for (int node = 0; node < nnodes; ++node) { - const auto& next_vidx_node = next_vidx[node]; - const auto& ipath_visiting_order_node = ipath_visiting_order[node]; - if (next_vidx_node < ipath_visiting_order_node.size()) { - const auto& aid = ipath_visiting_order_node[next_vidx_node].second; - const auto& next_aidx_aid = next_aidx[aid]; - DBG(0, "[AdjustIPaths] incomplete: node=%d is_free=%d next_vidx=%d/%d: aid=%d next_aidx_aid=%d/%d:node=%d/t=%d nextcp=%d\n", node, is_free[node], next_vidx_node, ipath_visiting_order_node.size(), aid, next_aidx_aid, num_checkpoints[aid], checkpoints[aid][next_aidx_aid], checkpoints_t[aid][next_aidx_aid], next_checkpoint[aid]); - assert(next_aidx_aid < num_checkpoints[aid]); - assert(!is_free[node] || checkpoints[aid][next_aidx_aid] != node); - const auto& t_inc = max(ipath_visiting_order_node[next_vidx_node].first, tcheckpoints[aid][next_aidx_aid - 1]); - if (aid_incomplete < 0 || t_inc < tmin_incomplete) { - aid_incomplete = aid; - tmin_incomplete = t_inc; - } - } - } - - assert(aid_incomplete < 0); - } - } - - ++is_covered_idx_0; - - for (int aid = 0; aid < N; ++aid) { - auto& ipath_aid = ipath[aid]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - - const auto& num_checkpoints_aid = num_checkpoints[aid]; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& tcheckpoints_aid = tcheckpoints[aid]; - const auto& next_aidx_aid = next_aidx[aid]; - - if (next_aidx_aid < num_checkpoints_aid) { - const auto& v = checkpoints_aid[next_aidx_aid]; - const auto& ipath_visiting_order_v = ipath_visiting_order[v]; - const auto& next_vidx_v = next_vidx[v]; - assert(next_vidx_v < ipath_visiting_order_v.size()); - DBG(0, "!!! [AdjustIPaths] aid=%d next_aidx_aid=%d/%d: v=%d(%d) next_vidx_v=%d/%d: t=%d vaid=%d\n", aid, next_aidx_aid, num_checkpoints_aid, v, is_free[v], next_vidx_v, ipath_visiting_order_v.size(), ipath_visiting_order_v[next_vidx_v].first, ipath_visiting_order_v[next_vidx_v].second); - exit(1); - } - - // Construct the path. - auto& path_aid = path[aid]; - if (path_aid.tmax > T) path_aid.tmax = T; - - if (path_aid.p[path_aid.tmax].how_i_got_here == OUTSIDE_SRC) { - for (int t = path_aid.tmax + 1; t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - path_aid.tmax = T; - } else if (path_aid.tmax < T && path_aid.p[path_aid.tmax].node != agent_aid.target_node) { - const auto& last_num_partial_turns = path_aid.p[path_aid.tmax].num_partial_turns; - const auto& last_how_i_got_here = path_aid.p[path_aid.tmax].how_i_got_here; - DBG(3, "!!! [AdjustIPaths] aid=%d next_aidx_aid=%d/%d tmax=%d/%d last_node=%d:(%d %d) npt=%d/%d target_node=%d:(%d %d)\n", aid, next_aidx[aid], num_checkpoints[aid], path_aid.tmax, T, path_aid.p[path_aid.tmax].node, node[path_aid.p[path_aid.tmax].node].row, node[path_aid.p[path_aid.tmax].node].col, last_num_partial_turns, agent_aid.cturns, agent_aid.target_node, node[agent_aid.target_node].row, node[agent_aid.target_node].col); - while (path_aid.tmax < T) { - ++path_aid.tmax; - auto& new_path_elem = path_aid.p[path_aid.tmax]; - memcpy(&new_path_elem, &path_aid.p[path_aid.tmax - 1], sizeof(PathElem)); - if (last_num_partial_turns == 0) - new_path_elem.how_i_got_here = last_how_i_got_here == OUTSIDE_SRC ? OUTSIDE_SRC : WAITED; - else { - ++new_path_elem.num_partial_turns; - new_path_elem.how_i_got_here = CONTINUED_MOVING; - } - } - } - - assert(path_aid.tmax <= T); - for (int t = TINIT; t <= path_aid.tmax; ++t) { - const auto& path_elem = path_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - if (path_elem.node == agent_aid.target_node) { - assert(t == path_aid.tmax); - continue; - } - assert(0 <= path_elem.node && path_elem.node < nnodes); - if (is_covered_0[t][path_elem.node] == is_covered_idx_0) { - DBG(0, "!!! [AdjustIPaths] aid=%d t=%d node=%d already covered by %d\n", aid, t, path_elem.node, covered_by_0[t][path_elem.node]); - exit(1); - } - is_covered_0[t][path_elem.node] = is_covered_idx_0; - covered_by_0[t][path_elem.node] = aid; - } - - if (path_aid.tmax != ipath_aid.tmax || path_aid.p[path_aid.tmax].node != ipath_aid.p[path_aid.tmax].node) { - DBG(3, "[AdjustIPaths] aid=%d diff: prev:(tmax=%d node=%d) curr:(tmax=%d node=%d)\n", aid, path_aid.tmax, path_aid.p[path_aid.tmax].node, ipath_aid.tmax, ipath_aid.p[ipath_aid.tmax].node); - } - - CopyPath(path_aid, &ipath_aid); - } - - RunConsistencyChecks(path, covered_by_0, is_covered_0, is_covered_idx_0); - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - auto& checkpoints_t_aid = checkpoints_t[aid]; - const auto& tcheckpoints_aid = tcheckpoints[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - for (int cid = next_checkpoint[aid]; cid < num_checkpoints_aid; ++cid) - checkpoints_t_aid[cid] = tcheckpoints_aid[cid]; - } - - MAX_DONE_AGENTS = 0; - MIN_COST = 0.0; - int new_max_tmax = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& path_aid = path[aid]; - assert(path_aid.tmax > TINIT); - if (path_aid.p[path_aid.tmax].node == agent_aid.target_node) { - ++MAX_DONE_AGENTS; - MIN_COST += GetScore(path_aid.tmax); - if (path_aid.tmax > new_max_tmax) new_max_tmax = path_aid.tmax; - } else { - assert(path_aid.tmax == T); - } - } - if (MAX_DONE_AGENTS >= 1) MIN_COST /= MAX_DONE_AGENTS; - - const bool changed_important_data = MAX_DONE_AGENTS != num_planned || new_max_tmax > max_tmax; - if (changed_important_data) { - DBG(0, ">>> [AdjustIPaths] mda=%d/%d minc=%.6lf new_max_tmax=%d/%d\n", MAX_DONE_AGENTS, num_planned, MIN_COST, new_max_tmax, max_tmax); - } - - CheckNonDeadlockPaths(); - - return !changed_important_data; -} - -void ReinitDataStructures() { - MAX_DONE_AGENTS = 0; - MIN_COST = 1e10; - for (int aid = 0; aid < N; ++aid) path[aid].tmax = -1000; - xor128[0].reset(14012019U); - for (int tid = 1; tid < MAX_NUM_THREADS; ++tid) xor128[tid].reset(19999997U * tid + 29997U); - for (int tid = 0; tid < MAX_NUM_THREADS; ++tid) { - can_reach_idx[tid] = is_covered_idx[tid] = 0; - auto& can_reach_tid = can_reach[tid]; - auto& is_covered_tid = is_covered[tid]; - for (int t = 0; t <= T + 2; ++t) { - auto& can_reach_tid_t = can_reach_tid[t]; - auto& is_covered_tid_t = is_covered_tid[t]; - for (int i = 0; i < nnodes; ++i) { - is_covered_tid_t[i] = 0; - auto& can_reach_tid_t_i = can_reach_tid_t[i]; - for (int o = 0; o <= 3; ++o) can_reach_tid_t_i[o] = 0; - } - } - } -} - -int GetMove(int aid) { - if (num_planned == 0) return DO_NOTHING; - const auto& path_aid = path[aid]; - auto& agent_aid = agent[aid]; - if (path_aid.tmax < TINIT + 1) return DO_NOTHING; - const auto& path_elem = path_aid.p[TINIT]; - const auto& path_elem_end_turn = path_aid.p[TINIT + 1]; - int action = DO_NOTHING; - DBG(2, " GetMove for aid=%d: tmax=%d\n", aid, path_aid.tmax); - if (path_elem_end_turn.how_i_got_here == ENTERED_SRC) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node < 0); - assert(path_elem.moving_to_o < 0); - assert(path_elem_end_turn.num_partial_turns == 0); - action = MOVE_FORWARD; - assert(agent_aid.moving_to_node < 0); - } else if (path_elem_end_turn.how_i_got_here == WAITED) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node < 0); - assert(path_elem.moving_to_o < 0); - assert(path_elem.num_partial_turns == 0); - assert(path_elem_end_turn.num_partial_turns == 0); - action = STOP_MOVING; - assert(agent_aid.moving_to_node < 0); - } else if (path_elem_end_turn.how_i_got_here == STARTED_MOVING) { - assert(path_elem_end_turn.num_partial_turns <= 1); - int dst_node = -1, dst_o = -1; - if (path_elem_end_turn.moving_to_node >= 0 && path_elem_end_turn.moving_to_o >= 0) { - assert(path_elem_end_turn.num_partial_turns == 1); - dst_node = path_elem_end_turn.moving_to_node; - dst_o = path_elem_end_turn.moving_to_o; - } else { - assert(path_elem_end_turn.num_partial_turns == 0); - dst_node = path_elem_end_turn.node; - dst_o = path_elem_end_turn.o; - } - assert(path_elem.node != dst_node); - assert(next[path_elem.node][path_elem.o][dst_o] == dst_node); - if (dst_o == path_elem.o || dst_o == ((path_elem.o + 2) & 3)) - action = MOVE_FORWARD; - else if (dst_o == ((path_elem.o + 1) & 3)) - action = MOVE_RIGHT; - else if (dst_o == ((path_elem.o + 3) & 3)) - action = MOVE_LEFT; - else { - DBG(0, "Incorrect move!!!\n"); - exit(1); - } - assert(agent_aid.moving_to_node < 0 || (agent_aid.moving_to_node == dst_node && agent_aid.moving_to_o == dst_o)); - agent_aid.moving_to_node = dst_node; - agent_aid.moving_to_o = dst_o; - } else if (path_elem_end_turn.how_i_got_here == CONTINUED_MOVING) { - if (path_elem.node == path_elem_end_turn.node) { - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node == path_elem_end_turn.moving_to_node); - assert(path_elem_end_turn.num_partial_turns == path_elem.num_partial_turns + 1); - } else { - assert(path_elem_end_turn.moving_to_node < 0); - assert(path_elem_end_turn.moving_to_o < 0); - assert(path_elem_end_turn.num_partial_turns == 0); - } - } else if (path_elem_end_turn.how_i_got_here == MALFUNCTIONED) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node == path_elem_end_turn.moving_to_node); - assert(path_elem.moving_to_o == path_elem_end_turn.moving_to_o); - assert(path_elem.num_partial_turns == path_elem_end_turn.num_partial_turns); - } - return action; -} - -void WriteMoves(const char* testid) { - num_planned = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - if (ipath_aid.tmax > TINIT && ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node) ++num_planned; - } - sprintf(fname, "output-%s.txt", testid); - FILE* f = fopen(fname, "w"); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const int action = GetMove(aid); - fprintf(f, "%d ", action); - if (action != DO_NOTHING) DBG(2, " Move aid=%d: %d\n", aid, action); - } - fprintf(f, "\n"); - fclose(f); -} - -void SaveDataForReplay(const char* testid) { - sprintf(fname, "saved-%s-%d.txt", testid, TINIT); - FILE* f = fopen(fname, "w"); - fprintf(f, "1\n%d %d\n", H, W); - for (int v = 0; v < nnodes; ++v) { - const auto& node_v = node[v]; - const auto& next_v = next[v]; - for (int o1 = 0; o1 <= 3; ++o1) for (int o2 = 0; o2 <= 3; ++o2) - if (next_v[o1][o2] >= 0) fprintf(f, "%d %d %d %d\n", node_v.row, node_v.col, o1, o2); - } - fprintf(f, "-1 -1 -1 -1\n%d %d\n%d %d %d\n", N, TINIT, num_reschedules, num_planned, num_adjust_ipaths_without_full_plan_regeneration); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - fprintf(f, "%d %d %d %d %d %d %.10lf %.10lf %d %d %d %d 1 1 %d %d %d\n", agent_aid.aid, agent_aid.poz_row, agent_aid.poz_col, agent_aid.poz_o, agent_aid.target_row, agent_aid.target_col, agent_aid.speed, agent_aid.poz_frac, agent_aid.malfunc, agent_aid.nr_malfunc, agent_aid.status, agent_aid.fresh_malfunc, agent_aid.moving_to_node >= 0 ? node[agent_aid.moving_to_node].row : -1, agent_aid.moving_to_node >= 0 ? node[agent_aid.moving_to_node].col : -1, agent_aid.moving_to_o); - const auto& ipath_aid = ipath[aid]; - fprintf(f, "%d\n", ipath_aid.tmax); - for (int t = TINIT; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - fprintf(f, "%d %d %d %d %d %d %d %d\n", node[path_elem.node].row, node[path_elem.node].col, path_elem.o, path_elem.moving_to_node < 0 ? -1 : node[path_elem.moving_to_node].row, path_elem.moving_to_node < 0 ? -1 : node[path_elem.moving_to_node].col, path_elem.moving_to_o, path_elem.num_partial_turns, path_elem.how_i_got_here); - } - const auto& num_checkpoints_aid = num_checkpoints[aid]; - const auto& next_checkpoint_aid = next_checkpoint[aid]; - fprintf(f, "%d\n", num_checkpoints_aid - next_checkpoint_aid); - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - const auto& checkpoints_t_aid = checkpoints_t[aid]; - for (int cid = next_checkpoint_aid; cid < num_checkpoints_aid; ++cid) { - fprintf(f, "%d %d %d %d\n", node[checkpoints_aid[cid]].row, node[checkpoints_aid[cid]].col, checkpoints_o_aid[cid], checkpoints_t_aid[cid]); - } - } - fprintf(f, "%d\n", T); - fclose(f); -} - -double total_time; - -void GetMoves(const char* testid, bool replay_mode = false) { - TSTART = GetTime(); - sprintf(fname, "input-%s.txt", testid); - fin = fopen(fname, "r"); - ReadTransitionsMap(); - ReadAgentsData(replay_mode); - fclose(fin); - if (TINIT == 0 || replay_mode) { - ReinitDataStructures(); - ComputeShortestPaths(); - } - SCORE_EXPONENT1 = 2.0;//2.0; - SCORE_EXPONENT2 = 4.0;//3.0; - DBG(2, "testid=%s TINIT=%d: resc=%d nda=%d npl=%d\n", testid, TINIT, reschedule, num_done_agents, num_planned); - if (reschedule) { - if (TINIT >= MIN_TINIT_FOR_SAVE_DATA_FOR_REPLAY) SaveDataForReplay(testid); - bool updated_paths_ok = false; - if (TINIT >= 1) { - updated_paths_ok = AdjustIPaths(); - ++num_adjust_ipaths_without_full_plan_regeneration; - } - const int kMaxNumAdjustIPathsWithoutFullPlanRegenartion = 5;//10; - if (!updated_paths_ok || num_adjust_ipaths_without_full_plan_regeneration > kMaxNumAdjustIPathsWithoutFullPlanRegenartion) { - RegenerateFullPlan(); - if (TINIT >= 1 && any_best_solution_updates) AdjustIPaths(); - num_adjust_ipaths_without_full_plan_regeneration = 0; - } - } - WriteMoves(testid); - if (TINIT == 0) total_time = 0.0; - total_time += GetTime() - TSTART; - DBG(0, "[GetMoves] testid=%s TINIT=%d/%d ttime=%.3lf nresc=%d nadjip=%d nadjipwofpr=%d nda=%d npl=%d sum=%d/%d(%.2lf)\n", testid, TINIT, TEST, total_time, num_reschedules, num_adjust_ipaths, num_adjust_ipaths_without_full_plan_regeneration, num_done_agents, num_planned, num_done_agents + num_planned, N, 100.0 * (num_done_agents + num_planned) / N); - - /*for (int aid = 0; aid < N; ++aid) { - if (aid == 27 || aid == 49 || aid == 56) { - const auto& ipath_aid = ipath[aid]; - for (int t = max(TINIT, 450); t <= 490 && t <= ipath_aid.tmax; ++t) { - const auto& elem = ipath_aid.p[t]; - DBG(0, "aid=%d t=%d node=%d npt=%d\n", aid, t, elem.node, elem.num_partial_turns); - } - } - }*/ -} - -} - -void GetMoves(const char* testid) { - SOLVE::GetMoves(testid, false); -} - -int main() { - SOLVE::GetMoves("1", true); - return 0; -} - diff --git a/r2sol-old2.cc b/r2sol-old2.cc deleted file mode 100644 index 1db4830929f3406a6658be76f4baa92372e631af..0000000000000000000000000000000000000000 --- a/r2sol-old2.cc +++ /dev/null @@ -1,2034 +0,0 @@ -#include "r2sol.h" -#undef NDEBUG -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <algorithm> -#include <memory> -#include <mutex> -#include <thread> - -#include <algorithm> -#include <vector> - -using namespace std; - -#define DEBUG_LEVEL 0//2 - -#define DBG(debug_level, ...) \ - { \ - if (debug_level <= DEBUG_LEVEL) { \ - fprintf(stderr, __VA_ARGS__); \ - fflush(stderr); \ - } \ - } - -#define HMAX 151 -#define NMAX 201 -#define MAXNODES 3000 -#define TMAX 2567 -#define MAX_NUM_THREADS 1//4 -#define MAX_CTURNS 5 -#define INF 1000000000 -#define ZERO 0.000001 -#define ONE 0.999999 -#define USE_SPACING_FOR_LONG_MOVES 1 -#define MIN_TINIT_FOR_SAVE_DATA_FOR_REPLAY 1000000 - -class Xor128 { - public: - void reset(unsigned int seed) { - xx = seed; - yy = 362436069; - zz = 521288629; - uu = 786232308; - } - - inline unsigned int rand() { - unsigned int t = (xx ^ (xx << 11)); - xx = yy; - yy = zz; - zz = uu; - return (uu = (uu ^ (uu >> 19)) ^ (t ^ (t >> 8))); - } - - private: - unsigned int xx, yy, zz, uu; -}; - -double GetTime() { - return 1.0 * clock() / CLOCKS_PER_SEC; -} - -const int DROW[4] = {-1, 0, +1, 0}; -const int DCOL[4] = {0, +1, 0, -1}; - -namespace SOLVE { - -FILE* fin; -char fname[128]; -int H, W, T, N, TINIT; -double TSTART; - -struct Node { - int row, col; -} node[MAXNODES]; - -int cell_to_node[HMAX][HMAX], nnodes; -int next[MAXNODES][4][4]; -int revnext[MAXNODES][4][4]; - -int target_node_agents[MAXNODES][NMAX], num_target_node_agents[MAXNODES]; - -void ReadTransitionsMap() { - int has_transition_map; - fscanf(fin, "%d", &has_transition_map); - if (!has_transition_map) return; - fscanf(fin, "%d %d", &H, &W); - DBG(2, "[ReadTransitionsMap] has_transition_map=%d H=%d W=%d\n", has_transition_map, H, W); - assert(1 <= H && H < HMAX && 1 <= W && W < HMAX); - for (int i = 0; i < H; ++i) { - for (int j = 0; j < W; ++j) { - cell_to_node[i][j] = -2; - } - } - nnodes = 0; - T = 8 * (H + W + 20); - int row, col, o1, o2, num_transitions = 0; - while (fscanf(fin, "%d %d %d %d", &row, &col, &o1, &o2) == 4) { - if (row < 0 || col < 0 || o1 < 0 || o2 < 0) break; - DBG(4, "row=%d/%d col=%d/%d o1=%d o2=%d nnodes=%d\n", row, H, col, W, o1, o2, nnodes); - assert(0 <= row && row < H); - assert(0 <= col && col < W); - assert(0 <= o1 && o1 < 4); - assert(0 <= o2 && o2 < 4); - if (cell_to_node[row][col] < 0) { - assert(nnodes < MAXNODES); - auto& new_node = node[nnodes]; - new_node.row = row; - new_node.col = col; - auto& next_nnodes = next[nnodes]; - auto& revnext_nnodes = revnext[nnodes]; - for (int tmpo1 = 0; tmpo1 <= 3; ++tmpo1) { - auto& next_nnodes_tmpo1 = next_nnodes[tmpo1]; - auto& revnext_nnodes_tmpo1 = revnext_nnodes[tmpo1]; - for (int tmpo2 = 0; tmpo2 <= 3; ++tmpo2) { - next_nnodes_tmpo1[tmpo2] = revnext_nnodes_tmpo1[tmpo2] = -1; - } - } - num_target_node_agents[nnodes] = 0; - cell_to_node[row][col] = nnodes++; - } - const auto& v1 = cell_to_node[row][col]; - const int rnext = row + DROW[o2], cnext = col + DCOL[o2]; - assert(0 <= rnext && rnext < H); - assert(0 <= cnext && cnext < W); - if (cell_to_node[rnext][cnext] < 0) { - assert(nnodes < MAXNODES); - auto& new_node = node[nnodes]; - new_node.row = rnext; - new_node.col = cnext; - auto& next_nnodes = next[nnodes]; - auto& revnext_nnodes = revnext[nnodes]; - for (int tmpo1 = 0; tmpo1 <= 3; ++tmpo1) { - auto& next_nnodes_tmpo1 = next_nnodes[tmpo1]; - auto& revnext_nnodes_tmpo1 = revnext_nnodes[tmpo1]; - for (int tmpo2 = 0; tmpo2 <= 3; ++tmpo2) { - next_nnodes_tmpo1[tmpo2] = revnext_nnodes_tmpo1[tmpo2] = -1; - } - } - num_target_node_agents[nnodes] = 0; - cell_to_node[rnext][cnext] = nnodes++; - } - const auto& v2 = cell_to_node[rnext][cnext]; - next[v1][o1][o2] = v2; - revnext[v2][o2][o1] = v1; - ++num_transitions; - } - DBG(0, "[ReadTransitionsMap] num_transitions=%d nnodes=%d/%d\n", num_transitions, nnodes, H * W); -} - -enum HowIGotHere { - INVALID = -1, - OUTSIDE_SRC = 0, - ENTERED_SRC = 1, - STARTED_MOVING = 2, - CONTINUED_MOVING = 3, - WAITED = 4, - MALFUNCTIONED = 5, -}; - -enum RailAgentStatus { - READY_TO_DEPART = 0, - ACTIVE = 1, - DONE = 2, - DONE_REMOVED = 3, -}; - -enum RailEnvActions { - DO_NOTHING = 0, - MOVE_LEFT = 1, - MOVE_FORWARD = 2, - MOVE_RIGHT = 3, - STOP_MOVING = 4, -}; - -struct PathElem { - int node, o, moving_to_node, moving_to_o, num_partial_turns; - HowIGotHere how_i_got_here; - - void PrintDebug(int t = -1) { - DBG(0, "t=%d poz=(%d %d) moving_to=(%d %d) npturns=%d how=%d\n", t, node, o, moving_to_node, moving_to_o, num_partial_turns, how_i_got_here); - } -}; - -struct Path { - struct PathElem p[TMAX]; - int tmax; -}; - -void CopyPath(const Path& src, Path* dst) { - dst->tmax = src.tmax; - if (src.tmax >= TINIT) memcpy(&dst->p[TINIT], &src.p[TINIT], (src.tmax - TINIT + 1) * sizeof(PathElem)); -} - -struct Agent { - int aid, poz_row, poz_col, poz_o, poz_node, target_row, target_col, target_node, malfunc, nr_malfunc, cturns; - double speed, poz_frac; - int inside_poz, fresh_malfunc; - RailAgentStatus status; -} agent[NMAX], tmp_agent; - -int cturns_agents[MAX_CTURNS][NMAX], num_cturns_agents[MAX_CTURNS]; - -int MAX_DONE_AGENTS; -double MIN_COST; -struct Path path[NMAX], ipath[NMAX]; - -int checkpoints[NMAX][TMAX], checkpoints_o[NMAX][TMAX], checkpoints_t[NMAX][TMAX], checkpoints_cnt[NMAX][TMAX], num_checkpoints[NMAX], tcheckpoints[NMAX][TMAX], next_checkpoint[NMAX]; - -vector<pair<int, int>> ipath_visiting_order[MAXNODES]; - -void RepopulateVisitingOrders() { - for (int node = 0; node < nnodes; ++node) ipath_visiting_order[node].clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_t_aid = checkpoints_t[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - for (int idx = next_checkpoint[aid]; idx < num_checkpoints_aid; ++idx) - ipath_visiting_order[checkpoints_aid[idx]].push_back({checkpoints_t_aid[idx], aid}); - } - for (int node = 0; node < nnodes; ++node) { - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - sort(ipath_visiting_order_node.begin(), ipath_visiting_order_node.end()); - } -} - -int covered_by[MAX_NUM_THREADS][TMAX][MAXNODES], is_covered[MAX_NUM_THREADS][TMAX][MAXNODES], is_covered_idx[MAX_NUM_THREADS], can_reach_idx[MAX_NUM_THREADS], can_reach[MAX_NUM_THREADS][TMAX][MAXNODES][4], can_reach_with_t1[MAX_NUM_THREADS][TMAX][MAXNODES][4]; - -void CheckAgent(int aid) { - //DBG(0, "[CheckAgent] aid=%d\n", aid); - - const auto& agent_aid = agent[aid]; - const auto& path = ipath[aid]; - if (path.tmax < TINIT) { - assert(agent_aid.status == DONE_REMOVED); - return; - } - - const auto& path_elem = path.p[TINIT]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) { - assert(!agent_aid.inside_poz); - assert(agent_aid.status == READY_TO_DEPART); - return; - } - - //DBG(0, " >>> nextcp=%d/%d\n", next_checkpoint[aid], num_checkpoints[aid]); - - if (agent_aid.inside_poz) { - auto& next_checkpoint_aid = next_checkpoint[aid]; - assert(next_checkpoint_aid < num_checkpoints[aid]); - if (checkpoints[aid][next_checkpoint_aid] == agent_aid.poz_node) { - assert(checkpoints_o[aid][next_checkpoint_aid] == agent_aid.poz_o); - ++next_checkpoint_aid; - } - } - - const auto& is_covered_idx_0 = is_covered_idx[0]; - auto& is_covered_0 = is_covered[0]; - - //DBG(0, ">>> aid=%d: poz=%d pelem=%d\n", aid, agent_aid.poz_node, path_elem.node); - - if (agent_aid.fresh_malfunc) { - if (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING) { - if (path_elem.num_partial_turns >= 1) { - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - (path_elem.num_partial_turns - 1) * agent_aid.speed) < ZERO); - } else { - assert(next[agent_aid.poz_node][agent_aid.poz_o][path_elem.o] == path_elem.node); - assert(agent_aid.poz_frac >= (agent_aid.cturns - 1) * agent_aid.speed - ZERO); - } - } else { - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - path_elem.num_partial_turns * agent_aid.speed) < ZERO); - } - } else if (is_covered_0[TINIT][path_elem.node] == is_covered_idx_0) { - assert((path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING || path_elem.how_i_got_here == ENTERED_SRC) && path_elem.num_partial_turns == 0); - if (path_elem.how_i_got_here == ENTERED_SRC) assert(!agent_aid.inside_poz); - else { - assert(agent_aid.inside_poz); - assert(agent_aid.poz_frac >= ONE); - } - } else if (path.tmax == TINIT) { - assert(!agent_aid.inside_poz); - assert(agent_aid.status == DONE_REMOVED); - } else { - assert(agent_aid.inside_poz); - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - //for (int t = TINIT; t <= TINIT + 2 && t <= path.tmax; ++t) DBG(0, " %d %d %d\n", path.p[t].node, path.p[t].num_partial_turns, path.p[t].how_i_got_here); - assert(fabs(agent_aid.poz_frac - path_elem.num_partial_turns * agent_aid.speed) < ZERO); - } - - if (agent_aid.inside_poz) is_covered_0[TINIT][agent_aid.poz_node] = is_covered_idx_0; -} - -bool reschedule; -int num_done_agents, num_planned, num_reschedules, num_adjust_ipaths; -int num_adjust_ipaths_without_full_plan_regeneration; - -void ReadAgentsData(bool replay_mode = false) { - fscanf(fin, "%d %d", &N, &TINIT); - DBG(2, "[ReadAgentsData] N=%d TINIT=%d/%d\n", N, TINIT, T); - assert(1 <= N && N < NMAX); - assert(TINIT < T); - if (replay_mode) { - fscanf(fin, "%d %d %d", &num_reschedules, &num_planned, &num_adjust_ipaths_without_full_plan_regeneration); - reschedule = TINIT == 0; - } else if (TINIT == 0) { - reschedule = true; - num_reschedules = 0; - num_adjust_ipaths = 0; - num_adjust_ipaths_without_full_plan_regeneration = 0; - num_planned = N; - } else reschedule = false; - if (num_planned == 0) return; - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) num_cturns_agents[cturns] = 0; - num_done_agents = 0; - num_planned = TINIT == 0 ? N : 0; - ++is_covered_idx[0]; - for (int aid = 0; aid < N; ++aid) { - int has_path_data = 0, status = -1; - fscanf(fin, "%d %d %d %d %d %d %lf %lf %d %d %d %d %d", &tmp_agent.aid, &tmp_agent.poz_row, &tmp_agent.poz_col, &tmp_agent.poz_o, &tmp_agent.target_row, &tmp_agent.target_col, &tmp_agent.speed, &tmp_agent.poz_frac, &tmp_agent.malfunc, &tmp_agent.nr_malfunc, &status, &tmp_agent.fresh_malfunc, &has_path_data); - assert(aid == tmp_agent.aid); - assert(status == READY_TO_DEPART || status == ACTIVE || status == DONE || status == DONE_REMOVED); - tmp_agent.status = (RailAgentStatus) status; - tmp_agent.poz_node = cell_to_node[tmp_agent.poz_row][tmp_agent.poz_col]; - tmp_agent.target_node = cell_to_node[tmp_agent.target_row][tmp_agent.target_col]; - tmp_agent.cturns = 0; - while (tmp_agent.cturns * tmp_agent.speed < ONE) ++tmp_agent.cturns; - tmp_agent.inside_poz = tmp_agent.status != READY_TO_DEPART && tmp_agent.status != DONE_REMOVED; - - auto& agent_aid = agent[aid]; - if (TINIT >= 1) { - if (!replay_mode) tmp_agent.fresh_malfunc |= (tmp_agent.nr_malfunc > agent_aid.nr_malfunc); - reschedule |= tmp_agent.fresh_malfunc; - if (tmp_agent.status == DONE_REMOVED) ++num_done_agents; - } - memcpy(&agent_aid, &tmp_agent, sizeof(Agent)); - - if (replay_mode || TINIT == 0) target_node_agents[agent_aid.target_node][num_target_node_agents[agent_aid.target_node]++] = aid; - - auto& ipath_aid = ipath[aid]; - if (has_path_data) { - fscanf(fin, "%d", &ipath_aid.tmax); - for (int t = TINIT; t <= ipath_aid.tmax; ++t) { - auto& new_path_elem = ipath_aid.p[t]; - int poz_row, poz_col, moving_to_row, moving_to_col, how_i_got_here = -1; - fscanf(fin, "%d %d %d %d %d %d %d %d", &poz_row, &poz_col, &new_path_elem.o, &moving_to_row, &moving_to_col, &new_path_elem.moving_to_o, &new_path_elem.num_partial_turns, &how_i_got_here); - assert(0 <= poz_row && poz_row < H && 0 <= poz_col && poz_col < W); - new_path_elem.node = cell_to_node[poz_row][poz_col]; - assert(0 <= new_path_elem.node && new_path_elem.node < nnodes); - if (moving_to_row >= 0 && moving_to_col >= 0) - new_path_elem.moving_to_node = cell_to_node[moving_to_row][moving_to_col]; - else new_path_elem.moving_to_node = -1; - assert(how_i_got_here == OUTSIDE_SRC || how_i_got_here == ENTERED_SRC || how_i_got_here == STARTED_MOVING || how_i_got_here == CONTINUED_MOVING || how_i_got_here == WAITED || how_i_got_here == MALFUNCTIONED); - new_path_elem.how_i_got_here = (HowIGotHere) how_i_got_here; - } - auto& num_checkpoints_aid = num_checkpoints[aid]; - fscanf(fin, "%d", &num_checkpoints_aid); - ++num_checkpoints_aid; - auto& checkpoints_aid = checkpoints[aid]; - auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_t_aid = checkpoints_t[aid]; - next_checkpoint[aid] = 1; - for (int cid = 1; cid < num_checkpoints_aid; ++cid) { - int row, col; - fscanf(fin, "%d %d %d %d", &row, &col, &checkpoints_o_aid[cid], &checkpoints_t_aid[cid]); - checkpoints_aid[cid] = cell_to_node[row][col]; - assert(0 <= checkpoints_aid[cid] && checkpoints_aid[cid] < nnodes); - } - if (agent_aid.inside_poz) { - checkpoints_aid[0] = agent_aid.poz_node; - checkpoints_o_aid[0] = agent_aid.poz_o; - } else { - checkpoints_aid[0] = checkpoints_o_aid[0] = -1; - } - checkpoints_t_aid[0] = TINIT; - } else if (TINIT == 0) { - // Initialize the path with fully waiting outside. - ipath_aid.tmax = T; - for (int t = 0; t <= T; ++t) { - auto& new_path_elem = ipath_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - num_checkpoints[aid] = next_checkpoint[aid] = 1; - checkpoints[aid][0] = checkpoints_o[aid][0] = -1; - } - - if (ipath_aid.tmax >= TINIT && ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node && agent_aid.status != DONE_REMOVED) - ++num_planned; - - DBG(2, "\nTINIT=%d aid=%d: poz=(%d %d %d):%d inside_poz=%d target=(%d %d):%d cturns=%d speed=%.6lf poz_frac=%.6lf malf=%d nr_malf=%d status=%d fresh_malf=%d\n", TINIT, agent_aid.aid, agent_aid.poz_row, agent_aid.poz_col, agent_aid.poz_o, agent_aid.poz_node, agent_aid.inside_poz, agent_aid.target_row, agent_aid.target_col, agent_aid.target_node, agent_aid.cturns, agent_aid.speed, agent_aid.poz_frac, agent_aid.malfunc, agent_aid.nr_malfunc, agent_aid.status, agent_aid.fresh_malfunc); - - assert(0 <= agent_aid.poz_row && agent_aid.poz_row < H); - assert(0 <= agent_aid.poz_col && agent_aid.poz_col < W); - assert(0 <= agent_aid.poz_node && agent_aid.poz_node < nnodes); - assert(0 <= agent_aid.poz_o && agent_aid.poz_o <= 3); - assert(0 <= agent_aid.target_row && agent_aid.target_row < H); - assert(0 <= agent_aid.target_col && agent_aid.target_col < W); - assert(0 <= agent_aid.target_node && agent_aid.target_node < nnodes); - assert(agent_aid.cturns < MAX_CTURNS); - cturns_agents[agent_aid.cturns][num_cturns_agents[agent_aid.cturns]++] = aid; - - if (TINIT >= 1) CheckAgent(aid); - } - - //exit(1); -} - -struct ShortestPathQueueElement { - int node, o; -} qshpath[MAXNODES * 4]; - -int dmin[NMAX][MAXNODES][4], prev_node[NMAX][MAXNODES][4], prev_o[NMAX][MAXNODES][4]; - -void ComputeShortestPaths(int aid) { - auto& dmin_aid = dmin[aid]; - auto& prev_node_aid = prev_node[aid]; - auto& prev_o_aid = prev_o[aid]; - for (int node = 0; node < nnodes; ++node) { - auto& dmin_aid_node = dmin_aid[node]; - for (int o = 0; o <= 3; ++o) dmin_aid_node[o] = INF; - } - int qli = 0, qls = -1; - const auto& agent_aid = agent[aid]; - for (int o = 0; o <= 3; ++o) { - auto& new_queue_elem = qshpath[++qls]; - new_queue_elem.node = agent_aid.target_node; - new_queue_elem.o = o; - dmin_aid[agent_aid.target_node][o] = 0; - } - while (qli <= qls) { - const auto& qelem = qshpath[qli++]; - const auto& node1 = qelem.node; - const auto& o1 = qelem.o; - const int dnew = dmin_aid[node1][o1] + agent_aid.cturns; - const auto& revnext_node1_o1 = revnext[node1][o1]; - for (int o2 = 0; o2 <= 3; ++o2) { - const auto& node2 = revnext_node1_o1[o2]; - if (node2 < 0) continue; - if (dnew < dmin_aid[node2][o2]) { - dmin_aid[node2][o2] = dnew; - auto& new_queue_elem = qshpath[++qls]; - new_queue_elem.node = node2; - new_queue_elem.o = o2; - prev_node_aid[node2][o2] = node1; - prev_o_aid[node2][o2] = o1; - } - } - } -} - -void ComputeShortestPaths() { - for (int aid = 0; aid < N; ++aid) ComputeShortestPaths(aid); -} - -Xor128 xor128[MAX_NUM_THREADS]; -int perm[MAX_NUM_THREADS][NMAX]; -char pused[MAX_NUM_THREADS][NMAX]; - -struct HeapElement { - int t, node, t1, est_tmin; - char o; - - bool IsSmaller(const HeapElement& other) const { - return est_tmin < other.est_tmin || (est_tmin == other.est_tmin && t1 > other.t1); - } -} heap[MAX_NUM_THREADS][TMAX * MAXNODES * 4]; - -int heap_size[MAX_NUM_THREADS]; - -inline void Swap(HeapElement h[], int poza, int pozb) { - auto& a = h[poza]; - auto& b = h[pozb]; - const HeapElement tmp = a; - a = b; - b = tmp; -} - -inline void PushUp(HeapElement h[], int poz) { - while (poz > 1) { - const int parent = poz >> 1; - auto& h_poz = h[poz]; - auto& h_parent = h[parent]; - if (h_poz.IsSmaller(h_parent)) { - Swap(h, poz, parent); - poz = parent; - } else - break; - } -} - -inline void PushDown(HeapElement h[], int& hsize, int poz) { - while (1) { - const int lchild = poz << 1; - if (lchild > hsize) break; - auto& h_lchild = h[lchild]; - auto& h_poz = h[poz]; - const int rchild = lchild + 1; - if (rchild <= hsize) { - auto& h_rchild = h[rchild]; - if (h_lchild.IsSmaller(h_rchild)) { - if (h_lchild.IsSmaller(h_poz)) { - Swap(h, lchild, poz); - poz = lchild; - } else - break; - } else { - if (h_rchild.IsSmaller(h_poz)) { - Swap(h, rchild, poz); - poz = rchild; - } else - break; - } - } else { - if (h_lchild.IsSmaller(h_poz)) { - Swap(h, lchild, poz); - poz = lchild; - } else - break; - } - } -} - -inline void InsertIntoHeap(HeapElement h[], int& hsize, int t, int node, int o, int t1, int est_tmin) { - auto& new_element = h[++hsize]; - new_element.t = t; - new_element.node = node; - new_element.o = o; - new_element.t1 = t1; - new_element.est_tmin = est_tmin; - PushUp(h, hsize); -} - -inline void ExtractMinFromHeap(HeapElement h[], int& hsize, int& t, int& node, int& o, int& t1) { - assert(hsize >= 1); - auto& min_element = h[1]; - t = min_element.t; - node = min_element.node; - o = min_element.o; - t1 = min_element.t1; - min_element = h[--hsize]; - if (hsize >= 1) PushDown(h, hsize, 1); -} - -struct Path tmp_path[MAX_NUM_THREADS][NMAX], tmp_path2[MAX_NUM_THREADS][NMAX]; -mutex m; - -struct PrevState { - int node, t; - char o; - HowIGotHere type; -} prev[MAX_NUM_THREADS][TMAX][MAXNODES][4]; - - -void CopyTmpPathToPath(int tid) { - // The mutex must be held before calling this function. - const auto& tmp_path_tid = tmp_path[tid]; - for (int aid = 0; aid < N; ++aid) { - auto& path_aid = path[aid]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) { - path_aid.tmax = -1; - continue; - } - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CopyPath(tmp_path_tid_aid, &path_aid); - } -} - -void RecomputeCheckpoints() { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - auto& num_checkpoints_aid = num_checkpoints[aid]; - - if (agent_aid.status == DONE_REMOVED) { - num_checkpoints_aid = next_checkpoint[aid] = 0; - continue; - } - - const auto& ipath_aid = ipath[aid]; - assert(ipath_aid.tmax > TINIT); - if (ipath_aid.p[ipath_aid.tmax].node != agent_aid.target_node) { - // This path hasn't been updated. We should keep the previously computed checkpoints. - continue; - } - - num_checkpoints_aid = next_checkpoint[aid] = 1; - - auto& checkpoints_aid = checkpoints[aid]; - auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_t_aid = checkpoints_t[aid]; - - if (agent_aid.inside_poz) { - checkpoints_aid[0] = agent_aid.poz_node; - checkpoints_o_aid[0] = agent_aid.poz_o; - } else { - checkpoints_aid[0] = checkpoints_o_aid[0] = -1; - } - - for (int t = TINIT + 1; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - if (path_elem.how_i_got_here == ENTERED_SRC || path_elem.node != checkpoints_aid[num_checkpoints_aid - 1]) { - checkpoints_aid[num_checkpoints_aid] = path_elem.node; - checkpoints_o_aid[num_checkpoints_aid] = path_elem.o; - checkpoints_t_aid[num_checkpoints_aid] = t; - ++num_checkpoints_aid; - } - } - } -} - -bool CanEnterCell(int aid, int t, int from, int to, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - assert(t > TINIT); - assert(0 <= to && to < nnodes); - const auto& agent_aid = agent[aid]; - const auto& is_covered1 = is_covered[t][to]; - const auto& is_covered2 = is_covered[t - 1][to]; - const auto& aid1 = covered_by[t][to]; - const auto& aid2 = covered_by[t - 1][to]; - - if (agent_aid.target_node == to) { - if (is_covered1 == is_covered_idx && aid1 < aid) return false; - if (is_covered2 == is_covered_idx && aid2 > aid) return false; - //if (USE_SPACING_FOR_LONG_MOVES && is_covered1 == is_covered_idx && (agent_aid.cturns >= 2 || agent[aid2].cturns >= 2)) return false; - } else { - if (is_covered1 == is_covered_idx) return false; - if (is_covered2 == is_covered_idx && aid2 > aid) return false; - if (from >= 0) { - const auto& is_covered3 = is_covered[t][from]; - const auto& aid3 = covered_by[t][from]; - if (is_covered2 == is_covered_idx && is_covered3 == is_covered_idx && aid2 == aid3) return false; - if (is_covered3 == is_covered_idx && aid3 < aid) return false; - } - if (t + 1 < T) { - const auto& is_covered4 = is_covered[t + 1][to]; - const auto& aid4 = covered_by[t + 1][to]; - if (is_covered4 == is_covered_idx && aid4 < aid) return false; - } - const auto& target_node_agents_to = target_node_agents[to]; - const auto& num_target_node_agents_to = num_target_node_agents[to]; - for (int idx = num_target_node_agents_to - 1; idx >= 0; --idx) { - const auto& aid5 = target_node_agents_to[idx]; - const auto& agent_aid5 = agent[aid5]; - if (agent_aid5.status == DONE_REMOVED) continue; - const auto& tmp_path_aid5 = tmp_path[aid5]; - assert(tmp_path_aid5.tmax > TINIT); - if (aid5 > aid && tmp_path_aid5.tmax == t && tmp_path_aid5.p[t].node == to) return false; - //if (USE_SPACING_FOR_LONG_MOVES && tmp_path_aid5.tmax == t && tmp_path_aid5.p[t].node == to && (agent_aid.cturns >= 2 || agent_aid5.cturns >= 2)) return false; - if (aid5 < aid && tmp_path_aid5.tmax == t + 1 && tmp_path_aid5.p[t + 1].node == to) return false; - } - } - - return true; -} - -inline bool IsFreeTimeWindow(int aid, int t1, int t2, int node, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - for (int t = t1; t <= t2; ++t) if (!CanEnterCell(aid, t, node, node, covered_by, is_covered, is_covered_idx, tmp_path)) return false; - return true; -} - -int tend_ongoing_move[NMAX]; - -bool OverlapsOngoingMove(int t1, int t2, int node, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - if (t1 < tend_ongoing_move[node]) return true; - for (int tend = t2 + 1; tend <= t2 + 3 && tend <= T; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid = covered_by[tend][node]; - const auto& agent_aid = agent[aid]; - if (tend - agent_aid.cturns < t2) return true; - } - } - for (int tend = t1 + 1; tend < t2; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - if (is_covered[tend - 1][node] != is_covered_idx) return false; - const auto& aid_tend = covered_by[tend][node]; - const auto& aid_tendm1 = covered_by[tend - 1][node]; - if (aid_tend != aid_tendm1) continue; - } - } - /*const auto& target_node_agents_node = target_node_agents[node]; - const auto& num_target_node_agents_node = num_target_node_agents[node]; - for (int idx = num_target_node_agents_node - 1; idx >= 0; --idx) { - const auto& aid5 = target_node_agents_node[idx]; - const auto& agent_aid5 = agent[aid5]; - if (agent_aid5.status == DONE_REMOVED) continue; - const auto& tmp_path_aid5 = tmp_path[aid5]; - assert(tmp_path_aid5.tmax > TINIT); - if (tmp_path_aid5.p[tmp_path_aid5.tmax].node == agent_aid5.target_node && t1 < tmp_path_aid5.tmax && tmp_path_aid5.tmax <= t2) { - return true; - } - }*/ - return false; -} - -bool FindBestPath(int aid, const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, int can_reach[][MAXNODES][4], int& can_reach_idx, int can_reach_with_t1[][MAXNODES][4], HeapElement h[], int& hsize, PrevState prev[][MAXNODES][4], Path tmp_path[], Path* tmp_path2) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - auto& tmp_path_aid = tmp_path[aid]; - CopyPath(ipath_aid, &tmp_path_aid); - - hsize = 0; - - ++can_reach_idx; - const auto& target_node = agent_aid.target_node; - const auto& cturns = agent_aid.cturns; - const auto& dmin_aid = dmin[aid]; - - int t1 = TINIT, t2 = TINIT, rnode = -1, ro = -1; - - if (!agent_aid.inside_poz) { - rnode = agent_aid.poz_node; - ro = agent_aid.poz_o; - t1 = TINIT + max(agent_aid.malfunc - 1/*2*/, 0); - for (int tstart = t1; tstart < T; ++tstart) { - if (!CanEnterCell(aid, tstart + 1, -1, rnode, covered_by, is_covered, is_covered_idx, tmp_path)) continue; - int t2 = tstart + 1; - const int est_tmin = t2 + dmin_aid[rnode][ro]; - if (est_tmin > T) break; - can_reach[t2][rnode][ro] = can_reach_idx; - can_reach_with_t1[t2][rnode][ro] = tstart + 1; - auto& new_prev = prev[t2][rnode][ro]; - new_prev.t = new_prev.node = new_prev.o = -1; - InsertIntoHeap(h, hsize, t2, rnode, ro, tstart + 1, est_tmin); - } - } else { - t1 = TINIT; - rnode = agent_aid.poz_node; - ro = agent_aid.poz_o; - int moving_to_node = ipath_aid.p[TINIT].moving_to_node, moving_to_o = ipath_aid.p[TINIT].moving_to_o; - while (t1 + 1 <= ipath_aid.tmax && ipath_aid.p[t1 + 1].how_i_got_here == MALFUNCTIONED) { - ++t1; - assert(ipath_aid.p[t1].moving_to_node == moving_to_node); - assert(ipath_aid.p[t1].moving_to_o == moving_to_o); - if (!CanEnterCell(aid, t1, rnode, rnode, covered_by, is_covered, is_covered_idx, tmp_path)) return false; - } - if (t1 >= T) return false; - if (t1 != TINIT + agent_aid.malfunc) { - DBG(0, "!!! [FindBestPath] aid=%d TINIT=%d malfunc=%d t1=%d/%d/%d\n", aid, TINIT, agent_aid.malfunc, t1, TINIT + agent_aid.malfunc, T); - exit(1); - } - memcpy(&tmp_path2->p[TINIT], &ipath_aid.p[TINIT], (t1 - TINIT + 1) * sizeof(PathElem)); - t2 = t1; - if (moving_to_node >= 0) { - bool finished_moving = false; - while (t2 < T && rnode == agent_aid.poz_node) { - const auto& prev_path_elem = tmp_path2->p[t2]; - auto& next_path_elem = tmp_path2->p[t2 + 1]; - if (prev_path_elem.num_partial_turns + 1 < agent_aid.cturns || !CanEnterCell(aid, t2 + 1, rnode, moving_to_node, covered_by, is_covered, is_covered_idx, tmp_path)) { - memcpy(&next_path_elem, &prev_path_elem, sizeof(PathElem)); - ++next_path_elem.num_partial_turns; - next_path_elem.how_i_got_here = CONTINUED_MOVING; - } else { - next_path_elem.node = moving_to_node; - next_path_elem.o = moving_to_o; - next_path_elem.moving_to_node = next_path_elem.moving_to_o = -1; - next_path_elem.num_partial_turns = 0; - next_path_elem.how_i_got_here = CONTINUED_MOVING; - finished_moving = true; - } - ++t2; - } - if (finished_moving) { - rnode = moving_to_node; - ro = moving_to_o; - } - if (USE_SPACING_FOR_LONG_MOVES && OverlapsOngoingMove(TINIT, t2, moving_to_node, covered_by, is_covered, is_covered_idx, tmp_path)) - return false; - } - const int est_tmin = t2 + dmin_aid[rnode][ro]; - if (est_tmin <= T) { - can_reach[t2][rnode][ro] = can_reach_idx; - can_reach_with_t1[t2][rnode][ro] = t1; - auto& new_prev = prev[t2][rnode][ro]; - new_prev.t = new_prev.node = new_prev.o = -1; - InsertIntoHeap(h, hsize, t2, rnode, ro, t1, est_tmin); - } - } - - int TMIN = T + 1, best_o = -1; - - if (tmp_path_aid.tmax < TINIT || tmp_path_aid.p[tmp_path_aid.tmax].node == agent_aid.target_node) TMIN = tmp_path_aid.tmax; - - while (hsize >= 1 /*&& TMIN > T*/) { - int t, node, o, ct1; - ExtractMinFromHeap(h, hsize, t, node, o, ct1); - //DBG(0, "aid=%d hsize=%d t=%d node=%d o=%d ct1=%d can_reach=%d/%d\n", aid, hsize, t, node, o, ct1, can_reach[t][node][o], can_reach_idx); - assert(can_reach[t][node][o] == can_reach_idx); - if (ct1 != can_reach_with_t1[t][node][o]) continue; - if (t + dmin_aid[node][o] >= TMIN) break; - - // Case 1: Wait. - if (t + 1 < TMIN && CanEnterCell(aid, t + 1, node, node, covered_by, is_covered, is_covered_idx, tmp_path) && - (can_reach[t + 1][node][o] != can_reach_idx || can_reach_with_t1[t + 1][node][o] < ct1) && - (agent_aid.inside_poz || t > ct1)) { - can_reach[t + 1][node][o] = can_reach_idx; - can_reach_with_t1[t + 1][node][o] = ct1; - auto& new_prev = prev[t + 1][node][o]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = WAITED; - const int est_tmin = t + 1 + dmin_aid[node][o]; - if (est_tmin < TMIN) InsertIntoHeap(h, hsize, t + 1, node, o, ct1, est_tmin); - } - - if (t + cturns >= TMIN) continue; - - const int tarrive_node2 = t + cturns; - if (!IsFreeTimeWindow(aid, t + 1, tarrive_node2 - 1, node, covered_by, is_covered, is_covered_idx, tmp_path)) continue; - - // Case 2: Move. - const auto& next_node_o = next[node][o]; - for (int onext = 0; onext <= 3; ++onext) { - const auto& node2 = next_node_o[onext]; - if (node2 >= 0 && node2 < nnodes && CanEnterCell(aid, tarrive_node2, node, node2, covered_by, is_covered, is_covered_idx, tmp_path) && - (can_reach[tarrive_node2][node2][onext] != can_reach_idx || can_reach_with_t1[tarrive_node2][node2][onext] < ct1)) { - if (USE_SPACING_FOR_LONG_MOVES && OverlapsOngoingMove(t, tarrive_node2, node2, covered_by, is_covered, is_covered_idx, tmp_path)) - continue; - if (node2 != target_node) { - can_reach[tarrive_node2][node2][onext] = can_reach_idx; - can_reach_with_t1[tarrive_node2][node2][onext] = ct1; - auto& new_prev = prev[tarrive_node2][node2][onext]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = STARTED_MOVING; - const int est_tmin = tarrive_node2 + dmin_aid[node2][onext]; - if (est_tmin < TMIN) InsertIntoHeap(h, hsize, tarrive_node2, node2, onext, ct1, est_tmin); - } else { - can_reach[tarrive_node2][node2][onext] = can_reach_idx; - can_reach_with_t1[tarrive_node2][node2][onext] = ct1; - auto& new_prev = prev[tarrive_node2][node2][onext]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = STARTED_MOVING; - if (tarrive_node2 < TMIN) { - TMIN = tarrive_node2; - best_o = onext; - } - } - } - } - } - - if (best_o < 0) return false; - - tmp_path_aid.tmax = TMIN; - int ct = TMIN, cnode = target_node, co = best_o; - while (1) { - assert(can_reach[ct][cnode][co] == can_reach_idx); - assert(ct >= can_reach_with_t1[ct][cnode][co]); - const auto& cprev = prev[ct][cnode][co]; - //DBG(0, "ct=%d cnode=%d co=%d cprev.t=%d cprev.type=%d\n", ct, cnode, co, cprev.t, cprev.type); - if (cprev.t < 0) break; - if (cprev.type == WAITED || cprev.type == MALFUNCTIONED) { - // Wait 1 unit. - auto& new_path_elem = tmp_path_aid.p[ct]; - new_path_elem.node = cnode; - new_path_elem.o = co; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = cprev.type; - } else { - assert(cprev.type == STARTED_MOVING); - // Move cturns units. - int num_partial_turns = 0; - - for (int tmove = cprev.t; tmove < ct; ++tmove) { - //DBG(0, " tmove=%d npt=%d\n", tmove, num_partial_turns); - auto& new_path_elem = tmp_path_aid.p[tmove + 1]; - ++num_partial_turns; - if (num_partial_turns < agent_aid.cturns) { - new_path_elem.node = cprev.node; - new_path_elem.o = cprev.o; - new_path_elem.moving_to_node = cnode; - new_path_elem.moving_to_o = co; - new_path_elem.num_partial_turns = num_partial_turns; - new_path_elem.how_i_got_here = num_partial_turns == 1 ? STARTED_MOVING : CONTINUED_MOVING; - } else { - new_path_elem.node = cnode; - new_path_elem.o = co; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = num_partial_turns == 1 ? STARTED_MOVING : CONTINUED_MOVING; - } - } - } - ct = cprev.t; - cnode = cprev.node; - co = cprev.o; - } - - if (!agent_aid.inside_poz) { - for (int t = TINIT + 1; t < ct; ++t) { - auto& new_path_elem = tmp_path_aid.p[t]; - new_path_elem.node = rnode; - new_path_elem.o = ro; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - auto& new_path_elem = tmp_path_aid.p[ct]; - new_path_elem.node = rnode; - new_path_elem.o = ro; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = ENTERED_SRC; - } else { - memcpy(&tmp_path_aid.p[TINIT], &tmp_path2->p[TINIT], (t2 - TINIT + 1) * sizeof(PathElem)); - } - - return true; -} - -bool updated_best_solution; -int rerun; - -vector<pair<int, int>> shpaths_sorted; - -void CoverPath(int aid, const Path& path, int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - for (int t = TINIT; t <= path.tmax; ++t) { - const auto& path_elem = path.p[t]; - if (path_elem.how_i_got_here != OUTSIDE_SRC && path_elem.node != agent_aid.target_node) { - assert(is_covered[t][path_elem.node] != is_covered_idx); - is_covered[t][path_elem.node] = is_covered_idx; - covered_by[t][path_elem.node] = aid; - } - } -} - -void UncoverPath(int aid, const Path& path, int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - for (int t = TINIT; t <= path.tmax; ++t) { - const auto& path_elem = path.p[t]; - if (path_elem.how_i_got_here != OUTSIDE_SRC && path_elem.node != agent_aid.target_node) { - assert(is_covered[t][path_elem.node] == is_covered_idx && covered_by[t][path_elem.node] == aid); - is_covered[t][path_elem.node] = 0; - } - } -} - -bool RunConsistencyChecks(Path path[], const int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, bool crash_on_error = true) { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& path_aid = path[aid]; - for (int t = TINIT + 1; t <= path_aid.tmax; ++t) { - const auto& path_elem = path_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - const auto& is_covered1 = is_covered[t][path_elem.node]; - const auto& is_covered2 = is_covered[t - 1][path_elem.node]; - const auto& aid1 = covered_by[t][path_elem.node]; - const auto& aid2 = covered_by[t - 1][path_elem.node]; - if (path_elem.node == agent_aid.target_node) { - if (is_covered1 == is_covered_idx) { - const bool ok = aid1 > aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - if (is_covered2 == is_covered_idx) { - const bool ok = aid2 < aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - } else { - Agent* agent_aid1 = is_covered1 != is_covered_idx ? nullptr : &agent[aid1]; - if (is_covered1 == is_covered_idx && aid1 != aid && agent_aid1->target_node != path_elem.node) { - DBG(0, "!!! [RunConsistencyChecks] aid=%d t=%d node=%d cov=%d how=%d\n", aid, t, path_elem.node, covered_by[t][path_elem.node], path_elem.how_i_got_here); - if (crash_on_error) exit(1); - return false; - } - - const auto& target_node_agents_node = target_node_agents[path_elem.node]; - const auto& num_target_node_agents_node = num_target_node_agents[path_elem.node]; - for (int idx = num_target_node_agents_node - 1; idx >= 0; --idx) { - const auto& aid3 = target_node_agents_node[idx]; - const auto& agent_aid3 = agent[aid3]; - if (agent_aid3.status == DONE_REMOVED) continue; - const auto& path_aid3 = path[aid3]; - bool ok = path_aid3.tmax > TINIT; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - if (path_aid3.tmax == t && path_aid3.p[t].node == path_elem.node) { - ok = aid3 < aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - if (path_aid3.tmax == t + 1 && path_aid3.p[t].node == path_elem.node) { - ok = aid3 > aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - } - - Agent* agent_aid2 = is_covered2 != is_covered_idx ? nullptr : &agent[aid2]; - if (t > TINIT && is_covered2 == is_covered_idx && aid2 > aid && agent_aid2->target_node != path_elem.node) { - DBG(0, "!!! [RunConsistencyChecks] aid=%d t=%d node=%d cov_t-1=%d(target=%d)\n", aid, t, path_elem.node, aid2, agent_aid2->target_node); - if (crash_on_error) exit(1); - return false; - } - } - - if (path_elem.num_partial_turns >= agent_aid.cturns && (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) { - bool ok = path_elem.moving_to_node >= 0; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - if ((is_covered[t][path_elem.moving_to_node] != is_covered_idx && - (is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx || - covered_by[t - 1][path_elem.moving_to_node] <= aid)) || - (is_covered[t][path_elem.moving_to_node] == is_covered_idx && - covered_by[t][path_elem.moving_to_node] >= aid && - (is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx || - covered_by[t - 1][path_elem.moving_to_node] != covered_by[t][path_elem.moving_to_node]))) { - DBG(0, "!!! [RunConsistencyChecks] Agent in motion can enter next cell, but doesn't: aid=%d t=%d node=%d->%d npt=%d/%d cov_t=%d cov_t-1=%d\n", aid, t, path_elem.node, path_elem.moving_to_node, path_elem.num_partial_turns, agent_aid.cturns, is_covered[t][path_elem.moving_to_node] != is_covered_idx ? -1 : covered_by[t][path_elem.moving_to_node], is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx ? -1 : covered_by[t - 1][path_elem.moving_to_node]); - if (crash_on_error) exit(1); - return false; - } - } - } - } - return true; -} - -void RandomPermutations(int tid, int ntries) { - auto& pused_tid = pused[tid]; - auto& perm_tid = perm[tid]; - auto& xor128_tid = xor128[tid]; - auto& covered_by_tid = covered_by[tid]; - auto& is_covered_tid = is_covered[tid]; - auto& is_covered_idx_tid = is_covered_idx[tid]; - auto& can_reach_tid = can_reach[tid]; - auto& can_reach_idx_tid = can_reach_idx[tid]; - auto& can_reach_with_t1_tid = can_reach_with_t1[tid]; - auto& heap_tid = heap[tid]; - auto& heap_size_tid = heap_size[tid]; - auto& prev_tid = prev[tid]; - auto& tmp_path_tid = tmp_path[tid]; - auto& tmp_path2_tid = tmp_path2[tid]; - - if (tid == 0) { - shpaths_sorted.resize(N); - for (int aid = 0; aid < N; ++aid) { - shpaths_sorted[aid].second = aid; - const auto& agent_aid = agent[aid]; - shpaths_sorted[aid].first = agent_aid.malfunc + dmin[aid][agent_aid.poz_node][agent_aid.poz_o]; - } - sort(shpaths_sorted.begin(), shpaths_sorted.end()); - } - - for (int trial = 1; trial <= ntries; ++trial) { - if (tid == 0 && trial <= 1) { - for (int i = 0; i < N; ++i) perm_tid[i] = shpaths_sorted[i].second; - reverse(shpaths_sorted.begin(), shpaths_sorted.end()); - } else { - for (int i = 0; i < N; ++i) pused_tid[i] = 0; - int idx = 0; - /*for (int i = 0; i < N; ++i) { - do { - perm_tid[idx] = xor128_tid.rand() % N; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - }*/ - if (0&&(trial & 1) == 1) { - for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } else { - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } - /*for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - }*/ - } - ++is_covered_idx_tid; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - CoverPath(aid, ipath_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - CopyPath(ipath_aid, &tmp_path_tid[aid]); - } - for (int idx = 0; idx < N; ++idx) { - const auto& aid = perm_tid[idx]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - UncoverPath(aid, ipath_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - DBG(3, "TINIT=%d tid=%d trial=%d/%d idx=%d: aid=%d start state=%d\n", TINIT, tid, trial, ntries, idx, aid, ipath_aid.p[TINIT].how_i_got_here); - FindBestPath(aid, covered_by_tid, is_covered_tid, is_covered_idx_tid, can_reach_tid, can_reach_idx_tid, can_reach_with_t1_tid, heap_tid, heap_size_tid, prev_tid, tmp_path_tid, &tmp_path2_tid[aid]); - DBG(3, "TINIT=%d tid=%d trial=%d/%d idx=%d: aid=%d done tmax=%d/%d reaches_target=%d(%d:%d) (%.3lf)\n", TINIT, tid, trial, ntries, idx, aid, tmp_path_tid_aid.tmax, T, tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node == agent_aid.target_node, tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node, agent_aid.target_node, GetTime() - TSTART); - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - } - - if (RunConsistencyChecks(tmp_path_tid, covered_by_tid, is_covered_tid, is_covered_idx_tid, false)) { - int num_done_agents = 0; - double cost = 0.0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - assert(tmp_path_tid_aid.tmax > TINIT); - if (tmp_path_tid_aid.tmax > TINIT && tmp_path_tid_aid.tmax <= T && tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node == agent_aid.target_node) { - ++num_done_agents; - //cost += agent_aid.speed * (tmp_path_tid_aid.tmax - TINIT); - cost += tmp_path_tid_aid.tmax * tmp_path_tid_aid.tmax; - } else { - //cost += agent_aid.speed * (T - TINIT); - } - } - { - lock_guard<mutex> guard(m); - DBG(3, "[RandomPermutations] rerun=%d tid=%d trial=%d/%d nda=%d/%d cost=%.6lf: maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, trial, ntries, num_done_agents, N, cost, MAX_DONE_AGENTS, N, MIN_COST, GetTime() - TSTART); - if (num_done_agents > MAX_DONE_AGENTS || (num_done_agents == MAX_DONE_AGENTS && cost < MIN_COST - 1e-6)) { - MAX_DONE_AGENTS = num_done_agents; - MIN_COST = cost; - updated_best_solution = true; - CopyTmpPathToPath(tid); - DBG(0, "[RandomPermutations] rerun=%d tid=%d trial=%d/%d maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, trial, ntries, MAX_DONE_AGENTS, N, MIN_COST, GetTime() - TSTART); - } - } - } - } -} - -bool any_best_solution_updates; - -void RegenerateFullPlan() { - any_best_solution_updates = false; - updated_best_solution = true; - rerun = 0; - - const int kMaxReruns = 2;//3; - - while (updated_best_solution && rerun < kMaxReruns) { - updated_best_solution = false; - ++num_reschedules; - ++rerun; - - for (int node = 0; node < nnodes; ++node) tend_ongoing_move[node] = TINIT; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz || agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - const auto& first_path_elem = ipath_aid.p[TINIT]; - assert(ipath_aid.tmax >= TINIT); - if (first_path_elem.num_partial_turns >= 1) { - assert(first_path_elem.moving_to_node >= 0); - tend_ongoing_move[first_path_elem.moving_to_node] = TINIT + agent_aid.malfunc + max(0, agent_aid.cturns - ipath_aid.p[TINIT].num_partial_turns); - } - } - - int max_threads = thread::hardware_concurrency(); - if (max_threads > MAX_NUM_THREADS) max_threads = MAX_NUM_THREADS; - DBG(2, "max_threads=%d\n", max_threads); - - if (N >= 2) { - thread** th = nullptr; - if (max_threads >= 2) th = new thread*[max_threads - 1]; - - // Random Permutations. - const int kNumRandomPermutations = TINIT == 0 ? 10 : 6/*4*/; - if (max_threads >= 2) { - for (int tid = 0; tid + 1 < max_threads; ++tid) th[tid] = new thread([tid, kNumRandomPermutations]{ - RandomPermutations(tid, kNumRandomPermutations); - }); - } - RandomPermutations(max_threads - 1, kNumRandomPermutations); - if (max_threads >= 2) { - for (int tid = 0; tid + 1 < max_threads; ++tid) { - auto& th_tid = th[tid]; - th_tid->join(); - delete th_tid; - } - delete th; - } - } else RandomPermutations(0, 1); - - if (updated_best_solution) { - for (int aid = 0; aid < N; ++aid) CopyPath(path[aid], &ipath[aid]); - any_best_solution_updates = true; - } - } - - if (any_best_solution_updates) RecomputeCheckpoints(); -} - -int nodecnt[MAXNODES], nodecnt_marked[MAXNODES], nodecnt_marked_idx; -char is_free[MAXNODES]; - -int next_aidx[NMAX], next_vidx[MAXNODES]; - -void SwapVisitingOrder(int aid1, int idx1, int aid2) { - const auto& checkpoints_aid1 = checkpoints[aid1]; - const auto& checkpoints_aid2 = checkpoints[aid2]; - const int node = checkpoints_aid1[idx1]; - int idx2 = next_aidx[aid2] - 1; - while (idx2 >= 0 && checkpoints_aid2[idx2] != node) --idx2; - assert(idx2 >= 0); - const auto& num_checkpoints_aid1 = num_checkpoints[aid1]; - const auto& num_checkpoints_aid2 = num_checkpoints[aid2]; - const auto& checkpoints_cnt_aid1 = checkpoints_cnt[aid1]; - const auto& checkpoints_cnt_aid2 = checkpoints_cnt[aid2]; - - int num_swaps = 0; - while (idx1 < num_checkpoints_aid1 && idx2 < num_checkpoints_aid2 && checkpoints_aid1[idx1] == checkpoints_aid2[idx2]) { - int vidx1 = -1, cnt1 = 0, vidx2 = -1, cnt2 = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[checkpoints_aid1[idx1]]; - for (int idx = 0; idx < ipath_visiting_order_node.size() && (vidx1 < 0 || vidx2 < 0); ++idx) { - const auto& elem_pair = ipath_visiting_order_node[idx]; - if (elem_pair.second == aid1) { - ++cnt1; - if (cnt1 == checkpoints_cnt_aid1[idx1]) vidx1 = idx; - } - if (elem_pair.second == aid2) { - ++cnt2; - if (cnt2 == checkpoints_cnt_aid2[idx2]) vidx2 = idx; - } - } - assert(vidx1 >= 0 && vidx2 >= 0); - assert(vidx1 > vidx2); - ipath_visiting_order_node[vidx1].second = aid2; - ipath_visiting_order_node[vidx2].second = aid1; - ++idx1; - ++idx2; - ++num_swaps; - } - - /*for (int node = 0; node < nnodes; ++node) { - int vidx1 = -1, cnt1 = 0, vidx2 = -1, cnt2 = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - for (int idx = 0; idx < ipath_visiting_order_node.size() && (vidx1 < 0 || vidx2 < 0); ++idx) { - const auto& elem_pair = ipath_visiting_order_node[idx]; - if (elem_pair.second == aid1) vidx1 = idx; - if (elem_pair.second == aid2) vidx2 = idx; - } - if (vidx1 >= 0 && vidx2 >= 0) { - ipath_visiting_order_node[vidx1].second = aid2; - ipath_visiting_order_node[vidx2].second = aid1; - ++num_swaps; - } - }*/ - - DBG(2, "[SwapVisitingOrder] aid1=%d aid2=%d idx1=%d num_swaps=%d\n", aid1, aid2, idx1, num_swaps); - - //exit(1); -} - -#define QMOD 255 -int qaid[QMOD + 1]; - -bool AdjustIPaths() { - /*for (int aid = 0; aid < N; ++aid) { - if (aid == 27 || aid == 49 || aid == 56) { - const auto& ipath_aid = ipath[aid]; - for (int t = max(TINIT, 450); t <= 490 && t <= ipath_aid.tmax; ++t) { - const auto& elem = ipath_aid.p[t]; - DBG(0, "aid=%d t=%d node=%d npt=%d\n", aid, t, elem.node, elem.num_partial_turns); - } - } - }*/ - - ++num_adjust_ipaths; - - nodecnt_marked_idx = 0; - for (int node = 0; node < nnodes; ++node) { - ipath_visiting_order[node].clear(); - nodecnt_marked[node] = 0; - } - - int max_tmax = 0; - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - auto& path_aid = path[aid]; - if (agent_aid.status == DONE_REMOVED) { - CopyPath(ipath_aid, &path_aid); - continue; - } - - if (ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node && ipath_aid.tmax > max_tmax) max_tmax = ipath_aid.tmax; - - auto& new_path_elem = path_aid.p[TINIT]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.num_partial_turns = 0; - while (fabs(agent_aid.poz_frac - new_path_elem.num_partial_turns * agent_aid.speed) >= ZERO) - ++new_path_elem.num_partial_turns; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - if (agent_aid.inside_poz) { - const auto& first_expected_step = ipath_aid.p[TINIT]; - if (new_path_elem.num_partial_turns >= 1) { - if (first_expected_step.num_partial_turns >= 1) { - if (agent_aid.fresh_malfunc) - assert(first_expected_step.num_partial_turns >= new_path_elem.num_partial_turns); - assert(first_expected_step.node == agent_aid.poz_node); - assert(first_expected_step.o == agent_aid.poz_o); - new_path_elem.moving_to_node = first_expected_step.moving_to_node; - new_path_elem.moving_to_o = first_expected_step.moving_to_o; - assert(0 <= new_path_elem.moving_to_node && new_path_elem.moving_to_node < nnodes); - assert(0 <= new_path_elem.moving_to_o && new_path_elem.moving_to_o < nnodes); - } else { - assert(new_path_elem.num_partial_turns >= agent_aid.cturns - 1); - assert(first_expected_step.node != agent_aid.poz_node || first_expected_step.o != agent_aid.poz_o); - assert(first_expected_step.moving_to_node < 0); - assert(first_expected_step.moving_to_o < 0); - new_path_elem.moving_to_node = first_expected_step.node; - new_path_elem.moving_to_o = first_expected_step.o; - } - } - if (agent_aid.fresh_malfunc) new_path_elem.how_i_got_here = MALFUNCTIONED; - else new_path_elem.how_i_got_here = first_expected_step.how_i_got_here; - } else new_path_elem.how_i_got_here = OUTSIDE_SRC; - - const int tmin = TINIT + max(0, agent_aid.malfunc - (agent_aid.inside_poz ? /*1*/ 0 : /*2*/1)); - for (int t = TINIT + 1; t <= tmin && t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = agent_aid.inside_poz ? MALFUNCTIONED : OUTSIDE_SRC; - } - - const auto& next_checkpoint_aid = next_checkpoint[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - - if (next_checkpoint_aid == num_checkpoints_aid) { - assert(!agent_aid.inside_poz); - continue; - } - - assert(1 <= next_checkpoint_aid && next_checkpoint_aid < num_checkpoints_aid); - - auto& tcheckpoints_aid = tcheckpoints[aid]; - tcheckpoints_aid[next_checkpoint_aid - 1] = path_aid.tmax = tmin; - - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_cnt_aid = checkpoints_cnt[aid]; - - ++nodecnt_marked_idx; - - if (agent_aid.inside_poz) { - nodecnt_marked[agent_aid.poz_node] = nodecnt_marked_idx; - nodecnt[agent_aid.poz_node] = checkpoints_cnt_aid[next_checkpoint_aid - 1] = 1; - assert(checkpoints_aid[next_checkpoint_aid - 1] == agent_aid.poz_node); - } - - for (int cid = next_checkpoint_aid; cid < num_checkpoints_aid; ++cid) { - const auto& node = checkpoints_aid[cid]; - if (nodecnt_marked[node] != nodecnt_marked_idx) { - nodecnt_marked[node] = nodecnt_marked_idx; - nodecnt[node] = 0; - } - checkpoints_cnt_aid[cid] = ++nodecnt[node]; - } - } - - RepopulateVisitingOrders(); - - auto& is_covered_0 = is_covered[0]; - auto& is_covered_idx_0 = is_covered_idx[0]; - auto& covered_by_0 = covered_by[0]; - - bool updated_visiting_order = true; - int nelems = 0; - - while (updated_visiting_order) { - updated_visiting_order = false; - ++is_covered_idx_0; - - for (int node = 0; node < nnodes; ++node) is_free[node] = 1; - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - next_aidx[aid] = next_checkpoint[aid]; - auto& path_aid = path[aid]; - const int tmin = TINIT + max(0, agent_aid.malfunc - (agent_aid.inside_poz ? /*1*/ 0 : /*2*/ 1)); - for (int t = TINIT + 1; t <= tmin && t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = agent_aid.inside_poz ? MALFUNCTIONED : OUTSIDE_SRC; - if (agent_aid.inside_poz) { - assert(is_covered_0[t][new_path_elem.node] != is_covered_idx_0); - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - } - } - - path_aid.tmax = tmin; - - if (agent_aid.inside_poz) { - is_free[agent_aid.poz_node] = 0; - is_covered_0[TINIT][agent_aid.poz_node] = is_covered_idx_0; - covered_by_0[TINIT][agent_aid.poz_node] = aid; - } - } - - int qli = 0, qls = 0; - - for (int node = 0; node < nnodes; ++node) { - next_vidx[node] = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - if (ipath_visiting_order_node.empty()) continue; - for (auto& elem_pair : ipath_visiting_order_node) elem_pair.first = TINIT; - const auto& aid_0 = ipath_visiting_order_node[0].second; - if (is_free[node] && checkpoints[aid_0][next_aidx[aid_0]] == node) { - qaid[qls] = aid_0; - qls = (qls + 1) & QMOD; - } - } - - nelems = 0; - - int tmin_incomplete = -1, aid_incomplete = -1; - - while (qli != qls) { - ++nelems; - - const auto& aid = qaid[qli]; - const auto& agent_aid = agent[aid]; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& tcheckpoints_aid = tcheckpoints[aid]; - auto& next_aidx_aid = next_aidx[aid]; - const auto& next_checkpoint_aid = next_checkpoint[aid]; - assert(next_checkpoint_aid <= next_aidx_aid && next_aidx_aid < num_checkpoints[aid]); - const auto& curr_node = checkpoints_aid[next_aidx_aid - 1]; - const auto& next_node = checkpoints_aid[next_aidx_aid]; - - qli = (qli + 1) & QMOD; - - assert(0 <= next_node && next_node < nnodes); - assert(is_free[next_node]); - if (curr_node >= 0) assert(!is_free[curr_node]); - - const auto& t_curr_node = tcheckpoints_aid[next_aidx_aid - 1]; - const auto& next_o = checkpoints_o_aid[next_aidx_aid]; - - auto& next_vidx_next_node = next_vidx[next_node]; - auto& ipath_visiting_order_next_node = ipath_visiting_order[next_node]; - assert(next_vidx_next_node < ipath_visiting_order_next_node.size()); - assert(ipath_visiting_order_next_node[next_vidx_next_node].second == aid); - - int tend_move = ipath_visiting_order_next_node[next_vidx_next_node].first; - - //const bool print_debug = (aid == 56 || aid == 49 || aid == 27) && (curr_node == 191 || next_node == 191); - const bool print_debug = false; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-A] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tend_move=%d(init) \n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tend_move); - - auto& path_aid = path[aid]; - - if (next_aidx_aid > next_checkpoint_aid && path_aid.tmax <= T) assert(path_aid.p[path_aid.tmax].num_partial_turns == 0); - - const int move_duration = max(1, curr_node < 0 ? 1 : (next_aidx_aid == next_checkpoint_aid ? agent_aid.cturns - path_aid.p[TINIT].num_partial_turns : agent_aid.cturns)); - int tstart_move = tend_move - move_duration; - if (tstart_move < t_curr_node) tstart_move = t_curr_node; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-B] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tstart_move=%d tend_move=%d move_duration=%d\n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tstart_move, tend_move, move_duration); - - assert(path_aid.tmax == t_curr_node); - if (t_curr_node <= T && curr_node >= 0) assert(path_aid.p[t_curr_node].node == curr_node); - int t = t_curr_node + 1; - - tend_move = tstart_move + move_duration; - - if (!agent_aid.inside_poz && next_aidx_aid == next_checkpoint_aid) { - for (; t <= tstart_move; ++t) { - assert(path_aid.tmax == t - 1); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - } - assert(t == tend_move); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = ENTERED_SRC; - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - assert(t == tend_move); - } - ++t; - } - - if (curr_node >= 0) { - if (next_aidx_aid > next_checkpoint_aid || path_aid.p[TINIT].num_partial_turns == 0) { - for (; t <= tstart_move; ++t) { - assert(path_aid.tmax == t - 1); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = WAITED; - assert(new_path_elem.num_partial_turns == 0); - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - } - } - } - int num_partial_turns = next_aidx_aid > next_checkpoint_aid ? 0 : path_aid.p[TINIT].num_partial_turns; - for (; 1; ++t) { - assert(path_aid.tmax == t - 1); - assert(t > TINIT); - path_aid.tmax = t; - PathElem* new_path_elem = nullptr; - if (t <= T) new_path_elem = &path_aid.p[t]; - if (new_path_elem != nullptr) memcpy(new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - ++num_partial_turns; - if (print_debug) DBG(0, " aid=%d t=%d/%d npt=%d\n", aid, t, tend_move, num_partial_turns); - if (new_path_elem != nullptr) { - new_path_elem->num_partial_turns = num_partial_turns; - if (new_path_elem->num_partial_turns == 1) new_path_elem->how_i_got_here = STARTED_MOVING; - else new_path_elem->how_i_got_here = CONTINUED_MOVING; - new_path_elem->moving_to_node = next_node; - new_path_elem->moving_to_o = next_o; - if (new_path_elem->num_partial_turns >= 2) { - if (print_debug) DBG(0, " prev_moving_to=(%d %d)\n", path_aid.p[t - 1].moving_to_node, path_aid.p[t - 1].moving_to_o); - assert(path_aid.p[t - 1].moving_to_node == next_node); - assert(path_aid.p[t - 1].moving_to_o == next_o); - } - } - if (num_partial_turns >= agent_aid.cturns) { - if (t >= tend_move) { - if (new_path_elem != nullptr) { - new_path_elem->node = next_node; - new_path_elem->o = next_o; - new_path_elem->moving_to_node = new_path_elem->moving_to_o = -1; - new_path_elem->num_partial_turns = 0; - if (new_path_elem->node != agent_aid.target_node) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - } - } - tend_move = t; - ++t; - break; - } else if (new_path_elem != nullptr) { - if (print_debug) DBG(0, " >>> is_cov_next_node=%d cov_by=%d\n", is_covered_0[t][next_node] == is_covered_idx_0, covered_by_0[t][next_node]); - if ((is_covered_0[t][next_node] != is_covered_idx_0 && - (is_covered_0[t - 1][next_node] != is_covered_idx_0 || - covered_by_0[t - 1][next_node] < aid)) || - (is_covered_0[t][next_node] == is_covered_idx_0 && covered_by_0[t][next_node] > aid && - (is_covered_0[t - 1][next_node] != is_covered_idx_0 || - covered_by_0[t - 1][next_node] != covered_by_0[t][next_node]))) { - DBG(0, "||| [AdjustIPaths] Agent in motion cannot wait for delayed agent: aid=%d next_aidx_aid=%d tend=%d t=%d curr_node=%d:(%d %d) next_node=%d:(%d %d) next_vidx_next_node=%d target_node=%d:(%d %d) nelems=%d\n", aid, next_aidx_aid, tend_move, t, curr_node, node[curr_node].row, node[curr_node].col, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, agent_aid.target_node, node[agent_aid.target_node].row, node[agent_aid.target_node].col, nelems); - assert(next_vidx_next_node >= 1); - const int prev_aid = ipath_visiting_order_next_node[next_vidx_next_node - 1].second; - if (agent_aid.target_node == next_node || agent[prev_aid].target_node == next_node) { - SwapVisitingOrder(aid, next_aidx_aid, prev_aid); - updated_visiting_order = true; - break; - } - exit(1); - } - if (new_path_elem->node != agent_aid.target_node) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - } - } - } else if (new_path_elem != nullptr) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - assert(num_partial_turns >= 1); - assert(0 <= new_path_elem->moving_to_node && new_path_elem->moving_to_node < nnodes); - } - } - } - - if (updated_visiting_order) break; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-C] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tstart_move=%d tend_move=%d move_duration=%d\n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tstart_move, tend_move, move_duration); - - if (t != tend_move + 1) { - DBG(0, "!!!A aid=%d next_aidx_aid=%d curr_node=%d curr_npt=%d curr_how=%d next_node=%d tstart_move=%d tend_move=%d t=%d: last_path_elem=(node=%d npt=%d/%d how=%d)\n", aid, next_aidx_aid, curr_node, path_aid.p[t_curr_node].num_partial_turns, path_aid.p[t_curr_node].how_i_got_here, next_node, tstart_move, tend_move, t, path_aid.p[path_aid.tmax].node, path_aid.p[path_aid.tmax].num_partial_turns, agent_aid.cturns, path_aid.p[path_aid.tmax].how_i_got_here); - exit(1); - } - - assert(path_aid.tmax == tend_move); - if (tend_move <= T && path_aid.p[tend_move].node != next_node) { - DBG(0, "!!!B aid=%d next_aidx_aid=%d curr_node=%d curr_npt=%d curr_how=%d next_node=%d tstart_move=%d tend_move=%d: last_path_elem=(node=%d npt=%d/%d how=%d)\n", aid, next_aidx_aid, curr_node, path_aid.p[t_curr_node].num_partial_turns, path_aid.p[t_curr_node].how_i_got_here, next_node, tstart_move, tend_move, path_aid.p[path_aid.tmax].node, path_aid.p[path_aid.tmax].num_partial_turns, agent_aid.cturns, path_aid.p[path_aid.tmax].how_i_got_here); - exit(1); - } - - tcheckpoints_aid[next_aidx_aid] = tend_move; - if (curr_node >= 0) is_free[curr_node] = 1; - is_free[next_node] = 0; - ++next_aidx_aid; - ++next_vidx_next_node; - - if (next_aidx_aid < num_checkpoints[aid]) { - const auto& next2_node = checkpoints_aid[next_aidx_aid]; - auto& next_vidx2_next2_node = next_vidx[next2_node]; - auto& ipath_visiting_order_next2_node = ipath_visiting_order[next2_node]; - if (next2_node != curr_node && ipath_visiting_order_next2_node[next_vidx2_next2_node].second == aid && is_free[next2_node]) { - qaid[qls] = aid; - qls = (qls + 1) & QMOD; - } - } else if (next_node == agent_aid.target_node) { - // Free up next_node right away. - is_free[next_node] = 1; - if (next_vidx_next_node < ipath_visiting_order_next_node.size()) { - const auto& aid1 = ipath_visiting_order_next_node[next_vidx_next_node].second; - const auto& path_aid1 = path[aid1]; - const auto& last_path_elem = path_aid1.p[path_aid1.tmax]; - int tend_move_aid1 = tend_move + (aid1 < aid && agent[aid1].target_node != next_node ? 1 : 0); - const auto& agent_aid1 = agent[aid1]; - if (last_path_elem.num_partial_turns == 0 && tend_move_aid1 - agent_aid1.cturns < tend_move) { - tend_move_aid1 = tend_move + agent_aid1.cturns; - } - ipath_visiting_order_next_node[next_vidx_next_node].first = tend_move_aid1; - if (checkpoints[aid1][next_aidx[aid1]] == next_node) { - qaid[qls] = aid1; - qls = (qls + 1) & QMOD; - } - } - } - - if (curr_node >= 0) { - const auto& next_vidx_curr_node = next_vidx[curr_node]; - auto& ipath_visiting_order_curr_node = ipath_visiting_order[curr_node]; - if (next_vidx_curr_node < ipath_visiting_order_curr_node.size()) { - const auto& aid1 = ipath_visiting_order_curr_node[next_vidx_curr_node].second; - const auto& path_aid1 = path[aid1]; - const auto& last_path_elem = path_aid1.p[path_aid1.tmax]; - int tend_move_aid1 = tend_move + (aid1 < aid ? 1 : 0); - const auto& agent_aid1 = agent[aid1]; - if (last_path_elem.num_partial_turns == 0 && tend_move_aid1 - agent_aid1.cturns < t_curr_node) { - tend_move_aid1 = t_curr_node + agent_aid1.cturns; - } - ipath_visiting_order_curr_node[next_vidx_curr_node].first = tend_move_aid1; - if (checkpoints[aid1][next_aidx[aid1]] == curr_node) { - qaid[qls] = aid1; - qls = (qls + 1) & QMOD; - } - } - } - } - - DBG(2, "[AdjustIPaths] nelems=%d updvis=%d\n", nelems, updated_visiting_order); - if (updated_visiting_order) continue; - - if (aid_incomplete < 0) { - for (int node = 0; node < nnodes; ++node) { - const auto& next_vidx_node = next_vidx[node]; - const auto& ipath_visiting_order_node = ipath_visiting_order[node]; - if (next_vidx_node < ipath_visiting_order_node.size()) { - const auto& aid = ipath_visiting_order_node[next_vidx_node].second; - const auto& next_aidx_aid = next_aidx[aid]; - DBG(2, "[AdjustIPaths] incomplete: node=%d is_free=%d next_vidx=%d/%d: aid=%d next_aidx_aid=%d/%d:node=%d/t=%d nextcp=%d\n", node, is_free[node], next_vidx_node, ipath_visiting_order_node.size(), aid, next_aidx_aid, num_checkpoints[aid], checkpoints[aid][next_aidx_aid], checkpoints_t[aid][next_aidx_aid], next_checkpoint[aid]); - assert(next_aidx_aid < num_checkpoints[aid]); - assert(!is_free[node] || checkpoints[aid][next_aidx_aid] != node); - const auto& t_inc = max(ipath_visiting_order_node[next_vidx_node].first, tcheckpoints[aid][next_aidx_aid - 1]); - if (aid_incomplete < 0 || t_inc < tmin_incomplete) { - aid_incomplete = aid; - tmin_incomplete = t_inc; - } - } - } - - assert(aid_incomplete < 0); - } - } - - ++is_covered_idx_0; - - for (int aid = 0; aid < N; ++aid) { - auto& ipath_aid = ipath[aid]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - - const auto& num_checkpoints_aid = num_checkpoints[aid]; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& tcheckpoints_aid = tcheckpoints[aid]; - const auto& next_aidx_aid = next_aidx[aid]; - - if (next_aidx_aid < num_checkpoints_aid) { - const auto& v = checkpoints_aid[next_aidx_aid]; - const auto& ipath_visiting_order_v = ipath_visiting_order[v]; - const auto& next_vidx_v = next_vidx[v]; - assert(next_vidx_v < ipath_visiting_order_v.size()); - DBG(0, "!!! [AdjustIPaths] aid=%d next_aidx_aid=%d/%d: v=%d(%d) next_vidx_v=%d/%d: t=%d vaid=%d\n", aid, next_aidx_aid, num_checkpoints_aid, v, is_free[v], next_vidx_v, ipath_visiting_order_v.size(), ipath_visiting_order_v[next_vidx_v].first, ipath_visiting_order_v[next_vidx_v].second); - exit(1); - } - - // Construct the path. - auto& path_aid = path[aid]; - if (path_aid.tmax > T) path_aid.tmax = T; - - if (path_aid.p[path_aid.tmax].how_i_got_here == OUTSIDE_SRC) { - for (int t = path_aid.tmax + 1; t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - path_aid.tmax = T; - } else if (path_aid.tmax < T && path_aid.p[path_aid.tmax].node != agent_aid.target_node) { - const auto& last_num_partial_turns = path_aid.p[path_aid.tmax].num_partial_turns; - const auto& last_how_i_got_here = path_aid.p[path_aid.tmax].how_i_got_here; - DBG(3, "!!! [AdjustIPaths] aid=%d next_aidx_aid=%d/%d tmax=%d/%d last_node=%d:(%d %d) npt=%d/%d target_node=%d:(%d %d)\n", aid, next_aidx[aid], num_checkpoints[aid], path_aid.tmax, T, path_aid.p[path_aid.tmax].node, node[path_aid.p[path_aid.tmax].node].row, node[path_aid.p[path_aid.tmax].node].col, last_num_partial_turns, agent_aid.cturns, agent_aid.target_node, node[agent_aid.target_node].row, node[agent_aid.target_node].col); - while (path_aid.tmax < T) { - ++path_aid.tmax; - auto& new_path_elem = path_aid.p[path_aid.tmax]; - memcpy(&new_path_elem, &path_aid.p[path_aid.tmax - 1], sizeof(PathElem)); - if (last_num_partial_turns == 0) - new_path_elem.how_i_got_here = last_how_i_got_here == OUTSIDE_SRC ? OUTSIDE_SRC : WAITED; - else { - ++new_path_elem.num_partial_turns; - new_path_elem.how_i_got_here = CONTINUED_MOVING; - } - } - } - - assert(path_aid.tmax <= T); - for (int t = TINIT; t <= path_aid.tmax; ++t) { - const auto& path_elem = path_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - if (path_elem.node == agent_aid.target_node) { - assert(t == path_aid.tmax); - continue; - } - assert(0 <= path_elem.node && path_elem.node < nnodes); - if (is_covered_0[t][path_elem.node] == is_covered_idx_0) { - DBG(0, "!!! [AdjustIPaths] aid=%d t=%d node=%d already covered by %d\n", aid, t, path_elem.node, covered_by_0[t][path_elem.node]); - exit(1); - } - is_covered_0[t][path_elem.node] = is_covered_idx_0; - covered_by_0[t][path_elem.node] = aid; - } - - if (path_aid.tmax != ipath_aid.tmax || path_aid.p[path_aid.tmax].node != ipath_aid.p[path_aid.tmax].node) { - DBG(3, "[AdjustIPaths] aid=%d diff: prev:(tmax=%d node=%d) curr:(tmax=%d node=%d)\n", aid, path_aid.tmax, path_aid.p[path_aid.tmax].node, ipath_aid.tmax, ipath_aid.p[ipath_aid.tmax].node); - } - - CopyPath(path_aid, &ipath_aid); - } - - RunConsistencyChecks(path, covered_by_0, is_covered_0, is_covered_idx_0); - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - auto& checkpoints_t_aid = checkpoints_t[aid]; - const auto& tcheckpoints_aid = tcheckpoints[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - for (int cid = next_checkpoint[aid]; cid < num_checkpoints_aid; ++cid) - checkpoints_t_aid[cid] = tcheckpoints_aid[cid]; - } - - MAX_DONE_AGENTS = 0; - MIN_COST = 0.0; - int new_max_tmax = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& path_aid = path[aid]; - assert(path_aid.tmax > TINIT); - if (path_aid.p[path_aid.tmax].node == agent_aid.target_node) { - ++MAX_DONE_AGENTS; - //MIN_COST += agent_aid.speed * (path_aid.tmax - TINIT); - MIN_COST += path_aid.tmax * path_aid.tmax; - if (path_aid.tmax > new_max_tmax) new_max_tmax = path_aid.tmax; - } else { - assert(path_aid.tmax == T); - //MIN_COST += agent_aid.speed * (path_aid.tmax - TINIT); - } - } - - const bool changed_important_data = MAX_DONE_AGENTS != num_planned || new_max_tmax > max_tmax; - if (changed_important_data) { - DBG(0, ">>> [AdjustIPaths] mda=%d/%d minc=%.3lf new_max_tmax=%d/%d\n", MAX_DONE_AGENTS, num_planned, MIN_COST, new_max_tmax, max_tmax); - } - - return !changed_important_data; -} - -void ReinitDataStructures() { - MAX_DONE_AGENTS = 0; - MIN_COST = 1e10; - for (int aid = 0; aid < N; ++aid) path[aid].tmax = -1000; - xor128[0].reset(14012019U); - for (int tid = 1; tid < MAX_NUM_THREADS; ++tid) xor128[tid].reset(19999997U * tid + 29997U); - for (int tid = 0; tid < MAX_NUM_THREADS; ++tid) { - can_reach_idx[tid] = is_covered_idx[tid] = 0; - auto& can_reach_tid = can_reach[tid]; - auto& is_covered_tid = is_covered[tid]; - for (int t = 0; t <= T + 2; ++t) { - auto& can_reach_tid_t = can_reach_tid[t]; - auto& is_covered_tid_t = is_covered_tid[t]; - for (int i = 0; i < nnodes; ++i) { - is_covered_tid_t[i] = 0; - auto& can_reach_tid_t_i = can_reach_tid_t[i]; - for (int o = 0; o <= 3; ++o) can_reach_tid_t_i[o] = 0; - } - } - } -} - -int GetMove(int aid) { - if (num_planned == 0) return DO_NOTHING; - const auto& path_aid = path[aid]; - const auto& agent_aid = agent[aid]; - if (path_aid.tmax < TINIT + 1) return DO_NOTHING; - const auto& path_elem = path_aid.p[TINIT]; - const auto& path_elem_end_turn = path_aid.p[TINIT + 1]; - int action = DO_NOTHING; - DBG(3, " GetMove for aid=%d: tmax=%d\n", aid, path_aid.tmax); - if (path_elem_end_turn.how_i_got_here == ENTERED_SRC) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node < 0); - assert(path_elem.moving_to_o < 0); - assert(path_elem_end_turn.num_partial_turns == 0); - action = MOVE_FORWARD; - } else if (path_elem_end_turn.how_i_got_here == WAITED) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node < 0); - assert(path_elem.moving_to_o < 0); - assert(path_elem.num_partial_turns == 0); - assert(path_elem_end_turn.num_partial_turns == 0); - action = STOP_MOVING; - } else if (path_elem_end_turn.how_i_got_here == STARTED_MOVING) { - assert(path_elem_end_turn.num_partial_turns <= 1); - int dst_node = -1, dst_o = -1; - if (path_elem_end_turn.moving_to_node >= 0 && path_elem_end_turn.moving_to_o >= 0) { - assert(path_elem_end_turn.num_partial_turns == 1); - dst_node = path_elem_end_turn.moving_to_node; - dst_o = path_elem_end_turn.moving_to_o; - } else { - assert(path_elem_end_turn.num_partial_turns == 0); - dst_node = path_elem_end_turn.node; - dst_o = path_elem_end_turn.o; - } - assert(path_elem.node != dst_node); - assert(next[path_elem.node][path_elem.o][dst_o] == dst_node); - if (dst_o == path_elem.o || dst_o == ((path_elem.o + 2) & 3)) - action = MOVE_FORWARD; - else if (dst_o == ((path_elem.o + 1) & 3)) - action = MOVE_RIGHT; - else if (dst_o == ((path_elem.o + 3) & 3)) - action = MOVE_LEFT; - else { - DBG(0, "Incorrect move!!!\n"); - exit(1); - } - } else if (path_elem_end_turn.how_i_got_here == CONTINUED_MOVING) { - if (path_elem.node == path_elem_end_turn.node) { - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node == path_elem_end_turn.moving_to_node); - assert(path_elem_end_turn.num_partial_turns == path_elem.num_partial_turns + 1); - } else { - assert(path_elem_end_turn.moving_to_node < 0); - assert(path_elem_end_turn.moving_to_o < 0); - assert(path_elem_end_turn.num_partial_turns == 0); - } - } else if (path_elem_end_turn.how_i_got_here == MALFUNCTIONED) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node == path_elem_end_turn.moving_to_node); - assert(path_elem.moving_to_o == path_elem_end_turn.moving_to_o); - assert(path_elem.num_partial_turns == path_elem_end_turn.num_partial_turns); - } - return action; -} - -void WriteMoves(const char* testid) { - num_planned = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - if (ipath_aid.tmax > TINIT && ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node) ++num_planned; - } - sprintf(fname, "output-%s.txt", testid); - FILE* f = fopen(fname, "w"); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const int action = GetMove(aid); - fprintf(f, "%d ", action); - if (action != DO_NOTHING) DBG(2, " Move aid=%d: %d\n", aid, action); - } - fprintf(f, "\n"); - fclose(f); -} - -void SaveDataForReplay(const char* testid) { - sprintf(fname, "saved-%s-%d.txt", testid, TINIT); - FILE* f = fopen(fname, "w"); - fprintf(f, "1\n%d %d\n", H, W); - for (int v = 0; v < nnodes; ++v) { - const auto& node_v = node[v]; - const auto& next_v = next[v]; - for (int o1 = 0; o1 <= 3; ++o1) for (int o2 = 0; o2 <= 3; ++o2) - if (next_v[o1][o2] >= 0) fprintf(f, "%d %d %d %d\n", node_v.row, node_v.col, o1, o2); - } - fprintf(f, "-1 -1 -1 -1\n%d %d\n%d %d %d\n", N, TINIT, num_reschedules, num_planned, num_adjust_ipaths_without_full_plan_regeneration); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - fprintf(f, "%d %d %d %d %d %d %.10lf %.10lf %d %d %d %d 1\n", agent_aid.aid, agent_aid.poz_row, agent_aid.poz_col, agent_aid.poz_o, agent_aid.target_row, agent_aid.target_col, agent_aid.speed, agent_aid.poz_frac, agent_aid.malfunc, agent_aid.nr_malfunc, agent_aid.status, agent_aid.fresh_malfunc); - const auto& ipath_aid = ipath[aid]; - fprintf(f, "%d\n", ipath_aid.tmax); - for (int t = TINIT; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - fprintf(f, "%d %d %d %d %d %d %d %d\n", node[path_elem.node].row, node[path_elem.node].col, path_elem.o, path_elem.moving_to_node < 0 ? -1 : node[path_elem.moving_to_node].row, path_elem.moving_to_node < 0 ? -1 : node[path_elem.moving_to_node].col, path_elem.moving_to_o, path_elem.num_partial_turns, path_elem.how_i_got_here); - } - const auto& num_checkpoints_aid = num_checkpoints[aid]; - const auto& next_checkpoint_aid = next_checkpoint[aid]; - fprintf(f, "%d\n", num_checkpoints_aid - next_checkpoint_aid); - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - const auto& checkpoints_t_aid = checkpoints_t[aid]; - for (int cid = next_checkpoint_aid; cid < num_checkpoints_aid; ++cid) { - fprintf(f, "%d %d %d %d\n", node[checkpoints_aid[cid]].row, node[checkpoints_aid[cid]].col, checkpoints_o_aid[cid], checkpoints_t_aid[cid]); - } - } - fclose(f); -} - -double total_time; - -void GetMoves(const char* testid, bool replay_mode = false) { - TSTART = GetTime(); - sprintf(fname, "input-%s.txt", testid); - fin = fopen(fname, "r"); - ReadTransitionsMap(); - ReadAgentsData(replay_mode); - fclose(fin); - if (TINIT == 0 || replay_mode) { - ReinitDataStructures(); - ComputeShortestPaths(); - } - DBG(2, "testid=%s TINIT=%d: resc=%d nda=%d npl=%d\n", testid, TINIT, reschedule, num_done_agents, num_planned); - if (reschedule) { - if (TINIT >= MIN_TINIT_FOR_SAVE_DATA_FOR_REPLAY) SaveDataForReplay(testid); - bool updated_paths_ok = false; - if (TINIT >= 1) { - updated_paths_ok = AdjustIPaths(); - ++num_adjust_ipaths_without_full_plan_regeneration; - } - const int kMaxNumAdjustIPathsWithoutFullPlanRegenartion = 10; - if (!updated_paths_ok || num_adjust_ipaths_without_full_plan_regeneration > kMaxNumAdjustIPathsWithoutFullPlanRegenartion) { - RegenerateFullPlan(); - if (TINIT >= 1 && any_best_solution_updates) AdjustIPaths(); - num_adjust_ipaths_without_full_plan_regeneration = 0; - } - } - WriteMoves(testid); - if (TINIT == 0) total_time = 0.0; - total_time += GetTime() - TSTART; - DBG(0, "[GetMoves] testid=%s TINIT=%d/%d ttime=%.3lf nresc=%d nadjip=%d nadjipwofpr=%d nda=%d npl=%d sum=%d/%d(%.2lf)\n", testid, TINIT, T, total_time, num_reschedules, num_adjust_ipaths, num_adjust_ipaths_without_full_plan_regeneration, num_done_agents, num_planned, num_done_agents + num_planned, N, 100.0 * (num_done_agents + num_planned) / N); - - /*for (int aid = 0; aid < N; ++aid) { - if (aid == 27 || aid == 49 || aid == 56) { - const auto& ipath_aid = ipath[aid]; - for (int t = max(TINIT, 450); t <= 490 && t <= ipath_aid.tmax; ++t) { - const auto& elem = ipath_aid.p[t]; - DBG(0, "aid=%d t=%d node=%d npt=%d\n", aid, t, elem.node, elem.num_partial_turns); - } - } - }*/ - -// if (TINIT == 417) exit(1); -} - -} - -void GetMoves(const char* testid) { - SOLVE::GetMoves(testid, false); -} - -int main() { - SOLVE::GetMoves("1", true); - return 0; -} - diff --git a/tmp-scores.txt b/tmp-scores.txt index 330b58bef48a89eb77919f561e1244451078392d..e7ebc6ac8e2c36c8d8e4839b4da437f4298f0ef0 100644 --- a/tmp-scores.txt +++ b/tmp-scores.txt @@ -5,3 +5,5 @@ 18 83 45.1086956522 -65137.1666667329 0 0.0000000000 1.7058958372 19 68 85.0000000000 -29969.6666666545 -3 -3.7500000000 0.7965798643 20 120 91.6030534351 -42452.9166666759 1 0.7633587786 0.7918339949 +21 83 69.1666666667 -47696.3333333452 -4 -3.3333333333 0.2761880789 +22 61 54.9549549550 -59817.7500000534 3 2.7027027027 0.5458008149 diff --git a/x-r2sol.cc b/x-r2sol.cc deleted file mode 100644 index df84032d0b904e32d8e8e1df13aeb9c190ee906c..0000000000000000000000000000000000000000 --- a/x-r2sol.cc +++ /dev/null @@ -1,2379 +0,0 @@ -#include "r2sol.h" -#undef NDEBUG -#include <assert.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include <algorithm> -#include <memory> -#include <mutex> -#include <thread> - -#include <algorithm> -#include <vector> - -using namespace std; - -#define DEBUG_LEVEL 0//2 - -#define DBG(debug_level, ...) \ - { \ - if (debug_level <= DEBUG_LEVEL) { \ - fprintf(stderr, __VA_ARGS__); \ - fflush(stderr); \ - } \ - } - -#define HMAX 151 -#define NMAX 201 -#define MAXNODES 3000 -#define TMAX 2567 -#define MAX_NUM_THREADS 1//3//4 -#define MAX_CTURNS 5 -#define INF 1000000000 -#define ZERO 0.000001 -#define ONE 0.999999 -#define USE_SPACING_TO_AVOID_DEADLOCKS 1 -#define USE_STRICT_SPACING_TO_AVOID_DEADLOCKS 0 -#define MIN_TINIT_FOR_SAVE_DATA_FOR_REPLAY 1000000 - -class Xor128 { - public: - void reset(unsigned int seed) { - xx = seed; - yy = 362436069; - zz = 521288629; - uu = 786232308; - } - - inline unsigned int rand() { - unsigned int t = (xx ^ (xx << 11)); - xx = yy; - yy = zz; - zz = uu; - return (uu = (uu ^ (uu >> 19)) ^ (t ^ (t >> 8))); - } - - private: - unsigned int xx, yy, zz, uu; -}; - -double GetTime() { - return 1.0 * clock() / CLOCKS_PER_SEC; -} - -const int DROW[4] = {-1, 0, +1, 0}; -const int DCOL[4] = {0, +1, 0, -1}; - -namespace SOLVE { - -FILE* fin; -char fname[128]; -int H, W, T, TEST, N, TINIT; -double TSTART; - -struct Node { - int row, col; -} node[MAXNODES]; - -int cell_to_node[HMAX][HMAX], nnodes; -int next[MAXNODES][4][4]; -int revnext[MAXNODES][4][4]; - -int target_node_agents[MAXNODES][NMAX], num_target_node_agents[MAXNODES]; - -void ReadTransitionsMap() { - int has_transition_map; - fscanf(fin, "%d", &has_transition_map); - if (!has_transition_map) return; - fscanf(fin, "%d %d", &H, &W); - DBG(2, "[ReadTransitionsMap] has_transition_map=%d H=%d W=%d\n", has_transition_map, H, W); - assert(1 <= H && H < HMAX && 1 <= W && W < HMAX); - for (int i = 0; i < H; ++i) { - for (int j = 0; j < W; ++j) { - cell_to_node[i][j] = -2; - } - } - nnodes = 0; - T = TMAX - 7; - //T = 8 * (H + W + 20); - int row, col, o1, o2, num_transitions = 0; - while (fscanf(fin, "%d %d %d %d", &row, &col, &o1, &o2) == 4) { - if (row < 0 || col < 0 || o1 < 0 || o2 < 0) break; - DBG(4, "row=%d/%d col=%d/%d o1=%d o2=%d nnodes=%d\n", row, H, col, W, o1, o2, nnodes); - assert(0 <= row && row < H); - assert(0 <= col && col < W); - assert(0 <= o1 && o1 < 4); - assert(0 <= o2 && o2 < 4); - if (cell_to_node[row][col] < 0) { - assert(nnodes < MAXNODES); - auto& new_node = node[nnodes]; - new_node.row = row; - new_node.col = col; - auto& next_nnodes = next[nnodes]; - auto& revnext_nnodes = revnext[nnodes]; - for (int tmpo1 = 0; tmpo1 <= 3; ++tmpo1) { - auto& next_nnodes_tmpo1 = next_nnodes[tmpo1]; - auto& revnext_nnodes_tmpo1 = revnext_nnodes[tmpo1]; - for (int tmpo2 = 0; tmpo2 <= 3; ++tmpo2) { - next_nnodes_tmpo1[tmpo2] = revnext_nnodes_tmpo1[tmpo2] = -1; - } - } - num_target_node_agents[nnodes] = 0; - cell_to_node[row][col] = nnodes++; - } - const auto& v1 = cell_to_node[row][col]; - const int rnext = row + DROW[o2], cnext = col + DCOL[o2]; - assert(0 <= rnext && rnext < H); - assert(0 <= cnext && cnext < W); - if (cell_to_node[rnext][cnext] < 0) { - assert(nnodes < MAXNODES); - auto& new_node = node[nnodes]; - new_node.row = rnext; - new_node.col = cnext; - auto& next_nnodes = next[nnodes]; - auto& revnext_nnodes = revnext[nnodes]; - for (int tmpo1 = 0; tmpo1 <= 3; ++tmpo1) { - auto& next_nnodes_tmpo1 = next_nnodes[tmpo1]; - auto& revnext_nnodes_tmpo1 = revnext_nnodes[tmpo1]; - for (int tmpo2 = 0; tmpo2 <= 3; ++tmpo2) { - next_nnodes_tmpo1[tmpo2] = revnext_nnodes_tmpo1[tmpo2] = -1; - } - } - num_target_node_agents[nnodes] = 0; - cell_to_node[rnext][cnext] = nnodes++; - } - const auto& v2 = cell_to_node[rnext][cnext]; - next[v1][o1][o2] = v2; - revnext[v2][o2][o1] = v1; - ++num_transitions; - } - DBG(0, "[ReadTransitionsMap] num_transitions=%d nnodes=%d/%d\n", num_transitions, nnodes, H * W); -} - -enum HowIGotHere { - INVALID = -1, - OUTSIDE_SRC = 0, - ENTERED_SRC = 1, - STARTED_MOVING = 2, - CONTINUED_MOVING = 3, - WAITED = 4, - MALFUNCTIONED = 5, -}; - -enum RailAgentStatus { - READY_TO_DEPART = 0, - ACTIVE = 1, - DONE = 2, - DONE_REMOVED = 3, -}; - -enum RailEnvActions { - DO_NOTHING = 0, - MOVE_LEFT = 1, - MOVE_FORWARD = 2, - MOVE_RIGHT = 3, - STOP_MOVING = 4, -}; - -struct PathElem { - int node, o, moving_to_node, moving_to_o, num_partial_turns; - HowIGotHere how_i_got_here; - - void PrintDebug(int t = -1) { - DBG(0, "t=%d poz=(%d %d) moving_to=(%d %d) npturns=%d how=%d\n", t, node, o, moving_to_node, moving_to_o, num_partial_turns, how_i_got_here); - } -}; - -struct Path { - struct PathElem p[TMAX]; - int tmax; -}; - -void CopyPath(const Path& src, Path* dst) { - dst->tmax = src.tmax; - if (src.tmax >= TINIT) memcpy(&dst->p[TINIT], &src.p[TINIT], (src.tmax - TINIT + 1) * sizeof(PathElem)); -} - -struct Agent { - int aid, poz_row, poz_col, poz_o, poz_node, target_row, target_col, target_node, malfunc, nr_malfunc, cturns; - double speed, poz_frac; - int inside_poz, fresh_malfunc, moving_to_node, moving_to_o; - RailAgentStatus status; -} agent[NMAX], tmp_agent; - -int cturns_agents[MAX_CTURNS][NMAX], num_cturns_agents[MAX_CTURNS]; - -int MAX_DONE_AGENTS; -double MIN_COST; -struct Path path[NMAX], ipath[NMAX]; - -int checkpoints[NMAX][TMAX], checkpoints_o[NMAX][TMAX], checkpoints_t[NMAX][TMAX], checkpoints_cnt[NMAX][TMAX], num_checkpoints[NMAX], tcheckpoints[NMAX][TMAX], next_checkpoint[NMAX]; - -vector<pair<int, int>> ipath_visiting_order[MAXNODES]; - -void RepopulateVisitingOrders() { - for (int node = 0; node < nnodes; ++node) ipath_visiting_order[node].clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_t_aid = checkpoints_t[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - for (int idx = next_checkpoint[aid]; idx < num_checkpoints_aid; ++idx) - ipath_visiting_order[checkpoints_aid[idx]].push_back({checkpoints_t_aid[idx], aid}); - } - for (int node = 0; node < nnodes; ++node) { - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - sort(ipath_visiting_order_node.begin(), ipath_visiting_order_node.end()); - } -} - -short int covered_by[MAX_NUM_THREADS][TMAX][MAXNODES]; -int is_covered[MAX_NUM_THREADS][TMAX][MAXNODES], is_covered_idx[MAX_NUM_THREADS], can_reach_idx[MAX_NUM_THREADS], can_reach[MAX_NUM_THREADS][TMAX][MAXNODES][4]; -short int can_reach_with_t1[MAX_NUM_THREADS][TMAX][MAXNODES][4]; -short int tmax_at_poz_node[MAX_NUM_THREADS][NMAX]; - -void CheckAgent(int aid) { - auto& agent_aid = agent[aid]; - const auto& path = ipath[aid]; - if (path.tmax < TINIT) { - assert(agent_aid.status == DONE_REMOVED); - return; - } - - const auto& path_elem = path.p[TINIT]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) { - assert(!agent_aid.inside_poz); - assert(agent_aid.status == READY_TO_DEPART); - return; - } - - if (agent_aid.inside_poz) { - auto& next_checkpoint_aid = next_checkpoint[aid]; - assert(next_checkpoint_aid < num_checkpoints[aid]); - if (checkpoints[aid][next_checkpoint_aid] == agent_aid.poz_node) { - assert(checkpoints_o[aid][next_checkpoint_aid] == agent_aid.poz_o); - ++next_checkpoint_aid; - } - } - - const auto& is_covered_idx_0 = is_covered_idx[0]; - auto& is_covered_0 = is_covered[0]; - - if (agent_aid.fresh_malfunc) { - if (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING) { - assert(0 <= agent_aid.moving_to_node && agent_aid.moving_to_node < nnodes); - assert(0 <= agent_aid.moving_to_o && agent_aid.moving_to_o < nnodes); - if (path_elem.num_partial_turns >= 1) { - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - (path_elem.num_partial_turns - 1) * agent_aid.speed) < ZERO); - } else { - assert(next[agent_aid.poz_node][agent_aid.poz_o][path_elem.o] == path_elem.node); - assert(agent_aid.poz_frac >= (agent_aid.cturns - 1) * agent_aid.speed - ZERO); - } - } else { - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - path_elem.num_partial_turns * agent_aid.speed) < ZERO); - } - } else if (is_covered_0[TINIT][path_elem.node] == is_covered_idx_0) { - assert((path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING || path_elem.how_i_got_here == ENTERED_SRC) && path_elem.num_partial_turns == 0); - if (path_elem.how_i_got_here == ENTERED_SRC) assert(!agent_aid.inside_poz); - else { - assert(agent_aid.inside_poz); - assert(agent_aid.poz_frac >= ONE); - assert(agent_aid.moving_to_node == path_elem.node); - assert(agent_aid.moving_to_o == path_elem.o); - } - } else if (path.tmax == TINIT) { - assert(!agent_aid.inside_poz); - assert(agent_aid.status == DONE_REMOVED); - assert(agent_aid.moving_to_node == path_elem.node); - agent_aid.moving_to_node = agent_aid.moving_to_o = -1; - } else { - assert(agent_aid.inside_poz); - assert(agent_aid.poz_node == path_elem.node); - assert(agent_aid.poz_o == path_elem.o); - assert(fabs(agent_aid.poz_frac - path_elem.num_partial_turns * agent_aid.speed) < ZERO); - if (0 <= agent_aid.moving_to_node && agent_aid.moving_to_node < nnodes && path_elem.num_partial_turns == 0 && - (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) { - assert(agent_aid.moving_to_node == path_elem.node); - assert(agent_aid.moving_to_o == path_elem.o); - agent_aid.moving_to_node = agent_aid.moving_to_o = -1; - } - if (path_elem.num_partial_turns == 0 && (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) - assert(agent_aid.moving_to_node < 0); - } - - if (agent_aid.inside_poz) is_covered_0[TINIT][agent_aid.poz_node] = is_covered_idx_0; -} - -bool reschedule; -int num_done_agents, num_planned, num_reschedules, num_adjust_ipaths; -int num_adjust_ipaths_without_full_plan_regeneration; - -int important_row[2 * NMAX], important_col[2 * NMAX]; -char visited[2 * NMAX]; - -void DFSMarkCities(int aid) { - visited[aid] = 1; - static const int kMaxDiff = 2; - for (int aid2 = 0; aid2 < 2 * N; ++aid2) { - if (visited[aid2]) continue; - if (abs(important_row[aid] - important_row[aid2]) <= kMaxDiff && abs(important_col[aid] - important_col[aid2]) <= kMaxDiff) - DFSMarkCities(aid2); - } -} - -void EstimateT() { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - important_row[2 * aid] = agent_aid.poz_row; - important_col[2 * aid] = agent_aid.poz_col; - important_row[2 * aid + 1] = agent_aid.target_row; - important_col[2 * aid + 1] = agent_aid.target_col; - visited[2 * aid] = visited[2 * aid + 1] = 0; - } - int num_cities = 0; - for (int aid = 0; aid < 2 * N; ++aid) { - if (visited[aid]) continue; - DFSMarkCities(aid); - ++num_cities; - } - if (1.0 * N / num_cities < 20.0 - 1e-6) - TEST = (int)(8.0 * (H + W + 1.0 * N / num_cities)); - else - TEST = 8 * (H + W + 20); - DBG(0, "(estimated) num_cities=%d TEST=%d\n", num_cities, TEST); -} - -void ReadAgentsData(bool replay_mode = false) { - fscanf(fin, "%d %d", &N, &TINIT); - DBG(2, "[ReadAgentsData] N=%d TINIT=%d/%d\n", N, TINIT, T); - assert(1 <= N && N < NMAX); - if (replay_mode) { - fscanf(fin, "%d %d %d", &num_reschedules, &num_planned, &num_adjust_ipaths_without_full_plan_regeneration); - reschedule = TINIT == 0; - } else if (TINIT == 0) { - reschedule = true; - num_reschedules = 0; - num_adjust_ipaths = 0; - num_adjust_ipaths_without_full_plan_regeneration = 0; - num_planned = N; - } else reschedule = false; - if (num_planned == 0) return; - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) num_cturns_agents[cturns] = 0; - num_done_agents = 0; - num_planned = TINIT == 0 ? N : 0; - ++is_covered_idx[0]; - for (int aid = 0; aid < N; ++aid) { - int has_path_data = 0, has_moving_to_data = 0, status = -1; - fscanf(fin, "%d %d %d %d %d %d %lf %lf %d %d %d %d %d %d", &tmp_agent.aid, &tmp_agent.poz_row, &tmp_agent.poz_col, &tmp_agent.poz_o, &tmp_agent.target_row, &tmp_agent.target_col, &tmp_agent.speed, &tmp_agent.poz_frac, &tmp_agent.malfunc, &tmp_agent.nr_malfunc, &status, &tmp_agent.fresh_malfunc, &has_moving_to_data, &has_path_data); - assert(aid == tmp_agent.aid); - assert(status == READY_TO_DEPART || status == ACTIVE || status == DONE || status == DONE_REMOVED); - tmp_agent.status = (RailAgentStatus) status; - tmp_agent.poz_node = cell_to_node[tmp_agent.poz_row][tmp_agent.poz_col]; - tmp_agent.target_node = cell_to_node[tmp_agent.target_row][tmp_agent.target_col]; - tmp_agent.cturns = 0; - while (tmp_agent.cturns * tmp_agent.speed < ONE) ++tmp_agent.cturns; - tmp_agent.inside_poz = tmp_agent.status != READY_TO_DEPART && tmp_agent.status != DONE_REMOVED; - - auto& agent_aid = agent[aid]; - if (has_moving_to_data) { - int row, col; - fscanf(fin, "%d %d %d", &row, &col, &tmp_agent.moving_to_o); - if (row < 0 && col < 0) { - tmp_agent.moving_to_node = -1; - assert(tmp_agent.moving_to_o < 0); - } else { - tmp_agent.moving_to_node = cell_to_node[row][col]; - assert(0 <= tmp_agent.moving_to_node && tmp_agent.moving_to_node < nnodes); - assert(0 <= tmp_agent.moving_to_o && tmp_agent.moving_to_o <= 3); - } - } else if (TINIT == 0) tmp_agent.moving_to_node = tmp_agent.moving_to_o = -1; - else { - tmp_agent.moving_to_node = agent_aid.moving_to_node; - tmp_agent.moving_to_o = agent_aid.moving_to_o; - } - - if (TINIT >= 1) { - if (!replay_mode) tmp_agent.fresh_malfunc |= (tmp_agent.nr_malfunc > agent_aid.nr_malfunc); - reschedule |= tmp_agent.fresh_malfunc; - if (tmp_agent.status == DONE_REMOVED) ++num_done_agents; - } - memcpy(&agent_aid, &tmp_agent, sizeof(Agent)); - - if (replay_mode || TINIT == 0) target_node_agents[agent_aid.target_node][num_target_node_agents[agent_aid.target_node]++] = aid; - - auto& ipath_aid = ipath[aid]; - if (has_path_data) { - fscanf(fin, "%d", &ipath_aid.tmax); - for (int t = TINIT; t <= ipath_aid.tmax; ++t) { - auto& new_path_elem = ipath_aid.p[t]; - int poz_row, poz_col, moving_to_row, moving_to_col, how_i_got_here = -1; - fscanf(fin, "%d %d %d %d %d %d %d %d", &poz_row, &poz_col, &new_path_elem.o, &moving_to_row, &moving_to_col, &new_path_elem.moving_to_o, &new_path_elem.num_partial_turns, &how_i_got_here); - assert(0 <= poz_row && poz_row < H && 0 <= poz_col && poz_col < W); - new_path_elem.node = cell_to_node[poz_row][poz_col]; - assert(0 <= new_path_elem.node && new_path_elem.node < nnodes); - if (moving_to_row >= 0 && moving_to_col >= 0) - new_path_elem.moving_to_node = cell_to_node[moving_to_row][moving_to_col]; - else new_path_elem.moving_to_node = -1; - assert(how_i_got_here == OUTSIDE_SRC || how_i_got_here == ENTERED_SRC || how_i_got_here == STARTED_MOVING || how_i_got_here == CONTINUED_MOVING || how_i_got_here == WAITED || how_i_got_here == MALFUNCTIONED); - new_path_elem.how_i_got_here = (HowIGotHere) how_i_got_here; - } - auto& num_checkpoints_aid = num_checkpoints[aid]; - fscanf(fin, "%d", &num_checkpoints_aid); - ++num_checkpoints_aid; - auto& checkpoints_aid = checkpoints[aid]; - auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_t_aid = checkpoints_t[aid]; - next_checkpoint[aid] = 1; - for (int cid = 1; cid < num_checkpoints_aid; ++cid) { - int row, col; - fscanf(fin, "%d %d %d %d", &row, &col, &checkpoints_o_aid[cid], &checkpoints_t_aid[cid]); - checkpoints_aid[cid] = cell_to_node[row][col]; - assert(0 <= checkpoints_aid[cid] && checkpoints_aid[cid] < nnodes); - } - if (agent_aid.inside_poz) { - checkpoints_aid[0] = agent_aid.poz_node; - checkpoints_o_aid[0] = agent_aid.poz_o; - } else { - checkpoints_aid[0] = checkpoints_o_aid[0] = -1; - } - checkpoints_t_aid[0] = TINIT; - } else if (TINIT == 0) { - // Initialize the path with fully waiting outside. - ipath_aid.tmax = T; - for (int t = 0; t <= T; ++t) { - auto& new_path_elem = ipath_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - num_checkpoints[aid] = next_checkpoint[aid] = 1; - checkpoints[aid][0] = checkpoints_o[aid][0] = -1; - } - - if (ipath_aid.tmax >= TINIT && ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node && agent_aid.status != DONE_REMOVED) - ++num_planned; - - DBG(2, "\nTINIT=%d aid=%d: poz=(%d %d %d):%d inside_poz=%d target=(%d %d):%d moving_to_node=%d:(%d %d) moving_to_o=%d cturns=%d speed=%.6lf poz_frac=%.6lf malf=%d nr_malf=%d status=%d fresh_malf=%d\n", TINIT, agent_aid.aid, agent_aid.poz_row, agent_aid.poz_col, agent_aid.poz_o, agent_aid.poz_node, agent_aid.inside_poz, agent_aid.target_row, agent_aid.target_col, agent_aid.target_node, agent_aid.moving_to_node, node[agent_aid.moving_to_node].row, node[agent_aid.moving_to_node].col, agent_aid.moving_to_o, agent_aid.cturns, agent_aid.speed, agent_aid.poz_frac, agent_aid.malfunc, agent_aid.nr_malfunc, agent_aid.status, agent_aid.fresh_malfunc); - - assert(0 <= agent_aid.poz_row && agent_aid.poz_row < H); - assert(0 <= agent_aid.poz_col && agent_aid.poz_col < W); - assert(0 <= agent_aid.poz_node && agent_aid.poz_node < nnodes); - assert(0 <= agent_aid.poz_o && agent_aid.poz_o <= 3); - assert(0 <= agent_aid.target_row && agent_aid.target_row < H); - assert(0 <= agent_aid.target_col && agent_aid.target_col < W); - assert(0 <= agent_aid.target_node && agent_aid.target_node < nnodes); - assert(agent_aid.cturns < MAX_CTURNS); - cturns_agents[agent_aid.cturns][num_cturns_agents[agent_aid.cturns]++] = aid; - - if (TINIT >= 1) { - CheckAgent(aid); - DBG(2, " still moving_to_node=%d:(%d %d) moving_to_o=%d\n", agent_aid.moving_to_node, node[agent_aid.moving_to_node].row, node[agent_aid.moving_to_node].col, agent_aid.moving_to_o); - } - } - - if (TINIT == 0 || replay_mode) { - if (TINIT == 0) EstimateT(); - else fscanf(fin, "%d", &T); - } - - //exit(1); -} - -struct ShortestPathQueueElement { - int node, o; -} qshpath[MAXNODES * 4]; - -int dmin[NMAX][MAXNODES][4], prev_node[NMAX][MAXNODES][4], prev_o[NMAX][MAXNODES][4]; - -void ComputeShortestPaths(int aid) { - auto& dmin_aid = dmin[aid]; - auto& prev_node_aid = prev_node[aid]; - auto& prev_o_aid = prev_o[aid]; - for (int node = 0; node < nnodes; ++node) { - auto& dmin_aid_node = dmin_aid[node]; - for (int o = 0; o <= 3; ++o) dmin_aid_node[o] = INF; - } - int qli = 0, qls = -1; - const auto& agent_aid = agent[aid]; - for (int o = 0; o <= 3; ++o) { - auto& new_queue_elem = qshpath[++qls]; - new_queue_elem.node = agent_aid.target_node; - new_queue_elem.o = o; - dmin_aid[agent_aid.target_node][o] = 0; - } - while (qli <= qls) { - const auto& qelem = qshpath[qli++]; - const auto& node1 = qelem.node; - const auto& o1 = qelem.o; - const int dnew = dmin_aid[node1][o1] + agent_aid.cturns; - const auto& revnext_node1_o1 = revnext[node1][o1]; - for (int o2 = 0; o2 <= 3; ++o2) { - const auto& node2 = revnext_node1_o1[o2]; - if (node2 < 0) continue; - if (dnew < dmin_aid[node2][o2]) { - dmin_aid[node2][o2] = dnew; - auto& new_queue_elem = qshpath[++qls]; - new_queue_elem.node = node2; - new_queue_elem.o = o2; - prev_node_aid[node2][o2] = node1; - prev_o_aid[node2][o2] = o1; - } - } - } -} - -void ComputeShortestPaths() { - for (int aid = 0; aid < N; ++aid) ComputeShortestPaths(aid); -} - -Xor128 xor128[MAX_NUM_THREADS]; -short int perm[MAX_NUM_THREADS][NMAX]; -char pused[MAX_NUM_THREADS][NMAX]; - -#define MAX_HEAP_SIZE 100000 - -struct HeapElement { - short int t, node, t1, est_tmin; - char o; - - bool IsSmaller(const HeapElement& other) const { - return est_tmin < other.est_tmin || (est_tmin == other.est_tmin && t1 > other.t1); - } -} heap[MAX_NUM_THREADS][/*TMAX * MAXNODES * 4*/MAX_HEAP_SIZE]; - -int heap_size[MAX_NUM_THREADS]; - -inline void Swap(HeapElement h[], int poza, int pozb) { - auto& a = h[poza]; - auto& b = h[pozb]; - const HeapElement tmp = a; - a = b; - b = tmp; -} - -inline void PushUp(HeapElement h[], int poz) { - while (poz > 1) { - const int parent = poz >> 1; - auto& h_poz = h[poz]; - auto& h_parent = h[parent]; - if (h_poz.IsSmaller(h_parent)) { - Swap(h, poz, parent); - poz = parent; - } else - break; - } -} - -inline void PushDown(HeapElement h[], int& hsize, int poz) { - while (1) { - const int lchild = poz << 1; - if (lchild > hsize) break; - auto& h_lchild = h[lchild]; - auto& h_poz = h[poz]; - const int rchild = lchild + 1; - if (rchild <= hsize) { - auto& h_rchild = h[rchild]; - if (h_lchild.IsSmaller(h_rchild)) { - if (h_lchild.IsSmaller(h_poz)) { - Swap(h, lchild, poz); - poz = lchild; - } else - break; - } else { - if (h_rchild.IsSmaller(h_poz)) { - Swap(h, rchild, poz); - poz = rchild; - } else - break; - } - } else { - if (h_lchild.IsSmaller(h_poz)) { - Swap(h, lchild, poz); - poz = lchild; - } else - break; - } - } -} - -inline void InsertIntoHeap(HeapElement h[], int& hsize, int t, int node, int o, int t1, int est_tmin) { - assert(hsize< MAX_HEAP_SIZE); - auto& new_element = h[++hsize]; - new_element.t = t; - new_element.node = node; - new_element.o = o; - new_element.t1 = t1; - new_element.est_tmin = est_tmin; - PushUp(h, hsize); -} - -inline void ExtractMinFromHeap(HeapElement h[], int& hsize, int& t, int& node, int& o, int& t1) { - assert(hsize >= 1); - auto& min_element = h[1]; - t = min_element.t; - node = min_element.node; - o = min_element.o; - t1 = min_element.t1; - min_element = h[--hsize]; - if (hsize >= 1) PushDown(h, hsize, 1); -} - -struct Path tmp_path[MAX_NUM_THREADS][NMAX], tmp_path2[MAX_NUM_THREADS][NMAX]; -mutex m; - -struct PrevState { - short int node, t; - char o; - HowIGotHere type; -} prev[MAX_NUM_THREADS][TMAX][MAXNODES][4]; - - -void CopyTmpPathToPath(int tid) { - // The mutex must be held before calling this function. - const auto& tmp_path_tid = tmp_path[tid]; - for (int aid = 0; aid < N; ++aid) { - auto& path_aid = path[aid]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) { - path_aid.tmax = -1; - continue; - } - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CopyPath(tmp_path_tid_aid, &path_aid); - } -} - -void RecomputeCheckpoints() { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - auto& num_checkpoints_aid = num_checkpoints[aid]; - - if (agent_aid.status == DONE_REMOVED) { - num_checkpoints_aid = next_checkpoint[aid] = 0; - continue; - } - - const auto& ipath_aid = ipath[aid]; - assert(ipath_aid.tmax > TINIT); - if (ipath_aid.p[ipath_aid.tmax].node != agent_aid.target_node) { - // This path hasn't been updated. We should keep the previously computed checkpoints. - continue; - } - - num_checkpoints_aid = next_checkpoint[aid] = 1; - - auto& checkpoints_aid = checkpoints[aid]; - auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_t_aid = checkpoints_t[aid]; - - if (agent_aid.inside_poz) { - checkpoints_aid[0] = agent_aid.poz_node; - checkpoints_o_aid[0] = agent_aid.poz_o; - } else { - checkpoints_aid[0] = checkpoints_o_aid[0] = -1; - } - - for (int t = TINIT + 1; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - if (path_elem.how_i_got_here == ENTERED_SRC || path_elem.node != checkpoints_aid[num_checkpoints_aid - 1]) { - checkpoints_aid[num_checkpoints_aid] = path_elem.node; - checkpoints_o_aid[num_checkpoints_aid] = path_elem.o; - checkpoints_t_aid[num_checkpoints_aid] = t; - ++num_checkpoints_aid; - } - } - } -} - -bool CanEnterCell(int aid, int t, int from, int to, const short int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - assert(t > TINIT); - assert(0 <= to && to < nnodes); - const auto& agent_aid = agent[aid]; - const auto& is_covered1 = is_covered[t][to]; - const auto& is_covered2 = is_covered[t - 1][to]; - const auto& aid1 = covered_by[t][to]; - const auto& aid2 = covered_by[t - 1][to]; - - if (agent_aid.target_node == to) { - if (is_covered1 == is_covered_idx && aid1 < aid) return false; - if (is_covered2 == is_covered_idx && aid2 > aid) return false; - //if (USE_SPACING_TO_AVOID_DEADLOCKS && is_covered1 == is_covered_idx && (agent_aid.cturns >= 2 || agent[aid2].cturns >= 2)) return false; - } else { - if (is_covered1 == is_covered_idx) return false; - if (is_covered2 == is_covered_idx && aid2 > aid) return false; - if (from >= 0) { - const auto& is_covered3 = is_covered[t][from]; - const auto& aid3 = covered_by[t][from]; - if (is_covered2 == is_covered_idx && is_covered3 == is_covered_idx && aid2 == aid3) return false; - if (is_covered3 == is_covered_idx && aid3 < aid) return false; - } - if (t + 1 < T) { - const auto& is_covered4 = is_covered[t + 1][to]; - const auto& aid4 = covered_by[t + 1][to]; - if (is_covered4 == is_covered_idx && aid4 < aid) return false; - } - const auto& target_node_agents_to = target_node_agents[to]; - const auto& num_target_node_agents_to = num_target_node_agents[to]; - for (int idx = num_target_node_agents_to - 1; idx >= 0; --idx) { - const auto& aid5 = target_node_agents_to[idx]; - const auto& agent_aid5 = agent[aid5]; - if (agent_aid5.status == DONE_REMOVED) continue; - const auto& tmp_path_aid5 = tmp_path[aid5]; - assert(tmp_path_aid5.tmax > TINIT); - if (aid5 > aid && tmp_path_aid5.tmax == t && tmp_path_aid5.p[t].node == to) return false; - //if (USE_SPACING_TO_AVOID_DEADLOCKS && tmp_path_aid5.tmax == t && tmp_path_aid5.p[t].node == to && (agent_aid.cturns >= 2 || agent_aid5.cturns >= 2)) return false; - if (aid5 < aid && tmp_path_aid5.tmax == t + 1 && tmp_path_aid5.p[t + 1].node == to) return false; - } - } - - return true; -} - -inline bool IsFreeTimeWindow(int aid, int t1, int t2, int node, const short int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[]) { - for (int t = t1; t <= t2; ++t) if (!CanEnterCell(aid, t, node, node, covered_by, is_covered, is_covered_idx, tmp_path)) return false; - return true; -} - -int tend_ongoing_move[NMAX]; - -bool OverlapsOngoingMove(int t1, int t2, int node, const short int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, const Path tmp_path[], short int tmax_at_poz_node[]) { - if (!USE_SPACING_TO_AVOID_DEADLOCKS) return false; - - if (t1 < tend_ongoing_move[node]) return true; - //if (t2 <= tend_ongoing_move[node]) return true; - - const int min_tstart = t2;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? t2 : t1; - //const int min_tstart = t1;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? t2 : t1; - - const int aid_t1 = is_covered[t1][node] == is_covered_idx ? covered_by[t1][node] : -1; - - for (int tend = t2 + 1; tend <= t2 + 3 && tend <= T; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid = covered_by[tend][node]; - const auto& agent_aid = agent[aid]; - if (tend - agent_aid.cturns < min_tstart && (aid != aid_t1 || is_covered[tend - 1][node] != is_covered_idx)) return true; - } - } - - if (USE_STRICT_SPACING_TO_AVOID_DEADLOCKS) { - for (int tend = t1 + 1; tend <= t2; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid_tend = covered_by[tend][node]; - if (aid_tend != aid_t1 || is_covered[tend - 1][node] != is_covered_idx) return true; - } - } - } - - /*for (int tend = t2 + 1; tend <= t2 + 3 && tend <= T; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid = covered_by[tend][node]; - const auto& agent_aid = agent[aid]; - if (tend - agent_aid.cturns < t2) return true; - } - } - for (int tend = t1 + 1; tend <= t2; ++tend) { - if (is_covered[tend][node] == is_covered_idx) { - const auto& aid_tend = covered_by[tend][node]; - const auto& curr_node_aid_tend = agent[aid_tend].poz_node; - if (curr_node_aid_tend != node || tmax_at_poz_node[aid_tend] < tend) return true; - } - }*/ - - - /*const auto& target_node_agents_node = target_node_agents[node]; - const auto& num_target_node_agents_node = num_target_node_agents[node]; - for (int idx = num_target_node_agents_node - 1; idx >= 0; --idx) { - const auto& aid5 = target_node_agents_node[idx]; - const auto& agent_aid5 = agent[aid5]; - if (agent_aid5.status == DONE_REMOVED) continue; - const auto& tmp_path_aid5 = tmp_path[aid5]; - assert(tmp_path_aid5.tmax > TINIT); - if (tmp_path_aid5.p[tmp_path_aid5.tmax].node == agent_aid5.target_node && t1 < tmp_path_aid5.tmax && tmp_path_aid5.tmax <= t2) { - return true; - } - }*/ - - return false; -} - -bool FindBestPath(int aid, const short int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, int can_reach[][MAXNODES][4], int& can_reach_idx, short int can_reach_with_t1[][MAXNODES][4], HeapElement h[], int& hsize, PrevState prev[][MAXNODES][4], Path tmp_path[], Path* tmp_path2, short int tmax_at_poz_node[]) { - const auto& agent_aid = agent[aid]; - auto& tmp_path_aid = tmp_path[aid]; - - hsize = 0; - - ++can_reach_idx; - const auto& target_node = agent_aid.target_node; - const auto& cturns = agent_aid.cturns; - const auto& dmin_aid = dmin[aid]; - - int t1 = TINIT, t2 = TINIT, rnode = -1, ro = -1; - - if (!agent_aid.inside_poz) { - rnode = agent_aid.poz_node; - ro = agent_aid.poz_o; - t1 = TINIT + max(agent_aid.malfunc - 1, 0); - for (int tstart = t1; tstart < T; ++tstart) { - if (!CanEnterCell(aid, tstart + 1, -1, rnode, covered_by, is_covered, is_covered_idx, tmp_path)) continue; - int t2 = tstart + 1; - const int est_tmin = t2 + dmin_aid[rnode][ro]; - if (est_tmin > T) break; - can_reach[t2][rnode][ro] = can_reach_idx; - can_reach_with_t1[t2][rnode][ro] = tstart + 1; - auto& new_prev = prev[t2][rnode][ro]; - new_prev.t = new_prev.node = new_prev.o = -1; - InsertIntoHeap(h, hsize, t2, rnode, ro, tstart + 1, est_tmin); - } - } else { - t1 = TINIT; - rnode = agent_aid.poz_node; - ro = agent_aid.poz_o; - int moving_to_node = agent_aid.moving_to_node, moving_to_o = agent_aid.moving_to_o; - while (t1 + 1 <= tmp_path_aid.tmax && tmp_path_aid.p[t1 + 1].how_i_got_here == MALFUNCTIONED) { - ++t1; - if (!CanEnterCell(aid, t1, rnode, rnode, covered_by, is_covered, is_covered_idx, tmp_path)) return false; - } - if (t1 >= T) return false; - if (t1 != TINIT + agent_aid.malfunc) { - DBG(0, "!!! [FindBestPath] aid=%d TINIT=%d malfunc=%d t1=%d/%d/%d\n", aid, TINIT, agent_aid.malfunc, t1, TINIT + agent_aid.malfunc, T); - exit(1); - } - memcpy(&tmp_path2->p[TINIT], &tmp_path_aid.p[TINIT], (t1 - TINIT + 1) * sizeof(PathElem)); - t2 = t1; - if (moving_to_node >= 0) { - bool finished_moving = false; - while (t2 < T && rnode == agent_aid.poz_node) { - const auto& prev_path_elem = tmp_path2->p[t2]; - auto& next_path_elem = tmp_path2->p[t2 + 1]; - if (prev_path_elem.num_partial_turns + 1 < agent_aid.cturns || !CanEnterCell(aid, t2 + 1, rnode, moving_to_node, covered_by, is_covered, is_covered_idx, tmp_path)) { - memcpy(&next_path_elem, &prev_path_elem, sizeof(PathElem)); - ++next_path_elem.num_partial_turns; - next_path_elem.how_i_got_here = CONTINUED_MOVING; - } else { - next_path_elem.node = moving_to_node; - next_path_elem.o = moving_to_o; - next_path_elem.moving_to_node = next_path_elem.moving_to_o = -1; - next_path_elem.num_partial_turns = 0; - next_path_elem.how_i_got_here = CONTINUED_MOVING; - finished_moving = true; - } - ++t2; - } - if (finished_moving) { - rnode = moving_to_node; - ro = moving_to_o; - } - if (OverlapsOngoingMove(TINIT, t2, moving_to_node, covered_by, is_covered, is_covered_idx, tmp_path, tmax_at_poz_node)) - return false; - } - const int est_tmin = t2 + dmin_aid[rnode][ro]; - if (est_tmin <= T) { - can_reach[t2][rnode][ro] = can_reach_idx; - can_reach_with_t1[t2][rnode][ro] = t1; - auto& new_prev = prev[t2][rnode][ro]; - new_prev.t = new_prev.node = new_prev.o = -1; - InsertIntoHeap(h, hsize, t2, rnode, ro, t1, est_tmin); - } - } - - int TMIN = T + 1, best_o = -1, best_node = -1, best_t1 = -1; - - if (tmp_path_aid.tmax < TINIT || tmp_path_aid.p[tmp_path_aid.tmax].node == agent_aid.target_node) TMIN = tmp_path_aid.tmax; - - while (hsize >= 1) { - int t, node, o, ct1; - ExtractMinFromHeap(h, hsize, t, node, o, ct1); - assert(0 <= t && t <= T); - assert(can_reach[t][node][o] == can_reach_idx); - if (ct1 != can_reach_with_t1[t][node][o]) continue; - const auto& curr_dmin_aid = dmin_aid[node][o]; - if (t + curr_dmin_aid > TMIN) break; - - // Case 1: Wait. - if (t + 1 <= TMIN && t + 1 <= T && CanEnterCell(aid, t + 1, node, node, covered_by, is_covered, is_covered_idx, tmp_path) && - (can_reach[t + 1][node][o] != can_reach_idx || can_reach_with_t1[t + 1][node][o] < ct1) && - (agent_aid.inside_poz || t > ct1)) { - can_reach[t + 1][node][o] = can_reach_idx; - can_reach_with_t1[t + 1][node][o] = ct1; - auto& new_prev = prev[t + 1][node][o]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = WAITED; - const int est_tmin = t + 1 + dmin_aid[node][o]; - if (best_node != target_node || est_tmin <= TMIN) InsertIntoHeap(h, hsize, t + 1, node, o, ct1, est_tmin); - } - - const int tarrive_node2 = t + cturns; - if (tarrive_node2 > TMIN || tarrive_node2 > T) continue; - if (!IsFreeTimeWindow(aid, t + 1, tarrive_node2 - 1, node, covered_by, is_covered, is_covered_idx, tmp_path)) continue; - - // Case 2: Move. - const auto& next_node_o = next[node][o]; - for (int onext = 0; onext <= 3; ++onext) { - const auto& node2 = next_node_o[onext]; - if (node2 >= 0 && node2 < nnodes && CanEnterCell(aid, tarrive_node2, node, node2, covered_by, is_covered, is_covered_idx, tmp_path) && - (can_reach[tarrive_node2][node2][onext] != can_reach_idx || can_reach_with_t1[tarrive_node2][node2][onext] < ct1)) { - if (OverlapsOngoingMove(t, tarrive_node2, node2, covered_by, is_covered, is_covered_idx, tmp_path, tmax_at_poz_node)) - continue; - if (node2 != target_node) { - can_reach[tarrive_node2][node2][onext] = can_reach_idx; - can_reach_with_t1[tarrive_node2][node2][onext] = ct1; - auto& new_prev = prev[tarrive_node2][node2][onext]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = STARTED_MOVING; - const int est_tmin = tarrive_node2 + dmin_aid[node2][onext]; - if (best_node != target_node || est_tmin <= TMIN) InsertIntoHeap(h, hsize, tarrive_node2, node2, onext, ct1, est_tmin); - } else { - can_reach[tarrive_node2][node2][onext] = can_reach_idx; - can_reach_with_t1[tarrive_node2][node2][onext] = ct1; - auto& new_prev = prev[tarrive_node2][node2][onext]; - new_prev.t = t; - new_prev.node = node; - new_prev.o = o; - new_prev.type = STARTED_MOVING; - if (best_node != target_node || tarrive_node2 < TMIN || (tarrive_node2 == TMIN && best_t1 < ct1)) { - TMIN = tarrive_node2; - best_node = target_node; - best_o = onext; - best_t1 = ct1; - } - } - } - } - } - - //if (agent_aid.inside_poz) assert(best_o >= 0); - if (best_o < 0) return false; - if (best_node != target_node && !agent_aid.inside_poz) { - tmp_path_aid.tmax = T; - for (int t = TINIT; t <= T; ++t) { - auto& new_path_elem = tmp_path_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - return true; - } - - //assert(best_node == target_node); - - tmp_path_aid.tmax = TMIN; - int ct = TMIN, cnode = best_node, co = best_o; - while (1) { - assert(can_reach[ct][cnode][co] == can_reach_idx); - assert(ct >= can_reach_with_t1[ct][cnode][co]); - const auto& cprev = prev[ct][cnode][co]; - if (cprev.t < 0) break; - if (cprev.type == WAITED || cprev.type == MALFUNCTIONED) { - // Wait 1 unit. - auto& new_path_elem = tmp_path_aid.p[ct]; - new_path_elem.node = cnode; - new_path_elem.o = co; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = cprev.type; - } else { - assert(cprev.type == STARTED_MOVING); - // Move cturns units. - int num_partial_turns = 0; - - for (int tmove = cprev.t; tmove < ct; ++tmove) { - auto& new_path_elem = tmp_path_aid.p[tmove + 1]; - ++num_partial_turns; - if (num_partial_turns < agent_aid.cturns) { - new_path_elem.node = cprev.node; - new_path_elem.o = cprev.o; - new_path_elem.moving_to_node = cnode; - new_path_elem.moving_to_o = co; - new_path_elem.num_partial_turns = num_partial_turns; - new_path_elem.how_i_got_here = num_partial_turns == 1 ? STARTED_MOVING : CONTINUED_MOVING; - } else { - new_path_elem.node = cnode; - new_path_elem.o = co; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = num_partial_turns == 1 ? STARTED_MOVING : CONTINUED_MOVING; - } - } - } - ct = cprev.t; - cnode = cprev.node; - co = cprev.o; - } - - if (!agent_aid.inside_poz) { - for (int t = TINIT + 1; t < ct; ++t) { - auto& new_path_elem = tmp_path_aid.p[t]; - new_path_elem.node = rnode; - new_path_elem.o = ro; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - auto& new_path_elem = tmp_path_aid.p[ct]; - new_path_elem.node = rnode; - new_path_elem.o = ro; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = ENTERED_SRC; - } else { - memcpy(&tmp_path_aid.p[TINIT], &tmp_path2->p[TINIT], (t2 - TINIT + 1) * sizeof(PathElem)); - } - - return true; -} - -bool updated_best_solution; -int rerun; - -vector<pair<int, int>> shpaths_sorted; - -void CoverPath(int aid, const Path& path, short int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - for (int t = TINIT; t <= path.tmax; ++t) { - const auto& path_elem = path.p[t]; - if (path_elem.how_i_got_here != OUTSIDE_SRC && path_elem.node != agent_aid.target_node) { - assert(is_covered[t][path_elem.node] != is_covered_idx); - is_covered[t][path_elem.node] = is_covered_idx; - covered_by[t][path_elem.node] = aid; - } - } -} - -void UncoverPath(int aid, const Path& path, short int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - for (int t = TINIT; t <= path.tmax; ++t) { - const auto& path_elem = path.p[t]; - if (path_elem.how_i_got_here != OUTSIDE_SRC && path_elem.node != agent_aid.target_node) { - assert(is_covered[t][path_elem.node] == is_covered_idx && covered_by[t][path_elem.node] == aid); - is_covered[t][path_elem.node] = 0; - } - } -} - -void CoverPath1(int aid, const Path& path, short int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz) return; - for (int t = TINIT; t <= T; ++t) { - assert(is_covered[t][agent_aid.poz_node] != is_covered_idx); - is_covered[t][agent_aid.poz_node] = is_covered_idx; - covered_by[t][agent_aid.poz_node] = aid; - } -} - -void UncoverPath1(int aid, const Path& path, short int covered_by[][MAXNODES], int is_covered[][MAXNODES], int is_covered_idx) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz) return; - for (int t = TINIT; t <= T; ++t) { - assert(is_covered[t][agent_aid.poz_node] == is_covered_idx && covered_by[t][agent_aid.poz_node] == aid); - is_covered[t][agent_aid.poz_node] = 0; - } -} - -bool RunConsistencyChecks(Path path[], const short int covered_by[][MAXNODES], const int is_covered[][MAXNODES], int is_covered_idx, bool crash_on_error = true) { - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& path_aid = path[aid]; - for (int t = TINIT + 1; t <= path_aid.tmax; ++t) { - const auto& path_elem = path_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - const auto& is_covered1 = is_covered[t][path_elem.node]; - const auto& is_covered2 = is_covered[t - 1][path_elem.node]; - const auto& aid1 = covered_by[t][path_elem.node]; - const auto& aid2 = covered_by[t - 1][path_elem.node]; - if (path_elem.node == agent_aid.target_node) { - if (is_covered1 == is_covered_idx) { - const bool ok = aid1 > aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - if (is_covered2 == is_covered_idx) { - const bool ok = aid2 < aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - } else { - Agent* agent_aid1 = is_covered1 != is_covered_idx ? nullptr : &agent[aid1]; - if (is_covered1 == is_covered_idx && aid1 != aid && agent_aid1->target_node != path_elem.node) { - DBG(0, "!!! [RunConsistencyChecks] aid=%d t=%d node=%d cov=%d how=%d\n", aid, t, path_elem.node, covered_by[t][path_elem.node], path_elem.how_i_got_here); - if (crash_on_error) exit(1); - return false; - } - - const auto& target_node_agents_node = target_node_agents[path_elem.node]; - const auto& num_target_node_agents_node = num_target_node_agents[path_elem.node]; - for (int idx = num_target_node_agents_node - 1; idx >= 0; --idx) { - const auto& aid3 = target_node_agents_node[idx]; - const auto& agent_aid3 = agent[aid3]; - if (agent_aid3.status == DONE_REMOVED) continue; - const auto& path_aid3 = path[aid3]; - bool ok = path_aid3.tmax > TINIT; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - if (path_aid3.tmax == t && path_aid3.p[t].node == path_elem.node) { - ok = aid3 < aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - if (path_aid3.tmax == t + 1 && path_aid3.p[t].node == path_elem.node) { - ok = aid3 > aid; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - } - } - - Agent* agent_aid2 = is_covered2 != is_covered_idx ? nullptr : &agent[aid2]; - if (t > TINIT && is_covered2 == is_covered_idx && aid2 > aid && agent_aid2->target_node != path_elem.node) { - DBG(0, "!!! [RunConsistencyChecks] aid=%d t=%d node=%d cov_t-1=%d(target=%d)\n", aid, t, path_elem.node, aid2, agent_aid2->target_node); - if (crash_on_error) exit(1); - return false; - } - } - - if (path_elem.num_partial_turns >= agent_aid.cturns && (path_elem.how_i_got_here == STARTED_MOVING || path_elem.how_i_got_here == CONTINUED_MOVING)) { - bool ok = path_elem.moving_to_node >= 0; - if (!ok) { - if (crash_on_error) assert(ok); - return false; - } - if ((is_covered[t][path_elem.moving_to_node] != is_covered_idx && - (is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx || - covered_by[t - 1][path_elem.moving_to_node] <= aid)) || - (is_covered[t][path_elem.moving_to_node] == is_covered_idx && - covered_by[t][path_elem.moving_to_node] >= aid && - (is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx || - covered_by[t - 1][path_elem.moving_to_node] != covered_by[t][path_elem.moving_to_node]))) { - DBG(0, "!!! [RunConsistencyChecks] Agent in motion can enter next cell, but doesn't: aid=%d t=%d node=%d->%d npt=%d/%d cov_t=%d cov_t-1=%d\n", aid, t, path_elem.node, path_elem.moving_to_node, path_elem.num_partial_turns, agent_aid.cturns, is_covered[t][path_elem.moving_to_node] != is_covered_idx ? -1 : covered_by[t][path_elem.moving_to_node], is_covered[t - 1][path_elem.moving_to_node] != is_covered_idx ? -1 : covered_by[t - 1][path_elem.moving_to_node]); - if (crash_on_error) exit(1); - return false; - } - } - } - } - return true; -} - -vector<pair<pair<int, int>, int>> tmoves[MAXNODES]; - -void CheckNonDeadlockPaths() { - return; - if (!USE_SPACING_TO_AVOID_DEADLOCKS) return; - for (int node = 0; node < nnodes; ++node) tmoves[node].clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - - int curr_node = agent_aid.poz_node; - int next_node = agent_aid.moving_to_node; - int tdeparture = TINIT, tarrival = -1; - - for (int t = TINIT + 1; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - if (next_node < 0) { - if (path_elem.node != curr_node) { - next_node = path_elem.node; - tdeparture = t - 1; - } else if (path_elem.moving_to_node >= 0) { - next_node = path_elem.moving_to_node; - tdeparture = t - 1; - } - } - if (path_elem.node == next_node) { - tarrival = t; - if (next_node != agent_aid.target_node) { - tmoves[next_node].push_back({{tarrival, tdeparture}, aid}); - } - curr_node = next_node; - next_node = -1; - } - } - } - for (int node = 0; node < nnodes; ++node) { - auto& tmoves_node = tmoves[node]; - if (tmoves_node.empty()) continue; - sort(tmoves_node.begin(), tmoves_node.end()); - int prev_tarrival = -1, prev_tdeparture = -1, prev_aid = -1; - for (const auto& tuple : tmoves_node) { - const auto& tarrival = tuple.first.first; - const auto& tdeparture = tuple.first.second; - const auto& aid = tuple.second; - if (prev_tarrival > tdeparture) { - DBG(0, "!!! [CheckNonDeadlockPaths] node=%d: aid=%d ct=%d tdep=%d tarr=%d target=%d | aid2=%d ct2=%d tdep2=%d tarr2=%d target2=%d\n", node, aid, agent[aid].cturns, tdeparture, tarrival, agent[aid].target_node, prev_aid, agent[prev_aid].cturns, prev_tdeparture, prev_tarrival, agent[prev_aid].target_node); - DBG(0, " tend_ongoing_move[node]=%d\n", tend_ongoing_move[node]); - exit(1); - } - prev_tarrival = tarrival; - prev_tdeparture = tdeparture; - prev_aid = aid; - } - } -} - -double SCORE_EXPONENT1, SCORE_EXPONENT2; -double MAX_TMAX_WEIGHT; - -#define GetScore(t) (t <= TEST ? pow(1.0 * t / TEST, SCORE_EXPONENT1) : pow(1.0 * t / TEST, SCORE_EXPONENT2)) - -/*void RandomPermutations(int tid, int ntries) { - auto& pused_tid = pused[tid]; - auto& perm_tid = perm[tid]; - auto& xor128_tid = xor128[tid]; - auto& covered_by_tid = covered_by[tid]; - auto& is_covered_tid = is_covered[tid]; - auto& is_covered_idx_tid = is_covered_idx[tid]; - auto& can_reach_tid = can_reach[tid]; - auto& can_reach_idx_tid = can_reach_idx[tid]; - auto& can_reach_with_t1_tid = can_reach_with_t1[tid]; - auto& heap_tid = heap[tid]; - auto& heap_size_tid = heap_size[tid]; - auto& prev_tid = prev[tid]; - auto& tmp_path_tid = tmp_path[tid]; - auto& tmp_path2_tid = tmp_path2[tid]; - auto& tmax_at_poz_node_tid = tmax_at_poz_node[tid]; - - if (tid == 0) { - shpaths_sorted.clear(); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - shpaths_sorted.push_back({agent_aid.malfunc + dmin[aid][agent_aid.poz_node][agent_aid.poz_o], aid}); - } - sort(shpaths_sorted.begin(), shpaths_sorted.end()); - } - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - CopyPath(ipath[aid], &tmp_path_tid[aid]); - } - - int last_trial_update = -1, last_idx_update = -1; - - for (int trial = 1; trial <= ntries; ++trial) { - if (tid == 0 && trial <= 1) { - if (trial == 2) reverse(shpaths_sorted.begin(), shpaths_sorted.end()); - for (int i = 0; i < N; ++i) perm_tid[i] = shpaths_sorted[i].second; - } else { - for (int i = 0; i < N; ++i) pused_tid[i] = 0; - int idx = 0; - if ((0&&trial & 3) >= 2) { - for (int i = 0; i < N; ++i) { - do { - perm_tid[idx] = xor128_tid.rand() % N; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } else if (0&&(trial & 3) == 1) { - for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } else { - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } - } - ++is_covered_idx_tid; - for (int aid = 0; aid < N; ++aid) { - auto& tmax_at_poz_node_tid_aid = tmax_at_poz_node_tid[aid]; - tmax_at_poz_node_tid_aid = -1; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - if (agent_aid.inside_poz) { - tmax_at_poz_node_tid_aid = TINIT; - for (int t = TINIT + 1; t <= tmp_path_tid_aid.tmax; ++t) { - const auto& path_elem = tmp_path_tid_aid.p[t]; - if (path_elem.node != agent_aid.poz_node) break; - tmax_at_poz_node_tid_aid = t; - } - } - } - for (int idx = 0; idx < N; ++idx) { - const auto& aid = perm_tid[idx]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& ipath_aid = ipath[aid]; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - UncoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - const int curr_tmax = tmp_path_tid_aid.tmax; - FindBestPath(aid, covered_by_tid, is_covered_tid, is_covered_idx_tid, can_reach_tid, can_reach_idx_tid, can_reach_with_t1_tid, heap_tid, heap_size_tid, prev_tid, tmp_path_tid, &tmp_path2_tid[aid], tmax_at_poz_node_tid); - if (tmp_path_tid_aid.tmax < curr_tmax) { - last_trial_update = trial; - last_idx_update = idx; - } - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - auto& tmax_at_poz_node_tid_aid = tmax_at_poz_node_tid[aid]; - tmax_at_poz_node_tid_aid = -1; - if (agent_aid.inside_poz) { - tmax_at_poz_node_tid_aid = TINIT; - for (int t = TINIT + 1; t <= tmp_path_tid_aid.tmax; ++t) { - const auto& path_elem = tmp_path_tid_aid.p[t]; - if (path_elem.node != agent_aid.poz_node) break; - tmax_at_poz_node_tid_aid = t; - } - } - } - } - - if (RunConsistencyChecks(tmp_path_tid, covered_by_tid, is_covered_tid, is_covered_idx_tid, false)) { - int num_done_agents = 0; - double cost = 0.0, max_tmax = 0.0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - assert(tmp_path_tid_aid.tmax > TINIT); - if (tmp_path_tid_aid.tmax > TINIT && tmp_path_tid_aid.tmax <= T && tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node == agent_aid.target_node) { - ++num_done_agents; - cost += pow(tmp_path_tid_aid.tmax, kScoreExponent); - if (tmp_path_tid_aid.tmax > max_tmax) max_tmax = tmp_path_tid_aid.tmax; - } - } - cost += max_tmax * kMaxTmaxWeight; - { - lock_guard<mutex> guard(m); - DBG(3, "[RandomPermutations] rerun=%d tid=%d ltu=%d/%d liu=%d/%d nda=%d/%d cost=%.6lf: maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, last_trial_update, ntries, last_idx_update, N - 1, num_done_agents, num_planned, cost, MAX_DONE_AGENTS, num_planned, MIN_COST, GetTime() - TSTART); - if (num_done_agents > MAX_DONE_AGENTS || (num_done_agents == MAX_DONE_AGENTS && cost < MIN_COST - 1e-6)) { - MAX_DONE_AGENTS = num_done_agents; - MIN_COST = cost; - updated_best_solution = true; - CopyTmpPathToPath(tid); - DBG(0, "[RandomPermutations] rerun=%d tid=%d ltu=%d/%d liu=%d/%d nda=%d/%d cost=%.6lf: maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, last_trial_update, ntries, last_idx_update, N - 1, num_done_agents, num_planned, cost, MAX_DONE_AGENTS, num_planned, MIN_COST, GetTime() - TSTART); - CheckNonDeadlockPaths(); - } - } - } -} -*/ - -void RandomPermutations(int tid, int ntries) { - auto& pused_tid = pused[tid]; - auto& perm_tid = perm[tid]; - auto& xor128_tid = xor128[tid]; - auto& covered_by_tid = covered_by[tid]; - auto& is_covered_tid = is_covered[tid]; - auto& is_covered_idx_tid = is_covered_idx[tid]; - auto& can_reach_tid = can_reach[tid]; - auto& can_reach_idx_tid = can_reach_idx[tid]; - auto& can_reach_with_t1_tid = can_reach_with_t1[tid]; - auto& heap_tid = heap[tid]; - auto& heap_size_tid = heap_size[tid]; - auto& prev_tid = prev[tid]; - auto& tmp_path_tid = tmp_path[tid]; - auto& tmp_path2_tid = tmp_path2[tid]; - auto& tmax_at_poz_node_tid = tmax_at_poz_node[tid]; - - if (tid == 0) { - shpaths_sorted.resize(N); - for (int aid = 0; aid < N; ++aid) { - shpaths_sorted[aid].second = aid; - const auto& agent_aid = agent[aid]; - shpaths_sorted[aid].first = agent_aid.malfunc + dmin[aid][agent_aid.poz_node][agent_aid.poz_o]; - } - sort(shpaths_sorted.begin(), shpaths_sorted.end()); - } - - for (int trial = 1; trial <= ntries; ++trial) { - if (tid == 0 && trial <= 1) { - for (int i = 0; i < N; ++i) perm_tid[i] = shpaths_sorted[i].second; - reverse(shpaths_sorted.begin(), shpaths_sorted.end()); - } else { - for (int i = 0; i < N; ++i) pused_tid[i] = 0; - int idx = 0; - if (0&&(trial & 1) == 1) { - for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } else { - for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) { - const auto& cturns_agents_cturns = cturns_agents[cturns]; - const auto& num_cturns_agents_cturns = num_cturns_agents[cturns]; - for (int i = 0; i < num_cturns_agents_cturns; ++i) { - do { - perm_tid[idx] = cturns_agents_cturns[xor128_tid.rand() % num_cturns_agents_cturns]; - } while (pused_tid[perm_tid[idx]]); - pused_tid[perm_tid[idx++]] = 1; - } - } - } - } - ++is_covered_idx_tid; - for (int aid = 0; aid < N; ++aid) { - auto& tmax_at_poz_node_tid_aid = tmax_at_poz_node_tid[aid]; - tmax_at_poz_node_tid_aid = -1; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - CopyPath(ipath[aid], &tmp_path_tid_aid); - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - if (agent_aid.inside_poz) { - tmax_at_poz_node_tid_aid = TINIT; - for (int t = TINIT + 1; t <= tmp_path_tid_aid.tmax; ++t) { - const auto& path_elem = tmp_path_tid_aid.p[t]; - if (path_elem.node != agent_aid.poz_node) break; - tmax_at_poz_node_tid_aid = t; - } - } - } - bool inconsistent = false; - for (int idx = 0; idx < N; ++idx) { - const auto& aid = perm_tid[idx]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - auto& tmp_path_tid_aid = tmp_path_tid[aid]; - UncoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - if (!FindBestPath(aid, covered_by_tid, is_covered_tid, is_covered_idx_tid, can_reach_tid, can_reach_idx_tid, can_reach_with_t1_tid, heap_tid, heap_size_tid, prev_tid, tmp_path_tid, &tmp_path2_tid[aid], tmax_at_poz_node_tid)) { - //inconsistent = true; - //break; - } - CoverPath(aid, tmp_path_tid_aid, covered_by_tid, is_covered_tid, is_covered_idx_tid); - } - if (!inconsistent && RunConsistencyChecks(tmp_path_tid, covered_by_tid, is_covered_tid, is_covered_idx_tid, false)) { - int num_done_agents = 0; - double cost = 0.0; - int max_tmax = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& tmp_path_tid_aid = tmp_path_tid[aid]; - assert(tmp_path_tid_aid.tmax > TINIT); - if (tmp_path_tid_aid.tmax > TINIT && tmp_path_tid_aid.tmax <= T && tmp_path_tid_aid.p[tmp_path_tid_aid.tmax].node == agent_aid.target_node) { - ++num_done_agents; - cost += GetScore(tmp_path_tid_aid.tmax); - if (tmp_path_tid_aid.tmax > max_tmax) max_tmax = tmp_path_tid_aid.tmax; - } - } - if (num_done_agents >= 1) cost /= num_done_agents; - - { - lock_guard<mutex> guard(m); - if (num_done_agents > MAX_DONE_AGENTS || (num_done_agents == MAX_DONE_AGENTS && cost < MIN_COST - 1e-6)) { - MAX_DONE_AGENTS = num_done_agents; - MIN_COST = cost; - updated_best_solution = true; - CopyTmpPathToPath(tid); - DBG(0, "[RandomPermutations] rerun=%d tid=%d trial=%d/%d maxda=%d/%d minc=%.6lf time=%.3lf\n", rerun, tid, trial, ntries, MAX_DONE_AGENTS, num_planned, MIN_COST, GetTime() - TSTART); - } - } - } - } -} - -bool any_best_solution_updates; - -void RegenerateFullPlan() { - ++num_reschedules; - any_best_solution_updates = false; - updated_best_solution = true; - rerun = 0; - - const int kMaxReruns = 4;//2; - - while (updated_best_solution && rerun < kMaxReruns) { - updated_best_solution = false; - ++rerun; - - for (int node = 0; node < nnodes; ++node) tend_ongoing_move[node] = TINIT; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (!agent_aid.inside_poz || agent_aid.status == DONE_REMOVED) continue; - if (agent_aid.moving_to_node >= 0) { - const auto& ipath_aid = ipath[aid]; - const auto& first_path_elem = ipath_aid.p[TINIT]; - assert(ipath_aid.tmax >= TINIT); - tend_ongoing_move[agent_aid.moving_to_node] = TINIT + agent_aid.malfunc + max(0, agent_aid.cturns - first_path_elem.num_partial_turns); - } - } - - int max_threads = thread::hardware_concurrency(); - if (max_threads > MAX_NUM_THREADS) max_threads = MAX_NUM_THREADS; - DBG(2, "max_threads=%d\n", max_threads); - - if (N >= 2) { - thread** th = nullptr; - if (max_threads >= 2) th = new thread*[max_threads - 1]; - - // Random Permutations. - const int kNumRandomPermutations = TINIT == 0 ? 20 /*10*/ : 12 /*6*/; - if (max_threads >= 2) { - for (int tid = 0; tid + 1 < max_threads; ++tid) th[tid] = new thread([tid, kNumRandomPermutations]{ - RandomPermutations(tid, kNumRandomPermutations); - }); - } - RandomPermutations(max_threads - 1, kNumRandomPermutations); - if (max_threads >= 2) { - for (int tid = 0; tid + 1 < max_threads; ++tid) { - auto& th_tid = th[tid]; - th_tid->join(); - delete th_tid; - } - delete th; - } - } else RandomPermutations(0, 1); - - if (updated_best_solution) { - for (int aid = 0; aid < N; ++aid) CopyPath(path[aid], &ipath[aid]); - any_best_solution_updates = true; - } - } - - if (any_best_solution_updates) RecomputeCheckpoints(); -} - -int nodecnt[MAXNODES], nodecnt_marked[MAXNODES], nodecnt_marked_idx; -char is_free[MAXNODES]; - -int next_aidx[NMAX], next_vidx[MAXNODES]; - -void SwapVisitingOrder(int aid1, int idx1, int aid2) { - const auto& checkpoints_aid1 = checkpoints[aid1]; - const auto& checkpoints_aid2 = checkpoints[aid2]; - const int node = checkpoints_aid1[idx1]; - int idx2 = next_aidx[aid2] - 1; - while (idx2 >= 0 && checkpoints_aid2[idx2] != node) --idx2; - assert(idx2 >= 0); - const auto& num_checkpoints_aid1 = num_checkpoints[aid1]; - const auto& num_checkpoints_aid2 = num_checkpoints[aid2]; - const auto& checkpoints_cnt_aid1 = checkpoints_cnt[aid1]; - const auto& checkpoints_cnt_aid2 = checkpoints_cnt[aid2]; - - int num_swaps = 0; - while (idx1 < num_checkpoints_aid1 && idx2 < num_checkpoints_aid2 && checkpoints_aid1[idx1] == checkpoints_aid2[idx2]) { - int vidx1 = -1, cnt1 = 0, vidx2 = -1, cnt2 = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[checkpoints_aid1[idx1]]; - for (int idx = 0; idx < ipath_visiting_order_node.size() && (vidx1 < 0 || vidx2 < 0); ++idx) { - const auto& elem_pair = ipath_visiting_order_node[idx]; - if (elem_pair.second == aid1) { - ++cnt1; - if (cnt1 == checkpoints_cnt_aid1[idx1]) vidx1 = idx; - } - if (elem_pair.second == aid2) { - ++cnt2; - if (cnt2 == checkpoints_cnt_aid2[idx2]) vidx2 = idx; - } - } - assert(vidx1 >= 0 && vidx2 >= 0); - assert(vidx1 > vidx2); - ipath_visiting_order_node[vidx1].second = aid2; - ipath_visiting_order_node[vidx2].second = aid1; - ++idx1; - ++idx2; - ++num_swaps; - } - - /*for (int node = 0; node < nnodes; ++node) { - int vidx1 = -1, cnt1 = 0, vidx2 = -1, cnt2 = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - for (int idx = 0; idx < ipath_visiting_order_node.size() && (vidx1 < 0 || vidx2 < 0); ++idx) { - const auto& elem_pair = ipath_visiting_order_node[idx]; - if (elem_pair.second == aid1) vidx1 = idx; - if (elem_pair.second == aid2) vidx2 = idx; - } - if (vidx1 >= 0 && vidx2 >= 0) { - ipath_visiting_order_node[vidx1].second = aid2; - ipath_visiting_order_node[vidx2].second = aid1; - ++num_swaps; - } - }*/ - - DBG(2, "[SwapVisitingOrder] aid1=%d aid2=%d idx1=%d num_swaps=%d\n", aid1, aid2, idx1, num_swaps); - - //exit(1); -} - -#define QMOD 255 -int qaid[QMOD + 1]; - -bool AdjustIPaths() { - /*for (int aid = 0; aid < N; ++aid) { - if (aid == 46) { - const auto& ipath_aid = ipath[aid]; - for (int t = max(TINIT, 795); t <= 805 && t <= ipath_aid.tmax; ++t) { - const auto& elem = ipath_aid.p[t]; - DBG(0, "aid=%d t=%d node=%d npt=%d\n", aid, t, elem.node, elem.num_partial_turns); - } - } - }*/ - - ++num_adjust_ipaths; - - nodecnt_marked_idx = 0; - for (int node = 0; node < nnodes; ++node) { - ipath_visiting_order[node].clear(); - nodecnt_marked[node] = 0; - } - - int max_tmax = 0; - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - auto& path_aid = path[aid]; - if (agent_aid.status == DONE_REMOVED) { - CopyPath(ipath_aid, &path_aid); - continue; - } - - if (ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node && ipath_aid.tmax > max_tmax) max_tmax = ipath_aid.tmax; - - auto& new_path_elem = path_aid.p[TINIT]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.num_partial_turns = 0; - while (fabs(agent_aid.poz_frac - new_path_elem.num_partial_turns * agent_aid.speed) >= ZERO) - ++new_path_elem.num_partial_turns; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - if (agent_aid.inside_poz) { - const auto& first_expected_step = ipath_aid.p[TINIT]; - if (new_path_elem.num_partial_turns >= 1) { - if (first_expected_step.num_partial_turns >= 1) { - if (agent_aid.fresh_malfunc) - assert(first_expected_step.num_partial_turns >= new_path_elem.num_partial_turns); - assert(first_expected_step.node == agent_aid.poz_node); - assert(first_expected_step.o == agent_aid.poz_o); - new_path_elem.moving_to_node = first_expected_step.moving_to_node; - new_path_elem.moving_to_o = first_expected_step.moving_to_o; - assert(0 <= new_path_elem.moving_to_node && new_path_elem.moving_to_node < nnodes); - assert(0 <= new_path_elem.moving_to_o && new_path_elem.moving_to_o < nnodes); - } else { - assert(new_path_elem.num_partial_turns >= agent_aid.cturns - 1); - assert(first_expected_step.node != agent_aid.poz_node || first_expected_step.o != agent_aid.poz_o); - assert(first_expected_step.moving_to_node < 0); - assert(first_expected_step.moving_to_o < 0); - new_path_elem.moving_to_node = first_expected_step.node; - new_path_elem.moving_to_o = first_expected_step.o; - } - } - if (agent_aid.fresh_malfunc) new_path_elem.how_i_got_here = MALFUNCTIONED; - else new_path_elem.how_i_got_here = first_expected_step.how_i_got_here; - } else new_path_elem.how_i_got_here = OUTSIDE_SRC; - - const int tmin = TINIT + max(0, agent_aid.malfunc - (agent_aid.inside_poz ? 0 : 1)); - for (int t = TINIT + 1; t <= tmin && t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = agent_aid.inside_poz ? MALFUNCTIONED : OUTSIDE_SRC; - } - - const auto& next_checkpoint_aid = next_checkpoint[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - - if (next_checkpoint_aid == num_checkpoints_aid) { - assert(!agent_aid.inside_poz); - continue; - } - - assert(1 <= next_checkpoint_aid && next_checkpoint_aid < num_checkpoints_aid); - - auto& tcheckpoints_aid = tcheckpoints[aid]; - tcheckpoints_aid[next_checkpoint_aid - 1] = path_aid.tmax = tmin; - - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& checkpoints_cnt_aid = checkpoints_cnt[aid]; - - ++nodecnt_marked_idx; - - if (agent_aid.inside_poz) { - nodecnt_marked[agent_aid.poz_node] = nodecnt_marked_idx; - nodecnt[agent_aid.poz_node] = checkpoints_cnt_aid[next_checkpoint_aid - 1] = 1; - assert(checkpoints_aid[next_checkpoint_aid - 1] == agent_aid.poz_node); - } - - for (int cid = next_checkpoint_aid; cid < num_checkpoints_aid; ++cid) { - const auto& node = checkpoints_aid[cid]; - if (nodecnt_marked[node] != nodecnt_marked_idx) { - nodecnt_marked[node] = nodecnt_marked_idx; - nodecnt[node] = 0; - } - checkpoints_cnt_aid[cid] = ++nodecnt[node]; - } - } - - RepopulateVisitingOrders(); - - auto& is_covered_0 = is_covered[0]; - auto& is_covered_idx_0 = is_covered_idx[0]; - auto& covered_by_0 = covered_by[0]; - - bool updated_visiting_order = true; - int nelems = 0; - - while (updated_visiting_order) { - updated_visiting_order = false; - ++is_covered_idx_0; - - for (int node = 0; node < nnodes; ++node) is_free[node] = 1; - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - next_aidx[aid] = next_checkpoint[aid]; - auto& path_aid = path[aid]; - const int tmin = TINIT + max(0, agent_aid.malfunc - (agent_aid.inside_poz ? /*1*/ 0 : /*2*/ 1)); - for (int t = TINIT + 1; t <= tmin && t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = agent_aid.inside_poz ? MALFUNCTIONED : OUTSIDE_SRC; - if (agent_aid.inside_poz) { - assert(is_covered_0[t][new_path_elem.node] != is_covered_idx_0); - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - } - } - - path_aid.tmax = tmin; - - if (agent_aid.inside_poz) { - is_free[agent_aid.poz_node] = 0; - is_covered_0[TINIT][agent_aid.poz_node] = is_covered_idx_0; - covered_by_0[TINIT][agent_aid.poz_node] = aid; - } - } - - int qli = 0, qls = 0; - - for (int node = 0; node < nnodes; ++node) { - next_vidx[node] = 0; - auto& ipath_visiting_order_node = ipath_visiting_order[node]; - if (ipath_visiting_order_node.empty()) continue; - for (auto& elem_pair : ipath_visiting_order_node) elem_pair.first = TINIT; - const auto& aid_0 = ipath_visiting_order_node[0].second; - if (is_free[node] && checkpoints[aid_0][next_aidx[aid_0]] == node) { - qaid[qls] = aid_0; - qls = (qls + 1) & QMOD; - } - } - - nelems = 0; - - int tmin_incomplete = -1, aid_incomplete = -1; - - while (qli != qls) { - ++nelems; - - const auto& aid = qaid[qli]; - const auto& agent_aid = agent[aid]; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - auto& tcheckpoints_aid = tcheckpoints[aid]; - auto& next_aidx_aid = next_aidx[aid]; - const auto& next_checkpoint_aid = next_checkpoint[aid]; - assert(next_checkpoint_aid <= next_aidx_aid && next_aidx_aid < num_checkpoints[aid]); - const auto& curr_node = checkpoints_aid[next_aidx_aid - 1]; - const auto& next_node = checkpoints_aid[next_aidx_aid]; - - qli = (qli + 1) & QMOD; - - assert(0 <= next_node && next_node < nnodes); - assert(is_free[next_node]); - if (curr_node >= 0) assert(!is_free[curr_node]); - - const auto& t_curr_node = tcheckpoints_aid[next_aidx_aid - 1]; - const auto& next_o = checkpoints_o_aid[next_aidx_aid]; - - auto& next_vidx_next_node = next_vidx[next_node]; - auto& ipath_visiting_order_next_node = ipath_visiting_order[next_node]; - assert(next_vidx_next_node < ipath_visiting_order_next_node.size()); - assert(ipath_visiting_order_next_node[next_vidx_next_node].second == aid); - - int tend_move = ipath_visiting_order_next_node[next_vidx_next_node].first; - - //const bool print_debug = (aid == 76 || aid == 24) && (curr_node == 117 || next_node == 117); - const bool print_debug = false; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-A] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tend_move=%d(init) \n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tend_move); - - auto& path_aid = path[aid]; - - if (next_aidx_aid > next_checkpoint_aid && path_aid.tmax <= T) assert(path_aid.p[path_aid.tmax].num_partial_turns == 0); - - const int move_duration = max(1, curr_node < 0 ? 1 : (next_aidx_aid == next_checkpoint_aid ? agent_aid.cturns - path_aid.p[TINIT].num_partial_turns : agent_aid.cturns)); - int tstart_move = tend_move - move_duration; - if (tstart_move < t_curr_node) tstart_move = t_curr_node; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-B] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tstart_move=%d tend_move=%d move_duration=%d\n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tstart_move, tend_move, move_duration); - - assert(path_aid.tmax == t_curr_node); - if (t_curr_node <= T && curr_node >= 0) assert(path_aid.p[t_curr_node].node == curr_node); - int t = t_curr_node + 1; - - tend_move = tstart_move + move_duration; - - if (!agent_aid.inside_poz && next_aidx_aid == next_checkpoint_aid) { - for (; t <= tstart_move; ++t) { - assert(path_aid.tmax == t - 1); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - } - assert(t == tend_move); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = ENTERED_SRC; - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - assert(t == tend_move); - } - ++t; - } - - if (curr_node >= 0) { - if (path_aid.p[TINIT].num_partial_turns >= 1) assert(agent_aid.moving_to_node >= 0); - if (next_aidx_aid > next_checkpoint_aid || /*path_aid.p[TINIT].num_partial_turns == 0*/ agent_aid.moving_to_node < 0) { - for (; t <= tstart_move; ++t) { - assert(path_aid.tmax == t - 1); - path_aid.tmax = t; - if (t <= T) { - auto& new_path_elem = path_aid.p[t]; - memcpy(&new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - new_path_elem.how_i_got_here = WAITED; - assert(new_path_elem.num_partial_turns == 0); - is_covered_0[t][new_path_elem.node] = is_covered_idx_0; - covered_by_0[t][new_path_elem.node] = aid; - } - } - } - int num_partial_turns = next_aidx_aid > next_checkpoint_aid ? 0 : path_aid.p[TINIT].num_partial_turns; - for (; 1; ++t) { - assert(path_aid.tmax == t - 1); - assert(t > TINIT); - path_aid.tmax = t; - PathElem* new_path_elem = nullptr; - if (t <= T) new_path_elem = &path_aid.p[t]; - if (new_path_elem != nullptr) memcpy(new_path_elem, &path_aid.p[t - 1], sizeof(PathElem)); - ++num_partial_turns; - if (print_debug) DBG(0, " aid=%d t=%d/%d npt=%d\n", aid, t, tend_move, num_partial_turns); - if (new_path_elem != nullptr) { - new_path_elem->num_partial_turns = num_partial_turns; - if (new_path_elem->num_partial_turns == 1) new_path_elem->how_i_got_here = STARTED_MOVING; - else new_path_elem->how_i_got_here = CONTINUED_MOVING; - new_path_elem->moving_to_node = next_node; - new_path_elem->moving_to_o = next_o; - if (new_path_elem->num_partial_turns >= 2) { - if (print_debug) DBG(0, " prev_moving_to=(%d %d)\n", path_aid.p[t - 1].moving_to_node, path_aid.p[t - 1].moving_to_o); - assert(path_aid.p[t - 1].moving_to_node == next_node); - assert(path_aid.p[t - 1].moving_to_o == next_o); - } - } - if (num_partial_turns >= agent_aid.cturns) { - if (t >= tend_move) { - if (new_path_elem != nullptr) { - new_path_elem->node = next_node; - new_path_elem->o = next_o; - new_path_elem->moving_to_node = new_path_elem->moving_to_o = -1; - new_path_elem->num_partial_turns = 0; - if (new_path_elem->node != agent_aid.target_node) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - } - } - tend_move = t; - ++t; - break; - } else if (new_path_elem != nullptr) { - if (print_debug) DBG(0, " >>> is_cov_next_node=%d cov_by=%d\n", is_covered_0[t][next_node] == is_covered_idx_0, covered_by_0[t][next_node]); - if ((is_covered_0[t][next_node] != is_covered_idx_0 && - (is_covered_0[t - 1][next_node] != is_covered_idx_0 || - covered_by_0[t - 1][next_node] < aid)) || - (is_covered_0[t][next_node] == is_covered_idx_0 && covered_by_0[t][next_node] > aid && - (is_covered_0[t - 1][next_node] != is_covered_idx_0 || - covered_by_0[t - 1][next_node] != covered_by_0[t][next_node]))) { - DBG(0, "||| [AdjustIPaths] Agent in motion cannot wait for delayed agent: aid=%d next_aidx_aid=%d nextcp=%d tend=%d t=%d curr_node=%d:(%d %d) next_node=%d:(%d %d) next_vidx_next_node=%d target_node=%d:(%d %d) nelems=%d\n", aid, next_aidx_aid, next_checkpoint[aid], tend_move, t, curr_node, node[curr_node].row, node[curr_node].col, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, agent_aid.target_node, node[agent_aid.target_node].row, node[agent_aid.target_node].col, nelems); - assert(next_vidx_next_node >= 1); - const int prev_aid = ipath_visiting_order_next_node[next_vidx_next_node - 1].second; - DBG(0, " prev_aid=%d\n", prev_aid); - SwapVisitingOrder(aid, next_aidx_aid, prev_aid); - updated_visiting_order = true; - break; - } - if (new_path_elem->node != agent_aid.target_node) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - } - } - } else if (new_path_elem != nullptr) { - is_covered_0[t][new_path_elem->node] = is_covered_idx_0; - covered_by_0[t][new_path_elem->node] = aid; - assert(num_partial_turns >= 1); - assert(0 <= new_path_elem->moving_to_node && new_path_elem->moving_to_node < nnodes); - } - } - } - - if (updated_visiting_order) break; - - if (print_debug) DBG(0, "\n[AdjustIPaths-Debug-C] aid=%d next_aidx_aid=%d next_node=%d:(%d %d) next_vidx_next_node=%d curr_node=%d:(%d %d) t_curr_node=%d tstart_move=%d tend_move=%d move_duration=%d\n", aid, next_aidx_aid, next_node, node[next_node].row, node[next_node].col, next_vidx_next_node, curr_node, node[curr_node].row, node[curr_node].col, t_curr_node, tstart_move, tend_move, move_duration); - - if (t != tend_move + 1) { - DBG(0, "!!!A aid=%d next_aidx_aid=%d curr_node=%d curr_npt=%d curr_how=%d next_node=%d tstart_move=%d tend_move=%d t=%d: last_path_elem=(node=%d npt=%d/%d how=%d)\n", aid, next_aidx_aid, curr_node, path_aid.p[t_curr_node].num_partial_turns, path_aid.p[t_curr_node].how_i_got_here, next_node, tstart_move, tend_move, t, path_aid.p[path_aid.tmax].node, path_aid.p[path_aid.tmax].num_partial_turns, agent_aid.cturns, path_aid.p[path_aid.tmax].how_i_got_here); - exit(1); - } - - assert(path_aid.tmax == tend_move); - if (tend_move <= T && path_aid.p[tend_move].node != next_node) { - DBG(0, "!!!B aid=%d next_aidx_aid=%d curr_node=%d curr_npt=%d curr_how=%d next_node=%d tstart_move=%d tend_move=%d: last_path_elem=(node=%d npt=%d/%d how=%d)\n", aid, next_aidx_aid, curr_node, path_aid.p[t_curr_node].num_partial_turns, path_aid.p[t_curr_node].how_i_got_here, next_node, tstart_move, tend_move, path_aid.p[path_aid.tmax].node, path_aid.p[path_aid.tmax].num_partial_turns, agent_aid.cturns, path_aid.p[path_aid.tmax].how_i_got_here); - exit(1); - } - - tcheckpoints_aid[next_aidx_aid] = tend_move; - if (curr_node >= 0) is_free[curr_node] = 1; - is_free[next_node] = 0; - ++next_aidx_aid; - ++next_vidx_next_node; - - if (next_aidx_aid < num_checkpoints[aid]) { - const auto& next2_node = checkpoints_aid[next_aidx_aid]; - auto& next_vidx2_next2_node = next_vidx[next2_node]; - auto& ipath_visiting_order_next2_node = ipath_visiting_order[next2_node]; - if (next2_node != curr_node && ipath_visiting_order_next2_node[next_vidx2_next2_node].second == aid && is_free[next2_node]) { - qaid[qls] = aid; - qls = (qls + 1) & QMOD; - } - } else if (next_node == agent_aid.target_node) { - // Free up next_node right away. - is_free[next_node] = 1; - if (next_vidx_next_node < ipath_visiting_order_next_node.size()) { - const auto& aid1 = ipath_visiting_order_next_node[next_vidx_next_node].second; - const auto& path_aid1 = path[aid1]; - const auto& last_path_elem = path_aid1.p[path_aid1.tmax]; - int tend_move_aid1 = tend_move + (aid1 < aid && agent[aid1].target_node != next_node ? 1 : 0); - const auto& agent_aid1 = agent[aid1]; - if (USE_SPACING_TO_AVOID_DEADLOCKS && last_path_elem.num_partial_turns == 0 && (next_aidx[aid1] > next_checkpoint[aid1] || agent[aid1].moving_to_node < 0)) { - const int min_tstart = tend_move;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? tend_move : t_curr_node; - assert(t_curr_node < tend_move); - if (tend_move_aid1 - agent_aid1.cturns < min_tstart) tend_move_aid1 = min_tstart + agent_aid1.cturns; - } - ipath_visiting_order_next_node[next_vidx_next_node].first = tend_move_aid1; - if (checkpoints[aid1][next_aidx[aid1]] == next_node) { - qaid[qls] = aid1; - qls = (qls + 1) & QMOD; - } - } - } - - if (curr_node >= 0) { - const auto& next_vidx_curr_node = next_vidx[curr_node]; - auto& ipath_visiting_order_curr_node = ipath_visiting_order[curr_node]; - if (next_vidx_curr_node < ipath_visiting_order_curr_node.size()) { - const auto& aid1 = ipath_visiting_order_curr_node[next_vidx_curr_node].second; - const auto& path_aid1 = path[aid1]; - const auto& last_path_elem = path_aid1.p[path_aid1.tmax]; - int tend_move_aid1 = tend_move + (aid1 < aid ? 1 : 0); - const auto& agent_aid1 = agent[aid1]; - if (USE_SPACING_TO_AVOID_DEADLOCKS && last_path_elem.num_partial_turns == 0 && (next_aidx[aid1] > next_checkpoint[aid1] || agent[aid1].moving_to_node < 0)) { - const int min_tstart = t_curr_node;//USE_STRICT_SPACING_TO_AVOID_DEADLOCKS ? tend_move : t_curr_node; - assert(t_curr_node < tend_move); - if (tend_move_aid1 - agent_aid1.cturns < min_tstart) tend_move_aid1 = min_tstart + agent_aid1.cturns; - } - ipath_visiting_order_curr_node[next_vidx_curr_node].first = tend_move_aid1; - if (checkpoints[aid1][next_aidx[aid1]] == curr_node) { - qaid[qls] = aid1; - qls = (qls + 1) & QMOD; - } - } - } - } - - DBG(2, "[AdjustIPaths] nelems=%d updvis=%d\n", nelems, updated_visiting_order); - if (updated_visiting_order) continue; - - if (aid_incomplete < 0) { - for (int node = 0; node < nnodes; ++node) { - const auto& next_vidx_node = next_vidx[node]; - const auto& ipath_visiting_order_node = ipath_visiting_order[node]; - if (next_vidx_node < ipath_visiting_order_node.size()) { - const auto& aid = ipath_visiting_order_node[next_vidx_node].second; - const auto& next_aidx_aid = next_aidx[aid]; - DBG(0, "[AdjustIPaths] incomplete: node=%d is_free=%d next_vidx=%d/%d: aid=%d next_aidx_aid=%d/%d:node=%d/t=%d nextcp=%d\n", node, is_free[node], next_vidx_node, ipath_visiting_order_node.size(), aid, next_aidx_aid, num_checkpoints[aid], checkpoints[aid][next_aidx_aid], checkpoints_t[aid][next_aidx_aid], next_checkpoint[aid]); - assert(next_aidx_aid < num_checkpoints[aid]); - assert(!is_free[node] || checkpoints[aid][next_aidx_aid] != node); - const auto& t_inc = max(ipath_visiting_order_node[next_vidx_node].first, tcheckpoints[aid][next_aidx_aid - 1]); - if (aid_incomplete < 0 || t_inc < tmin_incomplete) { - aid_incomplete = aid; - tmin_incomplete = t_inc; - } - } - } - - assert(aid_incomplete < 0); - } - } - - ++is_covered_idx_0; - - for (int aid = 0; aid < N; ++aid) { - auto& ipath_aid = ipath[aid]; - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - - const auto& num_checkpoints_aid = num_checkpoints[aid]; - const auto& checkpoints_aid = checkpoints[aid]; - const auto& tcheckpoints_aid = tcheckpoints[aid]; - const auto& next_aidx_aid = next_aidx[aid]; - - if (next_aidx_aid < num_checkpoints_aid) { - const auto& v = checkpoints_aid[next_aidx_aid]; - const auto& ipath_visiting_order_v = ipath_visiting_order[v]; - const auto& next_vidx_v = next_vidx[v]; - assert(next_vidx_v < ipath_visiting_order_v.size()); - DBG(0, "!!! [AdjustIPaths] aid=%d next_aidx_aid=%d/%d: v=%d(%d) next_vidx_v=%d/%d: t=%d vaid=%d\n", aid, next_aidx_aid, num_checkpoints_aid, v, is_free[v], next_vidx_v, ipath_visiting_order_v.size(), ipath_visiting_order_v[next_vidx_v].first, ipath_visiting_order_v[next_vidx_v].second); - exit(1); - } - - // Construct the path. - auto& path_aid = path[aid]; - if (path_aid.tmax > T) path_aid.tmax = T; - - if (path_aid.p[path_aid.tmax].how_i_got_here == OUTSIDE_SRC) { - for (int t = path_aid.tmax + 1; t <= T; ++t) { - auto& new_path_elem = path_aid.p[t]; - new_path_elem.node = agent_aid.poz_node; - new_path_elem.o = agent_aid.poz_o; - new_path_elem.moving_to_node = new_path_elem.moving_to_o = -1; - new_path_elem.num_partial_turns = 0; - new_path_elem.how_i_got_here = OUTSIDE_SRC; - } - path_aid.tmax = T; - } else if (path_aid.tmax < T && path_aid.p[path_aid.tmax].node != agent_aid.target_node) { - const auto& last_num_partial_turns = path_aid.p[path_aid.tmax].num_partial_turns; - const auto& last_how_i_got_here = path_aid.p[path_aid.tmax].how_i_got_here; - DBG(3, "!!! [AdjustIPaths] aid=%d next_aidx_aid=%d/%d tmax=%d/%d last_node=%d:(%d %d) npt=%d/%d target_node=%d:(%d %d)\n", aid, next_aidx[aid], num_checkpoints[aid], path_aid.tmax, T, path_aid.p[path_aid.tmax].node, node[path_aid.p[path_aid.tmax].node].row, node[path_aid.p[path_aid.tmax].node].col, last_num_partial_turns, agent_aid.cturns, agent_aid.target_node, node[agent_aid.target_node].row, node[agent_aid.target_node].col); - while (path_aid.tmax < T) { - ++path_aid.tmax; - auto& new_path_elem = path_aid.p[path_aid.tmax]; - memcpy(&new_path_elem, &path_aid.p[path_aid.tmax - 1], sizeof(PathElem)); - if (last_num_partial_turns == 0) - new_path_elem.how_i_got_here = last_how_i_got_here == OUTSIDE_SRC ? OUTSIDE_SRC : WAITED; - else { - ++new_path_elem.num_partial_turns; - new_path_elem.how_i_got_here = CONTINUED_MOVING; - } - } - } - - assert(path_aid.tmax <= T); - for (int t = TINIT; t <= path_aid.tmax; ++t) { - const auto& path_elem = path_aid.p[t]; - if (path_elem.how_i_got_here == OUTSIDE_SRC) continue; - if (path_elem.node == agent_aid.target_node) { - assert(t == path_aid.tmax); - continue; - } - assert(0 <= path_elem.node && path_elem.node < nnodes); - if (is_covered_0[t][path_elem.node] == is_covered_idx_0) { - DBG(0, "!!! [AdjustIPaths] aid=%d t=%d node=%d already covered by %d\n", aid, t, path_elem.node, covered_by_0[t][path_elem.node]); - exit(1); - } - is_covered_0[t][path_elem.node] = is_covered_idx_0; - covered_by_0[t][path_elem.node] = aid; - } - - if (path_aid.tmax != ipath_aid.tmax || path_aid.p[path_aid.tmax].node != ipath_aid.p[path_aid.tmax].node) { - DBG(3, "[AdjustIPaths] aid=%d diff: prev:(tmax=%d node=%d) curr:(tmax=%d node=%d)\n", aid, path_aid.tmax, path_aid.p[path_aid.tmax].node, ipath_aid.tmax, ipath_aid.p[ipath_aid.tmax].node); - } - - CopyPath(path_aid, &ipath_aid); - } - - RunConsistencyChecks(path, covered_by_0, is_covered_0, is_covered_idx_0); - - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - auto& checkpoints_t_aid = checkpoints_t[aid]; - const auto& tcheckpoints_aid = tcheckpoints[aid]; - const auto& num_checkpoints_aid = num_checkpoints[aid]; - for (int cid = next_checkpoint[aid]; cid < num_checkpoints_aid; ++cid) - checkpoints_t_aid[cid] = tcheckpoints_aid[cid]; - } - - MAX_DONE_AGENTS = 0; - MIN_COST = 0.0; - int new_max_tmax = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - if (agent_aid.status == DONE_REMOVED) continue; - const auto& path_aid = path[aid]; - assert(path_aid.tmax > TINIT); - if (path_aid.p[path_aid.tmax].node == agent_aid.target_node) { - ++MAX_DONE_AGENTS; - MIN_COST += GetScore(path_aid.tmax); - if (path_aid.tmax > new_max_tmax) new_max_tmax = path_aid.tmax; - } else { - assert(path_aid.tmax == T); - } - } - if (MAX_DONE_AGENTS >= 1) MIN_COST /= MAX_DONE_AGENTS; - - const bool changed_important_data = MAX_DONE_AGENTS != num_planned || new_max_tmax > max_tmax; - if (changed_important_data) { - DBG(0, ">>> [AdjustIPaths] mda=%d/%d minc=%.6lf new_max_tmax=%d/%d\n", MAX_DONE_AGENTS, num_planned, MIN_COST, new_max_tmax, max_tmax); - } - - CheckNonDeadlockPaths(); - - return !changed_important_data; -} - -void ReinitDataStructures() { - MAX_DONE_AGENTS = 0; - MIN_COST = 1e10; - for (int aid = 0; aid < N; ++aid) path[aid].tmax = -1000; - xor128[0].reset(14012019U); - for (int tid = 1; tid < MAX_NUM_THREADS; ++tid) xor128[tid].reset(19999997U * tid + 29997U); - for (int tid = 0; tid < MAX_NUM_THREADS; ++tid) { - can_reach_idx[tid] = is_covered_idx[tid] = 0; - auto& can_reach_tid = can_reach[tid]; - auto& is_covered_tid = is_covered[tid]; - for (int t = 0; t <= T + 2; ++t) { - auto& can_reach_tid_t = can_reach_tid[t]; - auto& is_covered_tid_t = is_covered_tid[t]; - for (int i = 0; i < nnodes; ++i) { - is_covered_tid_t[i] = 0; - auto& can_reach_tid_t_i = can_reach_tid_t[i]; - for (int o = 0; o <= 3; ++o) can_reach_tid_t_i[o] = 0; - } - } - } -} - -int GetMove(int aid) { - if (num_planned == 0) return DO_NOTHING; - const auto& path_aid = path[aid]; - auto& agent_aid = agent[aid]; - if (path_aid.tmax < TINIT + 1) return DO_NOTHING; - const auto& path_elem = path_aid.p[TINIT]; - const auto& path_elem_end_turn = path_aid.p[TINIT + 1]; - int action = DO_NOTHING; - DBG(2, " GetMove for aid=%d: tmax=%d\n", aid, path_aid.tmax); - if (path_elem_end_turn.how_i_got_here == ENTERED_SRC) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node < 0); - assert(path_elem.moving_to_o < 0); - assert(path_elem_end_turn.num_partial_turns == 0); - action = MOVE_FORWARD; - assert(agent_aid.moving_to_node < 0); - } else if (path_elem_end_turn.how_i_got_here == WAITED) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node < 0); - assert(path_elem.moving_to_o < 0); - assert(path_elem.num_partial_turns == 0); - assert(path_elem_end_turn.num_partial_turns == 0); - action = STOP_MOVING; - assert(agent_aid.moving_to_node < 0); - } else if (path_elem_end_turn.how_i_got_here == STARTED_MOVING) { - assert(path_elem_end_turn.num_partial_turns <= 1); - int dst_node = -1, dst_o = -1; - if (path_elem_end_turn.moving_to_node >= 0 && path_elem_end_turn.moving_to_o >= 0) { - assert(path_elem_end_turn.num_partial_turns == 1); - dst_node = path_elem_end_turn.moving_to_node; - dst_o = path_elem_end_turn.moving_to_o; - } else { - assert(path_elem_end_turn.num_partial_turns == 0); - dst_node = path_elem_end_turn.node; - dst_o = path_elem_end_turn.o; - } - assert(path_elem.node != dst_node); - assert(next[path_elem.node][path_elem.o][dst_o] == dst_node); - if (dst_o == path_elem.o || dst_o == ((path_elem.o + 2) & 3)) - action = MOVE_FORWARD; - else if (dst_o == ((path_elem.o + 1) & 3)) - action = MOVE_RIGHT; - else if (dst_o == ((path_elem.o + 3) & 3)) - action = MOVE_LEFT; - else { - DBG(0, "Incorrect move!!!\n"); - exit(1); - } - assert(agent_aid.moving_to_node < 0 || (agent_aid.moving_to_node == dst_node && agent_aid.moving_to_o == dst_o)); - agent_aid.moving_to_node = dst_node; - agent_aid.moving_to_o = dst_o; - } else if (path_elem_end_turn.how_i_got_here == CONTINUED_MOVING) { - if (path_elem.node == path_elem_end_turn.node) { - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node == path_elem_end_turn.moving_to_node); - assert(path_elem_end_turn.num_partial_turns == path_elem.num_partial_turns + 1); - } else { - assert(path_elem_end_turn.moving_to_node < 0); - assert(path_elem_end_turn.moving_to_o < 0); - assert(path_elem_end_turn.num_partial_turns == 0); - } - } else if (path_elem_end_turn.how_i_got_here == MALFUNCTIONED) { - assert(path_elem.node == path_elem_end_turn.node); - assert(path_elem.o == path_elem_end_turn.o); - assert(path_elem.moving_to_node == path_elem_end_turn.moving_to_node); - assert(path_elem.moving_to_o == path_elem_end_turn.moving_to_o); - assert(path_elem.num_partial_turns == path_elem_end_turn.num_partial_turns); - } - return action; -} - -void WriteMoves(const char* testid) { - num_planned = 0; - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const auto& ipath_aid = ipath[aid]; - if (ipath_aid.tmax > TINIT && ipath_aid.p[ipath_aid.tmax].node == agent_aid.target_node) ++num_planned; - } - sprintf(fname, "output-%s.txt", testid); - FILE* f = fopen(fname, "w"); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - const int action = GetMove(aid); - fprintf(f, "%d ", action); - if (action != DO_NOTHING) DBG(2, " Move aid=%d: %d\n", aid, action); - } - fprintf(f, "\n"); - fclose(f); -} - -void SaveDataForReplay(const char* testid) { - sprintf(fname, "saved-%s-%d.txt", testid, TINIT); - FILE* f = fopen(fname, "w"); - fprintf(f, "1\n%d %d\n", H, W); - for (int v = 0; v < nnodes; ++v) { - const auto& node_v = node[v]; - const auto& next_v = next[v]; - for (int o1 = 0; o1 <= 3; ++o1) for (int o2 = 0; o2 <= 3; ++o2) - if (next_v[o1][o2] >= 0) fprintf(f, "%d %d %d %d\n", node_v.row, node_v.col, o1, o2); - } - fprintf(f, "-1 -1 -1 -1\n%d %d\n%d %d %d\n", N, TINIT, num_reschedules, num_planned, num_adjust_ipaths_without_full_plan_regeneration); - for (int aid = 0; aid < N; ++aid) { - const auto& agent_aid = agent[aid]; - fprintf(f, "%d %d %d %d %d %d %.10lf %.10lf %d %d %d %d 1 1 %d %d %d\n", agent_aid.aid, agent_aid.poz_row, agent_aid.poz_col, agent_aid.poz_o, agent_aid.target_row, agent_aid.target_col, agent_aid.speed, agent_aid.poz_frac, agent_aid.malfunc, agent_aid.nr_malfunc, agent_aid.status, agent_aid.fresh_malfunc, agent_aid.moving_to_node >= 0 ? node[agent_aid.moving_to_node].row : -1, agent_aid.moving_to_node >= 0 ? node[agent_aid.moving_to_node].col : -1, agent_aid.moving_to_o); - const auto& ipath_aid = ipath[aid]; - fprintf(f, "%d\n", ipath_aid.tmax); - for (int t = TINIT; t <= ipath_aid.tmax; ++t) { - const auto& path_elem = ipath_aid.p[t]; - fprintf(f, "%d %d %d %d %d %d %d %d\n", node[path_elem.node].row, node[path_elem.node].col, path_elem.o, path_elem.moving_to_node < 0 ? -1 : node[path_elem.moving_to_node].row, path_elem.moving_to_node < 0 ? -1 : node[path_elem.moving_to_node].col, path_elem.moving_to_o, path_elem.num_partial_turns, path_elem.how_i_got_here); - } - const auto& num_checkpoints_aid = num_checkpoints[aid]; - const auto& next_checkpoint_aid = next_checkpoint[aid]; - fprintf(f, "%d\n", num_checkpoints_aid - next_checkpoint_aid); - const auto& checkpoints_aid = checkpoints[aid]; - const auto& checkpoints_o_aid = checkpoints_o[aid]; - const auto& checkpoints_t_aid = checkpoints_t[aid]; - for (int cid = next_checkpoint_aid; cid < num_checkpoints_aid; ++cid) { - fprintf(f, "%d %d %d %d\n", node[checkpoints_aid[cid]].row, node[checkpoints_aid[cid]].col, checkpoints_o_aid[cid], checkpoints_t_aid[cid]); - } - } - fprintf(f, "%d\n", T); - fclose(f); -} - -double total_time; - -void GetMoves(const char* testid, bool replay_mode = false) { - TSTART = GetTime(); - sprintf(fname, "input-%s.txt", testid); - fin = fopen(fname, "r"); - ReadTransitionsMap(); - ReadAgentsData(replay_mode); - fclose(fin); - if (TINIT == 0 || replay_mode) { - ReinitDataStructures(); - ComputeShortestPaths(); - } - SCORE_EXPONENT1 = 2.0; - SCORE_EXPONENT2 = 4.0; - DBG(2, "testid=%s TINIT=%d: resc=%d nda=%d npl=%d\n", testid, TINIT, reschedule, num_done_agents, num_planned); - if (reschedule) { - if (TINIT >= MIN_TINIT_FOR_SAVE_DATA_FOR_REPLAY) SaveDataForReplay(testid); - bool updated_paths_ok = false; - if (TINIT >= 1) { - updated_paths_ok = AdjustIPaths(); - ++num_adjust_ipaths_without_full_plan_regeneration; - } - const int kMaxNumAdjustIPathsWithoutFullPlanRegenartion = 5;//10; - if (!updated_paths_ok || num_adjust_ipaths_without_full_plan_regeneration > kMaxNumAdjustIPathsWithoutFullPlanRegenartion) { - RegenerateFullPlan(); - if (TINIT >= 1 && any_best_solution_updates) AdjustIPaths(); - num_adjust_ipaths_without_full_plan_regeneration = 0; - } - } - WriteMoves(testid); - if (TINIT == 0) total_time = 0.0; - total_time += GetTime() - TSTART; - DBG(0, "[GetMoves] testid=%s TINIT=%d/%d ttime=%.3lf nresc=%d nadjip=%d nadjipwofpr=%d nda=%d npl=%d sum=%d/%d(%.2lf)\n", testid, TINIT, TEST, total_time, num_reschedules, num_adjust_ipaths, num_adjust_ipaths_without_full_plan_regeneration, num_done_agents, num_planned, num_done_agents + num_planned, N, 100.0 * (num_done_agents + num_planned) / N); - - /*for (int aid = 0; aid < N; ++aid) { - if (aid == 27 || aid == 49 || aid == 56) { - const auto& ipath_aid = ipath[aid]; - for (int t = max(TINIT, 450); t <= 490 && t <= ipath_aid.tmax; ++t) { - const auto& elem = ipath_aid.p[t]; - DBG(0, "aid=%d t=%d node=%d npt=%d\n", aid, t, elem.node, elem.num_partial_turns); - } - } - }*/ -} - -} - -void GetMoves(const char* testid) { - SOLVE::GetMoves(testid, false); -} - -int main() { - SOLVE::GetMoves("1", true); - return 0; -} -