All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.exigen.ie.constrainer.IntArrayCards Maven / Gradle / Ivy

package com.exigen.ie.constrainer;
import java.util.HashMap;

import com.exigen.ie.constrainer.impl.IntEvent;
import com.exigen.ie.constrainer.impl.IntExpAddArray;
import com.exigen.ie.constrainer.impl.IntExpCard;

/**
 * An implementation of the array of cardinalities for the integer expressions.
 * One can use IntArrayCards to control the number of occurences of several
 * values among the constrained variables in an array of constrained variables.
 * There is a simle example explaining the idea of using IntExpArray:
 * 
 *
 * Constariner C = new Constrainer('IntArrayCards_Test');
 * IntExpArray array =  new IntExpArray(C,10,0,9,'array');
 * IntArrayCards cards = new IntArrayCards(C,array);
 *
 * for (int i=0; i lt (array.max()-array.min()+1); i++){
 *    IntExp acard = cards.cardAt(i);
 *    C.postConstraint(acard.eq(1));
 * }
 * 
* * Here states that each integer value from the interval [0,9] must occure in the "array" * exactly once. So one can readily guess that the only possible solution is array[i] == i, * correct to permutations of the array's elements. IntArrayCards has the only * constructor {@link #IntArrayCards(Constrainer, IntExpArray)}. After being created * IntArrayCards becomes one to perform a policy of checking the number of occurrences * of every possible value among the constrained variables of IntExpArray using the "cards" * array. "cards" is an IntExpArray consisting of (array.max() - array.min() + 1) elements * (array is an IntExpArray to be controlled) so that it's i-th element defines the cardinality * of i+array.min() value. In other words, the number of occurrences must be within the * interval [cards.get(i).min(), cards.get(i).max()]. One can gain the access to the particular * card by using {@link #cardAt(int)} method. * */ public final class IntArrayCards extends Observer { int _min, _max; IntExpArray _vars; IntExpArray _cards; HashMap _index_map = new HashMap(); /** * Creates an array of cardinalities for an IntExpArray that * associates itself with each elements of controlled array in order to spy * on changes of their domains. * @param constrainer A particular constrainer the constructed array belongs to * @param vars An array to take control of * @throws Failure */ public IntArrayCards(Constrainer constrainer, IntExpArray vars) throws Failure { _vars = vars; //constrainer.propagate(); _min = vars.min(); _max = vars.max(); IntExp[] var_data = vars.data(); for(int i = 0; i < var_data.length; ++i) { var_data[i].attachObserver(this); _index_map.put(var_data[i], new Integer(i)); } int size = Math.max(1, _max - _min + 1); _cards = new IntExpArray(constrainer, size); for (int i = 0; i < size; ++i) { _cards.set(new IntExpCard(constrainer, _vars, _min + i), i); } // System.out.println("After build " + this); new IntExpAddArray(constrainer, _cards).equals(vars.size()).execute(); //System.out.println("After equals " + this); } /** * @return cards Array of cardinalities. */ public IntExpArray cards() { return _cards; } /** * Overrides the appropriate method of {@link Observer} class */ public void update(Subject subject, EventOfInterest event) throws Failure { IntEvent e = (IntEvent) event; // System.out.println("Update event: " + e); // System.out.println("++++ " + this); IntExp[] cards = _cards.data(); int var_index = this.getIndex(e.exp()); int type = e.type(); int max = e.max(); int min = e.min(); if ((type & EventOfInterestConstants.MIN) != 0) { int oldmin = e.oldmin(); for(int i = oldmin; i < min; ++i) { ((IntExpCard)cards[i - _min]).removeIndex(var_index); } } if ((type & EventOfInterestConstants.MAX) != 0) { int oldmax = e.oldmax(); for(int i = oldmax; i > max; --i) { ((IntExpCard)cards[i - _min]).removeIndex(var_index); } } if ((type & EventOfInterestConstants.REMOVE) != 0) { int nRemoves = e.numberOfRemoves(); for(int i = 0 ; i < nRemoves; ++i) { int removed = e.removed(i); if (min < removed && removed < max ) ((IntExpCard)cards[removed - _min]).removeIndex(var_index); } } if ((type & EventOfInterestConstants.VALUE) != 0) { ((IntExpCard)cards[min - _min]).addValueIndex(var_index); } // System.out.println("---- " + this); } int getIndex(IntExp exp) { return ((Integer) _index_map.get(exp)).intValue(); } /** * Returns cards[i-array.min()]. "array" is an array to be controlled. * @param i The number of value in the "array's" domain. * @return card */ public IntExpCard cardAt(int i) { return (IntExpCard) _cards.get(i - _min); } /** * * @return size Size of array of cardinalities. */ public int cardSize() { return _cards.size(); } public Object master() { return null; } public int subscriberMask() { return MIN | MAX |VALUE | REMOVE; } public String toString() { return "" + _cards + " card for " + _vars; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy