Пример #1
0
 private void showCC() {
   for (int i = 0; i < setCC.size(); i++) {
     IStateBitSet contain = setCC.elementAt(i);
     LOGGER.info("cc(" + i + ") = " + contain.toString());
   }
   LOGGER.info("*-*-*-*-*-*-*-*-*-*-*-*-*");
 }
Пример #2
0
 private void updateSpecialNodes() {
   for (int i = 0; i < nbNodes; i++) {
     if (graph[i].cardinality() == 0) sinkNodes.set(i, true);
     else sinkNodes.set(i, false);
     if (revGraph[i].cardinality() == 0) srcNodes.set(i, true);
     else srcNodes.set(i, false);
   }
 }
Пример #3
0
  @Override
  public boolean removeValue(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    ICause antipromo = cause;
    if (informCause) {
      cause = Cause.Null;
    }
    boolean change = false;
    int inf = getLB();
    int sup = getUB();
    if (value == inf && value == sup) {
      this.contradiction(cause, MSG_REMOVE);
    } else {
      if (inf <= value && value <= sup) {
        EventType e = EventType.REMOVE;

        int aValue = value - OFFSET;
        change = VALUES.get(aValue);
        this.VALUES.clear(aValue);
        if (change) {
          SIZE.add(-1);
          // todo delta
        }

        if (value == inf) {
          inf = VALUES.nextSetBit(aValue) + OFFSET;
          LB.set(inf);
          e = EventType.INCLOW;
          filterOnGeq(cause, inf);
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        } else if (value == sup) {
          sup = VALUES.prevSetBit(aValue) + OFFSET;
          UB.set(sup);
          e = EventType.DECUPP;
          filterOnLeq(cause, sup);
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        }
        if (change && !VALUES.isEmpty()) {
          if (this.instantiated()) {
            e = EventType.INSTANTIATE;
            if (cause.reactOnPromotion()) {
              cause = Cause.Null;
            }
          }
          this.notifyPropagators(e, cause);
        } else {
          if (VALUES.isEmpty()) {
            this.contradiction(cause, MSG_EMPTY);
          }
        }
      }
    }
    return change;
  }
Пример #4
0
 @Override
 public void backPropagate(int mask) throws ContradictionException {
   // one of the variable as changed externally, this involves a complete update of this
   if (!EventType.isRemove(mask)) {
     int elb = A.getLB() + B.getLB();
     int eub = A.getUB() + B.getUB();
     int ilb = LB.get();
     int iub = UB.get();
     int old_size = iub - ilb; // is == 0, then the view is already instantiated
     boolean up = false, down = false;
     EventType e = EventType.VOID;
     if (elb > ilb) {
       if (elb > iub) {
         this.contradiction(this, MSG_LOW);
       }
       VALUES.clear(ilb - OFFSET, elb - OFFSET);
       ilb = VALUES.nextSetBit(ilb - OFFSET) + OFFSET;
       LB.set(ilb);
       e = EventType.INCLOW;
       down = true;
     }
     if (eub < iub) {
       if (eub < ilb) {
         this.contradiction(this, MSG_LOW);
       }
       VALUES.clear(eub - OFFSET + 1, iub - OFFSET + 1);
       iub = VALUES.prevSetBit(iub - OFFSET + 1) + OFFSET;
       UB.set(iub);
       if (e != EventType.VOID) {
         e = EventType.BOUND;
       } else {
         e = EventType.DECUPP;
       }
       up = true;
     }
     int size = VALUES.cardinality();
     SIZE.set(size);
     if (ilb > iub) {
       this.contradiction(this, MSG_EMPTY);
     }
     if (down || size == 1) {
       filterOnGeq(this, ilb);
     }
     if (up || size == 1) { // size == 1 means instantiation, then force filtering algo
       filterOnLeq(this, iub);
     }
     if (ilb == iub) { // size == 1 means instantiation, then force filtering algo
       if (old_size > 0) {
         notifyPropagators(EventType.INSTANTIATE, this);
       }
     } else {
       notifyPropagators(e, this);
     }
   }
 }
