SolverResult ContestDijkstra::Solve(bool exhaustive) { assert(num_stages <= MAX_STAGES); if (trace_master.size() < num_stages) { /* not enough data in master trace */ ClearTrace(); finished = false; return SolverResult::FAILED; } if (finished || dijkstra.IsEmpty()) { UpdateTrace(exhaustive); if (n_points < num_stages) return SolverResult::FAILED; // don't re-start search unless we have had new data appear if (!trace_dirty && !finished) return SolverResult::FAILED; } else if (exhaustive || n_points < num_stages || CheckMasterSerial()) { UpdateTrace(exhaustive); if (n_points < num_stages) return SolverResult::FAILED; } assert(n_points >= num_stages); if (trace_dirty) { trace_dirty = false; finished = false; dijkstra.Clear(); dijkstra.Reserve(CONTEST_QUEUE_SIZE); StartSearch(); AddStartEdges(); if (dijkstra.IsEmpty()) return SolverResult::FAILED; } SolverResult result = DistanceGeneral(exhaustive ? 0 - 1 : 25); if (result != SolverResult::INCOMPLETE) { if (incremental && continuous) /* enable the incremental solver, which considers the existing Dijkstra edge map */ finished = true; else /* start the next iteration from scratch */ dijkstra.Clear(); if (result == SolverResult::VALID && !SaveSolution()) result = SolverResult::FAILED; } return result; }
bool TaskDijkstraMin::DistanceMin(const SearchPoint ¤tLocation) { dijkstra.Clear(); dijkstra.Reserve(256); if (currentLocation.IsValid()) { AddStartEdges(0, currentLocation); } else { AddZeroStartEdges(); } return Run(); }
bool TaskDijkstraMin::DistanceMin(const SearchPoint ¤tLocation) { if (!RefreshTask()) return false; dijkstra.Reserve(256); dijkstra.Clear(); if (active_stage > 0) { AddStartEdges(currentLocation); } else { LinkStart(ScanTaskPoint(0, 0)); } return Run(); }
void ContestDijkstra::AddIncrementalEdges(unsigned first_point) { assert(first_point < n_points); assert(continuous); assert(incremental); assert(finished); finished = false; first_finish_candidate = first_point; /* we need a copy of the current edge map, because the following loop will modify it, invalidating the iterator */ #if GCC_VERSION < 40800 || GCC_VERSION > 40802 const Dijkstra::EdgeMap edges = dijkstra.GetEdgeMap(); #else // workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59548 Dijkstra::EdgeMap edges; edges = dijkstra.GetEdgeMap(); #endif /* establish links between each old node and each new node, to initiate the follow-up search, hoping a better solution will be found here */ for (const auto &i : edges) { if (IsFinal(i.first)) /* ignore final nodes */ continue; /* "seek" the Dijkstra object to the current "old" node */ dijkstra.SetCurrentValue(i.second.value); /* add edges from the current "old" node to all "new" nodes (first_point .. n_points-1) */ AddEdges(i.first, first_point); } /* see if new start points are possible now (due to relaxed start height constraints); duplicates will be ignored by the Dijkstra class */ AddStartEdges(); }
void ContestDijkstra::AddIncrementalEdges(unsigned first_point) { assert(first_point < n_points); assert(continuous); assert(incremental); assert(finished); finished = false; first_finish_candidate = first_point; /* we need a copy of the current edge map, because the following loop will modify it, invalidating the iterator */ const Dijkstra::EdgeMap edges = dijkstra.GetEdgeMap(); /* establish links between each old node and each new node, to initiate the follow-up search, hoping a better solution will be found here */ for (auto i = edges.begin(), end = edges.end(); i != end; ++i) { if (IsFinal(i->first)) /* ignore final nodes */ continue; /* "seek" the Dijkstra object to the current "old" node */ dijkstra.SetCurrentValue(i->second.value); /* add edges from the current "old" node to all "new" nodes (first_point .. n_points-1) */ AddEdges(i->first, first_point); } /* see if new start points are possible now (due to relaxed start height constraints); duplicates will be ignored by the Dijkstra class */ AddStartEdges(); }