Beispiel #1
0
  /**
   * Check if a {@linkplain TRSPTwoOptMove 2-opt move} is feasible for the given <code>tour</code>
   *
   * @param tour the base tour
   * @param move the {@link TRSPTwoOptMove} to be tested
   * @return <code>true</code> if applying <code>move</code> to the given <code>tour</code> will
   *     result in a feasible tour
   */
  @Override
  public boolean isTwoOptFeasible(ITRSPTour itour, TRSPTwoOptMove move) {
    if (!TRSPTour.class.isAssignableFrom(itour.getClass())) {
      TRSPLogging.getOptimizationLogger()
          .warn(
              String.format(
                  "ToolsConstraint.isTwoOptFeasible: unsupported tour class (%s)",
                  itour.getClass()));
      return true;
    }
    TRSPTour tour = (TRSPTour) itour;

    if (!tour.isMainDepotVisited() // The main depot is not visited, the tour is already feasible
        || tour.isMainDepotVisited(
            tour.getSucc(move.getFirst())) // The visit to the main depot is done before
        // the first
        // affected node
        || !tour.isMainDepotVisited(move.getSecond())) // The visit to the main depot is done
      // after the last affected node
      return true;

    // The main depot is visited between j and m
    TRSPTourIterator it = tour.iterator(move.getSecond());

    // Start with node m and iterate backward
    int node = it.previous();
    while (node != tour.getMainDepotId() && it.hasNext()) {
      if (!tour.getInstance().hasRequiredTools(tour.getTechnician().getID(), node))
        // The technician does not have the required tools for this request
        return false;
    }

    // No incompatible request was found, the move is feasible
    return true;
  }
Beispiel #2
0
  /**
   * Check if a {@linkplain TRSPShiftMove shift move} is feasible for the given <code>solution
   * </code>
   *
   * @param solution the base solution
   * @param move the {@link TRSPShiftMove} to be tested
   * @return <code>true</code> if applying <code>move</code> to the given <code>solution</code> will
   *     result in a feasible mSolution
   */
  @Override
  public boolean isShiftFeasible(ITRSPTour itour, TRSPShiftMove move) {
    if (!TRSPTour.class.isAssignableFrom(itour.getClass())) {
      TRSPLogging.getOptimizationLogger()
          .warn(
              String.format(
                  "ToolsConstraint.isShiftFeasible: unsupported tour class (%s)",
                  itour.getClass()));
      return true;
    }
    TRSPTour tour = (TRSPTour) itour;

    if (!tour.isMainDepotVisited()) {
      // The main depot is not visited, we assume that the tour is and will remain feasible
      return true;
    } else {
      // The main depot is visited
      if (move.getNode() == tour.getMainDepotId()) {
        // The shifted node is the main depot
        if (!move.isForward()) {
          // A backward move of the main depot is always feasible
          return true;
        } else {
          // Check if the requests between the current depot position and its new one require a
          // visit to
          // the depot to be served
          List<Integer> seq = move.getChangedSequence();
          for (int s : seq) {
            if (s == tour.getMainDepotId())
              // The requests after the main depot will be feasible
              return true;
            else if (!tour.getInstance().hasRequiredTools(tour.getTechnician().getID(), s))
              // This request will be before the depot visit but the technician does not have the
              // required
              // skills
              return false;
          }
          throw new IllegalStateException(
              "Illegal state when checking the feasibility of move " + move);
        }
      } else {
        if (tour.getInstance().hasRequiredTools(tour.getTechnician().getID(), move.getNode()))
          // The technician already has the tools to serve the shifted node, the move is feasible in
          // all cases
          return true;

        int pred =
            move.getNewSucc() != ITRSPTour.UNDEFINED
                ? tour.getPred(move.getNewSucc())
                : tour.getLastNode();
        if (tour.isMainDepotVisited(move.getNode()) == tour.isMainDepotVisited(pred)) {
          // Both the shifted node and its new predecessor are on the same "side" of the tour
          // (either before
          // or after the depot visit), the move is therefore feasible
          return true;
        } else {
          // The shifted node and its new predecessor are on different "side" of the tour (one is
          // before
          // while the other is after the depot visit)
          if (move.isForward()) {
            // The node will be after the depot visit, the move is therefore feasible
            return true;
          } else {
            // The node is shifted before the depot visit, while the technician does not have the
            // required
            // tools (tested before)
            return false;
          }
        }
      }
    }
  }