Пример #5
0
 private void computeCCfromScratch() {
   this.cc.getConnectedComponents(affiche);
   if (affiche) showCC();
   // record the connected components of the graph
   for (int i = 0; i < nbNodes; i++) this.numFromVertCC[i].clear();
   for (int i = 0; i < this.setCC.size(); i++) {
     IStateBitSet contain = this.setCC.elementAt(i);
     this.vertFromNumCC[i].clear();
     for (int j = contain.nextSetBit(0); j >= 0; j = contain.nextSetBit(j + 1)) {
       this.vertFromNumCC[i].set(j, true);
       this.numFromVertCC[j].set(i, true);
     }
   }
   this.nbCC.set(this.cc.getNbCC());
 }
Пример #6
0
 public int nextValue(int aValue) {
   aValue -= OFFSET;
   int lb = LB.get();
   if (aValue < 0 || aValue < lb) return lb + OFFSET;
   aValue = VALUES.nextSetBit(aValue + 1);
   if (aValue > -1) return aValue + OFFSET;
   return Integer.MAX_VALUE;
 }
Пример #7
0
 /**
  * add a value.
  *
  * @param x value to add
  * @return true wether the value has been added
  */
 public boolean add(int x) {
   int i = x - offset;
   if (!contents.get(i)) {
     addIndex(i);
     return true;
   } else {
     return false;
   }
 }
Пример #8
0
 @Override
 public int previousValue(int aValue) {
   aValue -= OFFSET;
   int ub = UB.get();
   if (aValue > ub) return ub + OFFSET;
   aValue = VALUES.prevSetBit(aValue - 1);
   if (aValue > -1) return aValue + OFFSET;
   return Integer.MIN_VALUE;
 }
Пример #9
0
 /** Removes a value. */
 public boolean remove(int x) {
   int i = x - offset;
   if (contents.get(i)) {
     removeIndex(i);
     return true;
   } else {
     return false;
   }
 }
Пример #10
0
  /**
   * Instantiates the domain of <code>this</code> to <code>value</code>. The instruction comes from
   * <code>propagator</code>.
   *
   * <ul>
   *   <li>If the domain of <code>this</code> is already instantiated to <code>value</code>, nothing
   *       is done and the return value is <code>false</code>,
   *   <li>If the domain of <code>this</code> is already instantiated to another value, then a
   *       <code>ContradictionException</code> is thrown,
   *   <li>Otherwise, the domain of <code>this</code> is restricted to <code>value</code> and the
   *       observers are notified and the return value is <code>true</code>.
   * </ul>
   *
   * @param value instantiation value (int)
   * @param cause instantiation releaser
   * @param informCause
   * @return true if the instantiation is done, false otherwise
   * @throws solver.exception.ContradictionException if the domain become empty due to this action
   */
  public boolean instantiateTo(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    // BEWARE: THIS CODE SHOULD NOT BE MOVED TO THE DOMAIN TO NOT DECREASE PERFORMANCES!
    solver
        .getExplainer()
        .instantiateTo(
            this, value,
            cause); // the explainer is informed before the actual instantiation is performed
    if (informCause) {
      cause = Cause.Null;
    }
    if (this.instantiated()) {
      if (value != this.getValue()) {
        this.contradiction(cause, MSG_INST);
      }
      return false;
    } else if (contains(value)) {
      int aValue = value - OFFSET;
      if (reactOnRemoval) {
        int i = VALUES.nextSetBit(this.LB.get());
        for (; i < aValue; i = VALUES.nextSetBit(i + 1)) {
          delta.add(i + OFFSET);
        }
        i = VALUES.nextSetBit(aValue + 1);
        for (; i >= 0; i = VALUES.nextSetBit(i + 1)) {
          delta.add(i + OFFSET);
        }
      }
      this.VALUES.clear();
      this.VALUES.set(aValue);
      this.LB.set(aValue);
      this.UB.set(aValue);
      this.SIZE.set(1);

      if (VALUES.isEmpty()) {
        this.contradiction(cause, MSG_EMPTY);
      }
      this.notifyPropagators(EventType.INSTANTIATE, cause);
      return true;
    } else {
      this.contradiction(cause, MSG_UNKNOWN);
      return false;
    }
  }
