diff --git a/aicrowd.json b/aicrowd.json index c7c8e156dea73d2a09246fd32a0a379744a42011..fae008f5d9dde9ddfa218d3d2ae47573fe80e426 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" : false + "debug" : true } diff --git a/r2sol.cc b/r2sol.cc index 431cbd738f66f7042d2868c479b35556add29cb4..5877130adf6b6c05f1cd3956332c37fff9682400 100644 --- a/r2sol.cc +++ b/r2sol.cc @@ -37,6 +37,7 @@ using namespace std; #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 { @@ -663,7 +664,7 @@ bool CanEnterCell(int aid, int t, int from, int to, const int covered_by[][MAXNO 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; + //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; @@ -687,7 +688,7 @@ bool CanEnterCell(int aid, int t, int from, int to, const int covered_by[][MAXNO 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 (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; } } @@ -704,7 +705,24 @@ 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 (t1 < tend_ongoing_move[node]) return true; + const int aid_t1 = is_covered[t1][node] == is_covered_idx ? covered_by[t1][node] : -1; + + 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 && (aid != 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]; @@ -717,8 +735,10 @@ bool OverlapsOngoingMove(int t1, int t2, int node, const int covered_by[][MAXNOD 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& 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]; @@ -729,7 +749,8 @@ bool OverlapsOngoingMove(int t1, int t2, int node, const int covered_by[][MAXNOD 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; } @@ -1135,6 +1156,9 @@ void CheckNonDeadlockPaths() { } } +const double kScoreExponent = 2.0; +const double kMaxTmaxWeight = 1e9; + void RandomPermutations(int tid, int ntries) { auto& pused_tid = pused[tid]; auto& perm_tid = perm[tid]; @@ -1163,13 +1187,30 @@ void RandomPermutations(int tid, int ntries) { 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; - reverse(shpaths_sorted.begin(), shpaths_sorted.end()); + if (trial == 2) reverse(shpaths_sorted.begin(), shpaths_sorted.end()); } else { for (int i = 0; i < N; ++i) pused_tid[i] = 0; - int idx = 0; - if ((trial & 1) == 1) { - /*for (int cturns = MAX_CTURNS - 1; cturns >= 0; --cturns) { + /*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; + }*/ + const int kMaxSwapDistance = 2; + for (int idx = 0; idx < N; ++idx) { + const int idx2min = max(0, idx - kMaxSwapDistance); + const int idx2max = min(N - 1, idx + kMaxSwapDistance); + const int idx2 = idx2min + (xor128_tid.rand() % (idx2max - idx2min + 1)); + const int tmp = shpaths_sorted[idx].second; + shpaths_sorted[idx].second = shpaths_sorted[idx2].second; + shpaths_sorted[idx2].second = tmp; + } + for (int i = 0; i < N; ++i) perm_tid[i] = shpaths_sorted[i].second; + /*if ((trial & 1) == 0) { + 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) { @@ -1178,12 +1219,6 @@ void RandomPermutations(int tid, int ntries) { } while (pused_tid[perm_tid[idx]]); pused_tid[perm_tid[idx++]] = 1; } - }*/ - 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 { for (int cturns = 0; cturns < MAX_CTURNS; ++cturns) { @@ -1196,16 +1231,6 @@ void RandomPermutations(int tid, int ntries) { 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; @@ -1251,7 +1276,7 @@ void RandomPermutations(int tid, int ntries) { 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; + 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; @@ -1260,11 +1285,13 @@ void RandomPermutations(int tid, int ntries) { 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 += pow(tmp_path_tid_aid.tmax, 3.0); + cost += pow(tmp_path_tid_aid.tmax, kScoreExponent); + if (tmp_path_tid_aid.tmax > max_tmax) max_tmax = tmp_path_tid_aid.tmax; } else { //cost += agent_aid.speed * (T - TINIT); } } + cost += max_tmax * kMaxTmaxWeight; { 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); @@ -1288,7 +1315,7 @@ void RegenerateFullPlan() { updated_best_solution = true; rerun = 0; - const int kMaxReruns = 3;//TINIT == 0 ? 4 : 3; + const int kMaxReruns = 4; while (updated_best_solution && rerun < kMaxReruns) { updated_best_solution = false; @@ -1316,7 +1343,7 @@ void RegenerateFullPlan() { if (max_threads >= 2) th = new thread*[max_threads - 1]; // Random Permutations. - const int kNumRandomPermutations = 7;//min(6 * 200 * 2560 / (N * T), 25); + const int kNumRandomPermutations = 10;//min(6 * 200 * 2560 / (N * T), 25); if (max_threads >= 2) { for (int tid = 0; tid + 1 < max_threads; ++tid) th[tid] = new thread([tid, kNumRandomPermutations]{ RandomPermutations(tid, kNumRandomPermutations); @@ -1925,13 +1952,14 @@ bool AdjustIPaths() { 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 += pow(path_aid.tmax, 3.0); + MIN_COST += pow(path_aid.tmax, kScoreExponent); 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); } } + MIN_COST += new_max_tmax * kMaxTmaxWeight; const bool changed_important_data = MAX_DONE_AGENTS != num_planned || new_max_tmax > max_tmax; if (changed_important_data) { @@ -2111,7 +2139,7 @@ void GetMoves(const char* testid, bool replay_mode = false) { updated_paths_ok = AdjustIPaths(); ++num_adjust_ipaths_without_full_plan_regeneration; } - const int kMaxNumAdjustIPathsWithoutFullPlanRegenartion = 6;//10; + 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(); @@ -2132,8 +2160,6 @@ void GetMoves(const char* testid, bool replay_mode = false) { } } }*/ - -// if (TINIT == 417) exit(1); } } @@ -2146,11 +2172,3 @@ int main() { SOLVE::GetMoves("1", true); return 0; } - -/* -0 100 74.0740740741 -55460.4166667195 -1 100 71.4285714286 -45245.7500000240 -2 56 46.2809917355 -47283.7500000259 -3 80 100.0000000000 -12941.6666666694 -4 96 61.9354838710 -97453.3333331954 -*/ diff --git a/r2sol.exe b/r2sol.exe index 15948abf4d1dd903cd47060a5075f65990224a8c..4938556a36a5601f9f8c902603e778dfa64f8f75 100755 Binary files a/r2sol.exe and b/r2sol.exe differ diff --git a/run_local.py b/run_local.py index f20097bdd20d3c8759a96536a4a5824dc3ecdf82..4e9aba76a0261dde20dc6b4584f692f74d7e9a39 100644 --- a/run_local.py +++ b/run_local.py @@ -25,7 +25,7 @@ def GetTestParams(tid): return (seed, width, height, nr_trains, nr_cities, max_rails_between_cities, max_rails_in_cities, malfunction_rate, malfunction_min_duration, malfunction_max_duration) def ShouldRunTest(tid): - return tid >= 5 + #return tid >= 5 #return tid == 2 return True @@ -41,7 +41,7 @@ d_base = {} f = open("scores.txt", "r") for line in f.readlines(): lsplit = line.split(" ") - if len(lsplit) == 4: + if len(lsplit) >= 4: test_id = int(lsplit[0]) num_done_agents = int(lsplit[1]) percentage_num_done_agents = float(lsplit[2]) @@ -104,7 +104,6 @@ for test_id in range(NUM_TESTS): obs = next_obs.copy() if done['__all__']: - print ("done") break num_done_agents = 0 @@ -124,8 +123,11 @@ for test_id in range(NUM_TESTS): total_base_percentage_num_done_agents += base_percentage_num_done_agents total_base_score += base_score - print("\n### test_id=%d nda=%d(dif=%d) pnda=%.6f(dif=%.6f) score=%.6f(dif=%.6f) avg_nda=%.6f(dif=%.6f) avg_sc=%.6f(dif=%.6f)\n" % (test_id, num_done_agents, num_done_agents - base_num_done_agents, percentage_num_done_agents, percentage_num_done_agents - base_percentage_num_done_agents, score, score - base_score, total_percentage_num_done_agents / num_tests, (total_percentage_num_done_agents - total_base_percentage_num_done_agents) / num_tests, total_score / num_tests, (total_score - total_base_score) / num_tests)) - f.write("%d %d% .10f %.10f\n" % (test_id, num_done_agents, percentage_num_done_agents, score)) + avg_nda = total_percentage_num_done_agents / num_tests + avg_nda_dif = (total_percentage_num_done_agents - total_base_percentage_num_done_agents) / num_tests + + print("\n### test_id=%d nda=%d(dif=%d) pnda=%.6f(dif=%.6f) score=%.6f(dif=%.6f) avg_nda=%.6f(dif=%.6f) avg_sc=%.6f(dif=%.6f)\n" % (test_id, num_done_agents, num_done_agents - base_num_done_agents, percentage_num_done_agents, percentage_num_done_agents - base_percentage_num_done_agents, score, score - base_score, avg_nda, avg_nda_dif, total_score / num_tests, (total_score - total_base_score) / num_tests)) + f.write("%d %d% .10f %.10f %.10f %.10f\n" % (test_id, num_done_agents, percentage_num_done_agents, score, avg_nda, avg_nda_dif)) f.flush() f.close() diff --git a/tmp-scores.txt b/tmp-scores.txt index 2137d557937242d8675770fed4c66ba7ab784b2b..6a0da14a089b57720004df5913185ab60202631b 100644 --- a/tmp-scores.txt +++ b/tmp-scores.txt @@ -1,10 +1,5 @@ -5 126 96.1832061069 -44149.0833333480 -6 138 79.7687861272 -70195.6666667112 -7 87 63.9705882353 -46680.9166666893 -8 74 61.6666666667 -44158.7500000220 -9 55 35.9477124183 -79448.2499999903 -10 81 48.2142857143 -97614.4166665799 -11 91 87.5000000000 -18943.1666666680 -12 61 55.4545454545 -50918.2500000281 -13 122 76.7295597484 -53732.9166667196 -14 75 60.9756097561 -67341.6666667139 +0 103 76.2962962963 -56746.5833333795 76.2962962963 -0.7407407407 +1 94 67.1428571429 -47095.9166666898 71.7195767196 -2.5132275132 +2 70 57.8512396694 -45232.7500000205 67.0967977029 2.1812643025 +3 80 100.0000000000 -15218.8333333374 75.3225982771 1.6359482269 +4 100 64.5161290323 -91272.9166665628 73.1613044282 1.3087585815