Beispiel #1
0
 /**
  * Add a copy of the current decision to path
  *
  * @param dec a decision of the current decision path
  */
 private void addToPath(Decision dec) {
   Decision clone = dec.duplicate();
   path.add(clone);
   int pos = path.size() - 1;
   if (!dec.hasNext()) {
     refuted.set(pos);
   }
   /*boolean forceNext = !dec.hasNext();
   if (forceNext) {
       clone.buildNext(); // force to set up the decision in the very state it was
       clone.buildNext(); // that's why we call it twice
   }*/
 }
Beispiel #2
0
 /** Compute the initial fragment, ie set of decisions to keep. */
 private void clonePath() {
   Decision dec = mSolver.getSearchLoop().getLastDecision();
   while ((dec != RootDecision.ROOT)) {
     addToPath(dec);
     dec = dec.getPrevious();
   }
   Collections.reverse(path);
   int size = path.size();
   for (int i = 0, mid = size >> 1, j = size - 1; i < mid; i++, j--) {
     boolean bi = refuted.get(i);
     refuted.set(i, refuted.get(j));
     refuted.set(j, bi);
   }
 }
Beispiel #3
0
 /**
  * Copy the current decision path in _unkopen, for comparison with copen. Then, it compares each
  * decision, from the top to the bottom, to find the first difference. This is required to avoid
  * adding the same decision sub-path more than once
  *
  * @param searchLoop the search loop
  * @return the index of the decision, in _unkopen, that stops the loop
  */
 private int compareSubpath(SearchLoop searchLoop) {
   _unkopen.clear();
   Decision decision = searchLoop.decision;
   while (decision != topDecision) {
     _unkopen.add(decision);
     decision = decision.getPrevious();
   }
   Collections.reverse(_unkopen);
   //
   int i = 0;
   int I = Math.min(_unkopen.size(), copen.length);
   while (i < I && copen[i].isEquivalentTo(_unkopen.get(i))) {
     i++;
   }
   return i;
 }
Beispiel #4
0
 @Override
 public void afterUpBranch() {
   // we need to catch up that case when the sub tree is closed and this imposes a fragment
   if (last != null && mSolver.getSearchLoop().getLastDecision().getId() == last.getId()) {
     mSolver.getSearchLoop().restart();
   }
 }
Beispiel #5
0
 /**
  * Extract the open right branches from the current path until it reaches the i^th decision of
  * _unkopen
  *
  * @param searchLoop the search loop
  * @param i the index of the decision, in _unkopen, that stops the loop
  */
 private void extractOB(SearchLoop searchLoop, int i) {
   Decision stopAt = _unkopen.get(i).getPrevious();
   // then, goes up in the search tree, and detect open nodes
   searchLoop.mSolver.getEnvironment().worldPop();
   Decision decision = searchLoop.decision;
   int bound;
   while (decision != stopAt) {
     bound =
         isMinimization
             ? objectiveManager.getObjective().getLB()
             : objectiveManager.getObjective().getUB();
     if (decision.hasNext() && isValid(bound)) {
       opens.add(new Open(decision, bound, isMinimization));
     }
     searchLoop.decision = searchLoop.decision.getPrevious();
     decision.free();
     decision = searchLoop.decision;
     searchLoop.mSolver.getEnvironment().worldPop();
   }
 }
Beispiel #6
0
  @Override
  public void fixSomeVariables(ICause cause) throws ContradictionException {
    // this is called after restart
    // if required, force the cut and explain the cut
    if (forceCft) {
      explainCut();
      nbFixedVariables = related2cut.cardinality();
      nbCall = 0;
      increaseLimit();
    }
    // then fix variables
    // this part is specific: a fake decision path has to be created
    nbCall++;
    restrictLess();
    notFrozen.clear();
    notFrozen.or(related2cut);
    for (; !notFrozen.isEmpty() && notFrozen.cardinality() > nbFixedVariables; ) {
      int idx = selectVariable();
      notFrozen.clear(idx);
    }
    assert mSolver.getSearchLoop().getLastDecision() == RootDecision.ROOT;
    // add the first refuted decisions
    int first = notFrozen.nextSetBit(0);
    for (int i = (first > -1 ? refuted.nextSetBit(first) : first);
        i > -1;
        i = refuted.nextSetBit(i + 1)) {
      notFrozen.clear(i);
    }

    // add unrelated
    notFrozen.or(unrelated);

    // then build the fake decision path
    last = null;
    //        LOGGER.debug("relax cut {}", notFrozen.cardinality());
    for (int id = notFrozen.nextSetBit(0);
        id >= 0 && id < path.size();
        id = notFrozen.nextSetBit(id + 1)) {
      //            last = ExplanationToolbox.mimic(path.get(id)); // required because some
      // unrelated decisions can be refuted
      if (path.get(id).hasNext()) {
        last = path.get(id).duplicate();
        if (refuted.get(id)) last.buildNext();
        ExplanationToolbox.imposeDecisionPath(mSolver, last);
      }
    }
  }