Пример #11
0
  /**
   * Updates the lower bound of the domain of <code>this</code> to <code>value</code>. The
   * instruction comes from <code>propagator</code>.
   *
   * <ul>
   *   <li>If <code>value</code> is smaller than the lower bound of the domain, nothing is done and
   *       the return value is <code>false</code>,
   *   <li>if updating the lower bound to <code>value</code> leads to a dead-end (domain wipe-out),
   *       a <code>ContradictionException</code> is thrown,
   *   <li>otherwise, if updating the lower bound to <code>value</code> can be done safely, the
   *       event type is created (the original event can be promoted) and observers are notified and
   *       the return value is <code>true</code>
   * </ul>
   *
   * @param value new lower bound (included)
   * @param cause updating releaser
   * @param informCause
   * @return true if the lower bound has been updated, false otherwise
   * @throws solver.exception.ContradictionException if the domain become empty due to this action
   */
  public boolean updateLowerBound(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    boolean change;
    ICause antipromo = cause;
    if (informCause) {
      cause = Cause.Null;
    }
    int old = this.getLB();
    if (old < value) {
      if (this.getUB() < value) {
        solver.getExplainer().updateLowerBound(this, old, value, antipromo);
        this.contradiction(cause, MSG_LOW);
      } else {
        EventType e = EventType.INCLOW;

        int aValue = value - OFFSET;
        if (reactOnRemoval) {
          // BEWARE: this loop significantly decreases performances
          for (int i = old - OFFSET; i < aValue; i = VALUES.nextSetBit(i + 1)) {
            delta.add(i + OFFSET);
          }
        }
        VALUES.clear(old - OFFSET, aValue);
        LB.set(VALUES.nextSetBit(aValue));
        int _size = SIZE.get();
        int card = VALUES.cardinality();
        SIZE.set(card);
        change = _size - card > 0;

        if (instantiated()) {
          e = EventType.INSTANTIATE;
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        }
        assert (change);
        this.notifyPropagators(e, cause);
        solver.getExplainer().updateLowerBound(this, old, value, antipromo);
        return change;
      }
    }
    return false;
  }
Пример #12
0
 /**
  * Constructs a new domain for the specified variable and bounds.
  *
  * @param v The involved variable.
  * @param a Minimal value.
  * @param b Maximal value.
  * @param full indicate if the initial bitSetDomain is full or empty (env or ker)
  * @param environment
  */
 public BitSetEnumeratedDomain(SetVar v, int a, int b, boolean full, IEnvironment environment) {
   capacity = b - a + 1; // number of entries
   this.offset = a;
   if (full) size = environment.makeInt(capacity);
   else size = environment.makeInt(0);
   contents = environment.makeBitSet(capacity);
   if (full) {
     for (int i = 0; i < capacity; i++) contents.set(i);
   }
   delatDom = new BitSetDeltaDomain(capacity, offset);
 }
Пример #13
0
 private IStateBitSet getDesc(int i, int j, IStateBitSet[] graph) {
   // retrieve the set of reachable nodes from i in the graph
   needUpdate = true;
   Stack<Integer> stack = new Stack<Integer>();
   IStateBitSet reached = solver.getEnvironment().makeBitSet(nbNodes);
   stack.push(i);
   while (!stack.isEmpty()) {
     int a = stack.pop();
     for (int b = graph[a].nextSetBit(0); b >= 0; b = graph[a].nextSetBit(b + 1)) {
       if (!stack.contains(b) && !reached.get(b)) {
         reached.set(b, true);
         if (b == j) {
           needUpdate = false;
           return reached;
         } else stack.push(b);
       }
     }
   }
   return reached;
 }
