Example #1
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);
  }
}
Example #2
0
void
ContestDijkstra::AddEdges(const ScanTaskPoint origin,
                          const unsigned first_point)
{
  ScanTaskPoint destination(origin.GetStageNumber() + 1,
                            std::max(origin.GetPointIndex(), first_point));

  const int min_altitude = IsFinal(destination)
    ? GetMinimumFinishAltitude(GetPoint(FindStart(origin)))
    : 0;

  if (IsFinal(destination) &&
      first_finish_candidate > destination.GetPointIndex())
    /* limit the number of finish candidates during incremental
       search */
    destination.SetPointIndex(first_finish_candidate);

  const unsigned weight = GetStageWeight(origin.GetStageNumber());

  for (const ScanTaskPoint end(destination.GetStageNumber(), n_points);
       destination != end; destination.IncrementPointIndex()) {
    if (GetPoint(destination).GetIntegerAltitude() >= min_altitude) {
      const unsigned d = weight * CalcEdgeDistance(origin, destination);
      Link(destination, origin, d);
    }
  }

}
Example #3
0
ContestResult
ContestDijkstra::CalculateResult() const
{
  assert(num_stages <= MAX_STAGES);
  assert(solution_valid);

  ContestResult result;
  result.time = fixed(GetPoint(solution[num_stages - 1])
                      .DeltaTime(GetPoint(solution[0])));
  result.distance = result.score = fixed_zero;

  GeoPoint previous = GetPoint(solution[0]).GetLocation();
  for (unsigned i = 1; i < num_stages; ++i) {
    const GeoPoint &current = GetPoint(solution[i]).GetLocation();
    result.distance += current.Distance(previous);
    result.score += GetStageWeight(i - 1) * current.Distance(previous);
    previous = current;
  }

  #define fixed_fifth fixed(0.0002)
  result.score *= fixed_fifth;
  result.score = ApplyHandicap(result.score);

  return result;
}
Example #4
0
void
OLCTriangle::AddTurn2Edges(const ScanTaskPoint origin)
{
  ScanTaskPoint previous = dijkstra.GetPredecessor(origin);

  // give first leg points to penultimate node
  TriangleSecondLeg sl(is_fai, GetPoint(previous), GetPoint(origin));

  const ScanTaskPoint begin(origin.GetStageNumber() + 1,
                            origin.GetPointIndex() + 1);
  const ScanTaskPoint end(origin.GetStageNumber() + 1, n_points - 1);

  for (ScanTaskPoint i = begin; i != end; i.IncrementPointIndex()) {
    TriangleSecondLeg::Result result = sl.Calculate(GetPoint(i), best_d);
    const unsigned d = result.leg_distance;
    if (d > 0) {
      best_d = result.total_distance;

      Link(i, 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();
    }
  }
}
Example #5
0
void
OLCSprint::AddEdges(const ScanTaskPoint origin)
{
  const ScanTaskPoint destination(origin.GetStageNumber() + 1, n_points - 1);
  if (IsFinal(destination)) {
    /* For final, only add last valid point */
    const unsigned d = GetStageWeight(origin.GetStageNumber()) *
      CalcEdgeDistance(origin, destination);
    Link(destination, origin, d);
  } else
    ContestDijkstra::AddEdges(origin);
}
Example #6
0
void
ContestDijkstra::AddEdges(const ScanTaskPoint origin,
                          const unsigned first_point)
{
  ScanTaskPoint destination(origin.GetStageNumber() + 1,
                            std::max(origin.GetPointIndex(), first_point));

  const int min_altitude = IsFinal(destination)
    ? GetMinimumFinishAltitude(GetPoint(FindStart(origin)))
    : 0;

  if (IsFinal(destination) &&
      first_finish_candidate > destination.GetPointIndex())
    /* limit the number of finish candidates during incremental
       search */
    destination.SetPointIndex(first_finish_candidate);

  const unsigned weight = GetStageWeight(origin.GetStageNumber());

  bool previous_above = false;
  for (const ScanTaskPoint end(destination.GetStageNumber(), n_points);
       destination != end; destination.IncrementPointIndex()) {
    bool above = GetPoint(destination).GetIntegerAltitude() >= min_altitude;

    if (above) {
      const unsigned d = weight * CalcEdgeDistance(origin, destination);
      Link(destination, origin, d);
    } else if (previous_above) {
      /* After excessive thinning, the exact TracePoint that matches
         the required altitude difference may be gone, and the
         calculated result becomes overly pessimistic.  This code path
         makes it optimistic, by checking if the previous point
         matches. */

      /* TODO: interpolate the distance */
      const unsigned d = weight * CalcEdgeDistance(origin, destination);
      Link(destination, origin, d);
    }

    previous_above = above;
  }

  if (IsFinal(destination) && predicted.IsDefined()) {
    const unsigned d = weight * GetPoint(origin).FlatDistanceTo(predicted);
    destination.SetPointIndex(predicted_index);
    Link(destination, origin, d);
  }
}
Example #7
0
void
OLCTriangle::AddTurn1Edges(const ScanTaskPoint origin)
{
  // add points up to finish

  const ScanTaskPoint begin(origin.GetStageNumber() + 1, 0);
  const ScanTaskPoint end(origin.GetStageNumber() + 1, origin.GetPointIndex());

  for (ScanTaskPoint i = begin; i != end; i.IncrementPointIndex()) {
    const unsigned d = CalcEdgeDistance(origin, i);

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