Esempio n. 1
0
void
OLCTriangle::AddFinishEdges(const ScanTaskPoint origin)
{
  assert(IsFinal(origin.GetStageNumber() + 1));

  if (predict) {
    // dummy just to close the triangle
    Link(ScanTaskPoint(origin.GetStageNumber() + 1, n_points - 1), origin, 0);
  } else {
    const ScanTaskPoint start = FindStart(origin);
    const TracePoint &start_point = GetPoint(start);
    const TracePoint &origin_point = GetPoint(origin);

    const unsigned max_range =
      trace_master.ProjectRange(origin_point.GetLocation(), max_distance);

    /* check all remaining points, see which ones match the
       conditions */
    const ScanTaskPoint begin(origin.GetStageNumber() + 1, 0);
    const ScanTaskPoint end(origin.GetStageNumber() + 1,
                            origin.GetPointIndex());
    for (ScanTaskPoint i = begin; i != end; i.IncrementPointIndex())
      if (CalcEdgeDistance(start, i) <= max_range &&
          start_point.GetLocation().Distance(GetPoint(i).GetLocation()) < max_distance)
        Link(i, origin, CalcEdgeDistance(origin, i));
  }
}
Esempio n. 2
0
bool
OLCDijkstra::solve()
{
  if (m_dijkstra.empty()) {
    set_weightings();
    n_points = olc.get_trace_points(m_full_trace).size();
  }

  if (n_points < num_stages)
    return false;

  if (m_dijkstra.empty()) {
    m_dijkstra.reset(ScanTaskPoint(0, 0));
    add_start_edges();
    if (m_dijkstra.empty())
      // no processing to perform!
      // @todo
      // problem with this is it will immediately ask
      // OnlineContest for new data, which will be expensive
      // instead, new data should arrive only when preconditions
      // are satisfied (significant difference and valid)
      return true;
  }

  return solve_inner();
}
Esempio n. 3
0
void
OLCTriangle::AddEdges(const ScanTaskPoint origin)
{
  assert(origin.GetPointIndex() < n_points);

  switch (origin.GetStageNumber()) {
  case 0:
    // add points up to finish
    for (ScanTaskPoint destination(origin.GetStageNumber() + 1, 0),
           end(origin.GetStageNumber() + 1, origin.GetPointIndex());
         destination != end; destination.IncrementPointIndex()) {
      const unsigned d = CalcEdgeDistance(origin, destination);

      if (!is_fai || 4 * d >= best_d)
        /* no reason to add candidate if worse than 25% rule for FAI
           tasks */
        Link(destination, origin, GetStageWeight(origin.GetStageNumber()) * d);
    }
    break;

  case 1: {
    ScanTaskPoint previous = dijkstra.GetPredecessor(origin);

    // give first leg points to penultimate node
    TriangleSecondLeg sl(is_fai, GetPoint(previous), GetPoint(origin));
    for (ScanTaskPoint destination(origin.GetStageNumber() + 1,
                                   origin.GetPointIndex() + 1),
           end(origin.GetStageNumber() + 1, n_points - 1);
         destination != end; destination.IncrementPointIndex()) {
      TriangleSecondLeg::Result result = sl.Calculate(GetPoint(destination),
                                                      best_d);
      const unsigned d = result.leg_distance;
      if (d > 0) {
        best_d = result.total_distance;

        Link(destination, origin, GetStageWeight(origin.GetStageNumber()) * d);

        // we have an improved solution
        is_complete = true;

        // need to scan again whether path is closed
        is_closed = false;
        first_tp = origin.GetPointIndex();
      }
    }
  }
    break;

  case 2:
    // dummy just to close the triangle
    Link(ScanTaskPoint(origin.GetStageNumber() + 1, n_points - 1), origin, 0);
    break;

  default:
    assert(false);
  }
}
Esempio n. 4
0
bool
TaskDijkstraMax::DistanceMax()
{
  if (!RefreshTask())
    return false;

  dijkstra.Reserve(256);
  dijkstra.Clear();
  LinkStart(ScanTaskPoint(0, 0));
  return Run();
}
Esempio n. 5
0
bool
ContestDijkstra::Solve(bool exhaustive)
{
  if (dijkstra.empty()) {
    set_weightings();
    dijkstra.reserve(CONTEST_QUEUE_SIZE);
  }

  assert(num_stages <= MAX_STAGES);

  if (dijkstra.empty()) {

    update_trace();
    if (n_points < num_stages)
      return true;

    // don't re-start search unless we have had new data appear
    if (!trace_dirty) {
      return true;
    }
  } else if (exhaustive) {
    update_trace();
    if (n_points < num_stages)
      return true;
  } else if (n_points < num_stages) {
    update_trace();
    return true;
  }

  if (trace_dirty) {
    trace_dirty = false;

    dijkstra.restart(ScanTaskPoint(0, 0));
    start_search();
    add_start_edges();
    if (dijkstra.empty()) {
      return true;
    }
  }

#ifdef INSTRUMENT_TASK
  count_olc_solve++;
  count_olc_size = max(count_olc_size, dijkstra.queue_size());
#endif

  if (distance_general(exhaustive ? 0 - 1 : 25)) {
    SaveSolution();
    update_trace();
    return true;
  }

  return !dijkstra.empty();
}
Esempio n. 6
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();
}
Esempio n. 7
0
OLCDijkstra::OLCDijkstra(OnlineContest& _olc, const unsigned n_legs,
                         const unsigned finish_alt_diff,
                         const bool full_trace):
  NavDijkstra<TracePoint>(n_legs + 1),
  m_dijkstra(ScanTaskPoint(0, 0), false),
  olc(_olc),
  m_finish_alt_diff(finish_alt_diff),
  solution_found(false),
  best_distance(fixed_zero),
  best_speed(fixed_zero),
  best_time(fixed_zero),
  m_full_trace(full_trace)
{
  m_weightings.reserve(n_legs);
  best_solution.reserve(num_stages);
  reset();
}
Esempio n. 8
0
  /**
   * Returns the solution point for the specified task point.  Call
   * this after run() has returned true.
   */
  const SearchPoint &GetSolution(unsigned stage) const {
    assert(stage < num_stages);

    return GetPoint(ScanTaskPoint(stage, solution[stage]));
  }