Пример #14
0
  @Override
  public boolean updateLowerBound(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    ICause antipromo = cause;
    if (informCause) {
      cause = Cause.Null;
    }
    boolean change;
    int lb = this.getLB();
    if (lb < value) {
      if (this.getUB() < value) {
        this.contradiction(cause, MSG_LOW);
      } else {
        EventType e = EventType.INCLOW;

        int aValue = value - OFFSET;
        // todo delta
        VALUES.clear(lb - OFFSET, aValue);
        lb = VALUES.nextSetBit(aValue) + OFFSET;
        LB.set(lb);
        int _size = SIZE.get();
        int card = VALUES.cardinality();
        SIZE.set(card);
        change = _size - card > 0;

        filterOnGeq(cause, lb);

        if (instantiated()) {
          e = EventType.INSTANTIATE;
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        }
        this.notifyPropagators(e, cause);

        return change;
      }
    }
    return false;
  }
Пример #15
0
 private void remIncreTC(int i, int j) {
   if (i != j) {
     // reachable nodes from node i in the graph
     IStateBitSet tempDesc = getDesc(i, j, graph);
     if (needUpdate) {
       tcGraph[i] = tempDesc;
       // compute all the reachble nodes from each ancestor of i in graph
       IStateBitSet updateAnc = solver.getEnvironment().makeBitSet(nbNodes);
       for (int k = revTcGraph[i].nextSetBit(0); k >= 0; k = revTcGraph[i].nextSetBit(k + 1)) {
         if (!updateAnc.get(k)) {
           tempDesc = getDesc(k, j, graph);
           if (!needUpdate) updateAnc.or(revTcGraph[k]);
           else tcGraph[k] = tempDesc;
         }
       }
       // compute the nodes reachable from j in the reverse graph
       revTcGraph[j] = getDesc(j, i, revGraph);
       // compute all the nodes reachable from each descendant of j in the reverse graph
       IStateBitSet updateDesc = solver.getEnvironment().makeBitSet(nbNodes);
       for (int k = tcGraph[j].nextSetBit(0); k >= 0; k = tcGraph[j].nextSetBit(k + 1)) {
         if (!updateDesc.get(k)) {
           tempDesc = getDesc(k, i, revGraph);
           if (!needUpdate) updateDesc.or(tcGraph[k]);
           else revTcGraph[k] = tempDesc;
         }
       }
     }
   }
 }
Пример #16
0
  @Override
  public boolean updateUpperBound(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    ICause antipromo = cause;
    if (informCause) {
      cause = Cause.Null;
    }
    boolean change;
    int ub = this.getUB();
    if (ub > value) {
      if (this.getLB() > value) {
        this.contradiction(cause, MSG_UPP);
      } else {
        EventType e = EventType.DECUPP;
        int aValue = value - OFFSET;
        // todo delta
        VALUES.clear(aValue + 1, ub - OFFSET + 1);
        ub = VALUES.prevSetBit(aValue) + OFFSET;
        UB.set(ub);

        int _size = SIZE.get();
        int card = VALUES.cardinality();
        SIZE.set(card);
        change = _size - card > 0;

        filterOnLeq(cause, ub);

        if (card == 1) {
          e = EventType.INSTANTIATE;
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        }
        this.notifyPropagators(e, cause);
        return change;
      }
    }
    return false;
  }
Пример #17
0
  public BitsetXYSumView(IntVar a, IntVar b, Solver solver) {
    super(a, b, solver);
    int lbA = A.getLB();
    int ubA = A.getUB();
    int lbB = B.getLB();
    int ubB = B.getUB();
    OFFSET = lbA + lbB;
    VALUES = solver.getEnvironment().makeBitSet((ubA + ubB) - (lbA + lbB) + 1);

    DisposableRangeIterator itA = A.getRangeIterator(true);
    DisposableRangeIterator itB = B.getRangeIterator(true);
    while (itA.hasNext()) {
      itB.bottomUpInit();
      while (itB.hasNext()) {
        VALUES.set(itA.min() + itB.min() - OFFSET, itA.max() + itB.max() - OFFSET + 1);
        itB.next();
      }
      itB.dispose();
      itA.next();
    }
    itA.dispose();
    SIZE.set(VALUES.cardinality());
  }