Beispiel #7
0
 /**
  * Create an open right branch for HBFS
  *
  * @param decision an open decision
  * @param currentBound current lower (resp. upper) bound of the objective value for mimimization
  *     (resp. maximization)
  * @param minimization set to <tt>true</tt> for minimization
  */
 public Open(Decision<IntVar> decision, int currentBound, boolean minimization) {
   this.path = new ArrayList<>();
   while (decision != topDecision) {
     Decision d = decision.duplicate();
     while (decision.triesLeft() != d.triesLeft() - 1) {
       d.buildNext();
     }
     path.add(d);
     decision = decision.getPrevious();
   }
   this.currentBound = currentBound;
   this.minimization = (byte) (minimization ? 1 : -1);
 }
Beispiel #8
0
  /** Force the failure, apply decisions to the last solution + cut => failure! */
  private void explainCut() {
    // Goal: force the failure to get the set of decisions related to the cut
    forceCft = false;
    // 1. make a backup
    mSolver.getEnvironment().worldPush();
    Decision d;
    try {

      Decision previous = mSolver.getSearchLoop().getLastDecision();
      assert previous == RootDecision.ROOT;
      // 2. apply the decisions
      mExplanationEngine.getSolver().getObjectiveManager().postDynamicCut();
      for (int i = 0; i < path.size(); i++) {
        d = path.get(i);
        d.setPrevious(previous);
        d.buildNext();
        if (refuted.get(i)) d.buildNext();
        d.apply();
        mSolver.propagate();
        previous = d;
      }
      // mSolver.propagate();
      assert false : "SHOULD FAIL!";
    } catch (ContradictionException cex) {
      if ((cex.v != null) || (cex.c != null)) { // contradiction on domain wipe out
        tmpDeductions.clear();
        tmpValueDeductions.clear();
        related2cut.clear();
        unrelated.clear();

        // 3. explain the failure
        Explanation expl = new Explanation();
        if (cex.v != null) {
          cex.v.explain(mExplanationEngine, VariableState.DOM, expl);
        } else {
          cex.c.explain(mExplanationEngine, null, expl);
        }
        Explanation complete = mExplanationEngine.flatten(expl);
        ExplanationToolbox.extractDecision(complete, tmpValueDeductions);
        tmpDeductions.addAll(tmpValueDeductions);

        if (tmpDeductions.isEmpty()) {
          //                    if (LOGGER.isErrorEnabled()) {
          //                        LOGGER.error("2 cases: (a) optimality proven or (b) bug in
          // explanation");
          //                    }
          //                    throw new SolverException("2 cases: (a) optimality proven or (b) bug
          // in explanation");
          isTerminated = true;
        }

        for (int i = 0; i < tmpDeductions.size(); i++) {
          int idx = path.indexOf(((BranchingDecision) tmpDeductions.get(i)).getDecision());
          related2cut.set(idx);
        }

        // 4. need to replace the duplicated decision with the correct one
        for (int i = 0; i < path.size(); i++) {
          Decision dec = path.get(i);
          boolean forceNext = !dec.hasNext();
          dec.rewind();
          if (forceNext) dec.buildNext();
          dec.setPrevious(null); // useless .. but ... you know
        }

      } else {
        throw new UnsupportedOperationException(
            this.getClass().getName() + ".onContradiction incoherent state");
      }
    }
    mSolver.getEnvironment().worldPop();
    mSolver.getEngine().flush();
    unrelated.andNot(related2cut);
    unrelated.andNot(refuted);
  }