Beispiel #1
0
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;
}
Beispiel #2
0
bool
TaskDijkstraMin::DistanceMin(const SearchPoint &currentLocation)
{
  dijkstra.Clear();
  dijkstra.Reserve(256);

  if (currentLocation.IsValid()) {
    AddStartEdges(0, currentLocation);
  } else {
    AddZeroStartEdges();
  }

  return Run();
}
Beispiel #3
0
bool
TaskDijkstraMin::DistanceMin(const SearchPoint &currentLocation)
{
  if (!RefreshTask())
    return false;

  dijkstra.Reserve(256);
  dijkstra.Clear();

  if (active_stage > 0) {
    AddStartEdges(currentLocation);
  } else {
    LinkStart(ScanTaskPoint(0, 0));
  }

  return Run();
}
Beispiel #4
0
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();
}
Beispiel #5
0
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();
}