Пример #18
0
 @Override
 public int nextValue(int aValue) {
   // based on "Bounds Consistency Techniques for Long Linear Constraint"
   // we only check bounds of A and B, and consider VALUES inside as bounds as existing ones
   // what if lb > Integer.MAX_VALUE...
   int lb = getLB();
   if (aValue < lb) {
     return lb;
   } else if (aValue < getUB()) {
     return VALUES.nextSetBit(aValue - OFFSET + 1) + OFFSET;
   } else {
     return Integer.MAX_VALUE;
   }
 }
Пример #19
0
 @Override
 public int previousValue(int aValue) {
   // based on "Bounds Consistency Techniques for Long Linear Constraint"
   // we only check bounds of A and B, and consider VALUES inside as bounds as existing ones
   // what if ub > Integer.MAX_VALUE...
   int ub = getUB();
   if (aValue > ub) {
     return ub;
   } else if (aValue > getLB()) {
     return VALUES.prevSetBit(aValue - OFFSET - 1) + OFFSET;
   } else {
     return Integer.MIN_VALUE;
   }
 }
Пример #20
0
 public BitSetEnumeratedDomain(
     SetVar v, int[] sortedValues, boolean full, IEnvironment environment) {
   int a = sortedValues[0];
   int b = sortedValues[sortedValues.length - 1];
   capacity = b - a + 1; // number of entries
   this.offset = a;
   if (full) {
     size = environment.makeInt(sortedValues.length);
   } else {
     size = environment.makeInt(0);
   }
   contents = environment.makeBitSet(capacity);
   if (full) {
     // TODO : could be improved...
     for (int sortedValue : sortedValues) {
       contents.set(sortedValue - a);
     }
   }
   delatDom = new BitSetDeltaDomain(capacity, offset);
 }
Пример #21
0
  @Override
  public boolean instantiateTo(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    if (informCause) {
      cause = Cause.Null;
    }
    int lb = LB.get();
    if (this.instantiated()) {
      if (value != lb) {
        this.contradiction(cause, MSG_EMPTY);
      }
      return false;
    } else if (contains(value)) {

      int aValue = value - OFFSET;
      // todo delta
      this.VALUES.clear();
      this.VALUES.set(aValue);
      this.LB.set(value);
      this.UB.set(value);
      this.SIZE.set(1);

      if (VALUES.isEmpty()) {
        this.contradiction(cause, MSG_EMPTY);
      }

      filterOnLeq(cause, value);
      filterOnGeq(cause, value);

      this.notifyPropagators(EventType.INSTANTIATE, cause);
      return true;
    } else {
      this.contradiction(cause, MSG_UNKNOWN);
      return false;
    }
  }
Пример #22
0
 private void addIndex(int i) {
   contents.set(i);
   delatDom.remove(i + offset);
   if (!contents.get(i)) LOGGER.severe("etrange etrange");
   size.add(1);
 }
Пример #23
0
 @Override
 public boolean contains(int aValue) {
   // based on "Bounds Consistency Techniques for Long Linear Constraint"
   aValue -= OFFSET;
   return aValue >= 0 && VALUES.get(aValue);
 }
Пример #24
0
 private void removeIndex(int i) {
   contents.clear(i);
   delatDom.remove(i + offset);
   if (contents.get(i)) LOGGER.severe("etrange etrange");
   size.add(-1);
 }
Пример #25
0
  /**
   * Removes <code>value</code>from the domain of <code>this</code>. The instruction comes from
   * <code>propagator</code>.
   *
   * <ul>
   *   <li>If <code>value</code> is out of the domain, nothing is done and the return value is
   *       <code>false</code>,
   *   <li>if removing <code>value</code> leads to a dead-end (domain wipe-out), a <code>
   *       ContradictionException</code> is thrown,
   *   <li>otherwise, if removing <code>value</code> from the domain can be done safely, the event
   *       type is created (the original event can be promoted) and observers are notified and the
   *       return value is <code>true</code>
   * </ul>
   *
   * @param value value to remove from the domain (int)
   * @param cause removal releaser
   * @param informCause
   * @return true if the value has been removed, false otherwise
   * @throws solver.exception.ContradictionException if the domain become empty due to this action
   */
  public boolean removeValue(int value, ICause cause, boolean informCause)
      throws ContradictionException {
    // BEWARE: THIS CODE SHOULD NOT BE MOVED TO THE DOMAIN TO NOT DECREASE PERFORMANCES!
    boolean change = false;
    ICause antipromo = cause;
    if (informCause) {
      cause = Cause.Null;
    }
    int inf = getLB();
    int sup = getUB();
    if (value == inf && value == sup) {
      solver.getExplainer().removeValue(this, value, antipromo);
      this.contradiction(cause, MSG_REMOVE);
    } else {
      if (inf <= value && value <= sup) {
        EventType e = EventType.REMOVE;

        int aValue = value - OFFSET;
        change = VALUES.get(aValue);
        this.VALUES.set(aValue, false);
        if (change) {
          this.SIZE.add(-1);
          if (reactOnRemoval) {
            delta.add(aValue + OFFSET);
          }
        }

        if (value == inf) {
          LB.set(VALUES.nextSetBit(aValue));
          e = EventType.INCLOW;
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        } else if (value == sup) {
          UB.set(VALUES.prevSetBit(aValue));
          e = EventType.DECUPP;
          if (cause.reactOnPromotion()) {
            cause = Cause.Null;
          }
        }
        if (change && !VALUES.isEmpty()) {
          if (this.instantiated()) {
            e = EventType.INSTANTIATE;
            if (cause.reactOnPromotion()) {
              cause = Cause.Null;
            }
          }
          this.notifyPropagators(e, cause);
        } else {
          if (VALUES.isEmpty()) {
            solver.getExplainer().removeValue(this, value, antipromo);
            this.contradiction(cause, MSG_EMPTY);
          }
        }
      }
    }
    if (change) {
      solver.getExplainer().removeValue(this, value, antipromo);
    }
    return change;
  }
Пример #26
0
 /**
  * Returns the value following <code>x</code> if non exist return -1
  *
  * @param x starting value
  * @return value following x
  */
 public int getNextValue(int x) {
   int i = x - offset;
   int val = contents.nextSetBit(i + 1);
   if (val > 0) return val + offset;
   else return -1;
 }
Пример #27
0
 private void updateSpecialNodes(int u, int v) {
   if (graph[u].cardinality() == 0) sinkNodes.set(u, true);
   else sinkNodes.set(u, false);
   if (revGraph[v].cardinality() == 0) srcNodes.set(v, true);
   else srcNodes.set(v, false);
 }
Пример #28
0
 /**
  * Returns the value preceding <code>x</code> if non exist return -1
  *
  * @param x starting value
  * @return value preceding x
  */
 public int getPrevValue(int x) {
   int i = x - offset;
   int val = contents.prevSetBit(i - 1);
   if (val >= 0) return val + offset;
   else return -1;
 }
Пример #29
0
 /**
  * Checks if the value has a following value.
  *
  * @param x starting value
  * @return true whether there is a following value
  */
 public boolean hasNextValue(int x) {
   int i = x - offset;
   return (contents.nextSetBit(i + 1) != -1);
 }
Пример #30
0
 /**
  * Checks if the value has a preceding value.
  *
  * @param x starting value
  * @return true if there is a preceding value
  */
 public boolean hasPrevValue(int x) {
   int i = x - offset;
   return (contents.prevSetBit(i - 1) != -1);
 }