Package util.objects

Source Code of util.objects.StoredIndexedBipartiteSet

/**
*  Copyright (c) 1999-2014, Ecole des Mines de Nantes
*  All rights reserved.
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions are met:
*
*      * Redistributions of source code must retain the above copyright
*        notice, this list of conditions and the following disclaimer.
*      * Redistributions in binary form must reproduce the above copyright
*        notice, this list of conditions and the following disclaimer in the
*        documentation and/or other materials provided with the distribution.
*      * Neither the name of the Ecole des Mines de Nantes nor the
*        names of its contributors may be used to endorse or promote products
*        derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
*  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
*  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package util.objects;

import memory.IEnvironment;
import memory.IStateInt;
import memory.structure.IndexedObject;
import solver.exception.SolverException;
import util.iterators.DisposableIntIterator;

import java.util.ArrayList;

/**
* A stored list dedicated to positive integers and three operations :
* - iteration
* - removal of an element
* - check if an element is or not within the list
* It only requires a StoredInt to denote the first element of the list
* and proceeds by swapping element with the first one to remove them and incrementing
* the index of the first element.
* IT DOES NOT PRESERVE THE ORDER OF THE LIST
*/
public class StoredIndexedBipartiteSet /*implements IStateIntVector */{

    /**
     * The list of values
     */
    protected int[] list;

    /**
     * The position of each element within the list.
     * indexes[3] = k <=> list[k] = 3
     * we assume that elements ranges from 0 ... list.lenght
     * in other words the elements must be indexed.
     */
    protected int[] position;

    /**
     * If objects are added to the list, a mapping from their
     * indexes is needed.
     * idxToObjects[i] = o <=> o.getObjectIdx() == i
     */
    private IndexedObject[] idxToObjects;

    /**
     * The first element of the list
     */
    protected IStateInt last;

    protected BipartiteSetIterator _cachedIterator;

    /**
     * @param environment
     * @param values:     a set of DIFFERENT positive integer values !
     */
    public StoredIndexedBipartiteSet(final IEnvironment environment, final int[] values) {
        buildList(environment, values);
    }

    /**
     * @param environment
     * @param values:     a set of IndexObjects which have different indexes !
     */
    public StoredIndexedBipartiteSet(final IEnvironment environment, final IndexedObject[] values) {
        final int[] intvalues = new int[values.length];
        for (int i = 0; i < intvalues.length; i++) {
            intvalues[i] = values[i].getObjectIdx();
        }
        buildList(environment, intvalues);
        idxToObjects = new IndexedObject[position.length];
        for (int i = 0; i < intvalues.length; i++) {
            idxToObjects[values[i].getObjectIdx()] = values[i];
        }
    }

    /**
     * @param environment
     * @param values:     a set of IndexObjects which have different indexes !
     */
    public StoredIndexedBipartiteSet(final IEnvironment environment, final ArrayList<IndexedObject> values) {
        final int[] intvalues = new int[values.size()];
        for (int i = 0; i < intvalues.length; i++) {
            intvalues[i] = values.get(i).getObjectIdx();
        }
        buildList(environment, intvalues);
        idxToObjects = new IndexedObject[position.length];
        for (int i = 0; i < intvalues.length; i++) {
            idxToObjects[values.get(i).getObjectIdx()] = values.get(i);
        }
    }

    public void buildList(final IEnvironment environment, final int[] values) {
        this.list = values;
        int maxElt = 0;
        for (int i = 0; i < values.length; i++) {
            if (values[i] > maxElt) {
                maxElt = values[i];
            }
        }
        this.position = new int[maxElt + 1];
        for (int i = 0; i < values.length; i++) {
            position[values[i]] = i;
        }
        this.last = environment.makeInt(list.length - 1);
    }

    /**
     * Create a stored bipartite set with a size.
     * Thus the value stored will go from 0 to nbValues.
     *
     * @param environment
     * @param nbValues
     */
    public StoredIndexedBipartiteSet(final IEnvironment environment, final int nbValues) {
        final int[] values = new int[nbValues];
        for (int i = 0; i < nbValues; i++) {
            values[i] = i;
        }
        buildList(environment, values);
    }

    /**
     * Increase the number of value watched.
     * BEWARE: be sure your are correctly calling this method.
     * It deletes everything already declared
     *
     * @param gap the gap the reach the expected size
     */
    public final void increaseSize(final int gap) {
        final int l = list.length;
        final int[] newList = new int[l + gap];
        for (int i = 0; i < l + gap; i++) {
            newList[i] = i;
        }
        int maxElt = 0;
        for (int i = 0; i < newList.length; i++) {
            if (newList[i] > maxElt) {
                maxElt = newList[i];
            }
        }
        final int[] newPosition = new int[maxElt + 1];
        for (int i = 0; i < newList.length; i++) {
            newPosition[newList[i]] = i;
        }
        // record already removed values
        final int end = last.get() + 1;
        final int[] removed = new int[list.length - end];
        System.arraycopy(list, end, removed, 0, list.length - end);

        this.list = newList;
        this.position = newPosition;
        final IEnvironment env = last.getEnvironment();
        this.last = null;
        this.last = env.makeInt(list.length - 1);
        for (int i = 0; i < removed.length; i++) {
            remove(removed[i]);
        }
    }

    public final int size() {
        return last.get() + 1;
    }

    public final boolean isEmpty() {
        return last.get() == -1;
    }

    public final void add(final int i) {
        throw new UnsupportedOperationException("adding element is not permitted in this structure (the list is only meant to decrease during search)");
    }

    public final void clear() {
        last.set(-1);
    }

    public final void removeLast() {
        remove(list[last.get()]);
    }

    public void remove(final int object) {
        if (contains(object)) {
            final int idxToRem = position[object];
            if (idxToRem == last.get()) {
                last.add(-1);
            } else {
                final int temp = list[last.get()];
                list[last.get()] = object;
                list[idxToRem] = temp;
                position[object] = last.get();
                position[temp] = idxToRem;
                last.add(-1);
            }
        }
    }

    //we assume that the object belongs to the list
    public final void remove(final IndexedObject object) {
        remove(object.getObjectIdx());
    }

    public boolean contains(final int object) {
        return position[object] <= last.get();
    }

    public final boolean contains(final IndexedObject object) {
        return contains(object.getObjectIdx());
    }

    public final int get(final int index) {
        return list[index];
    }

    public final IndexedObject getObject(final int index) {
        return idxToObjects[list[index]];
    }

    public final int set(final int index, final int val) {
        throw new SolverException("setting an element is not permitted on this structure");
    }

    public final DisposableIntIterator getIterator() {
        if (_cachedIterator == null || !_cachedIterator.isReusable()) {
            _cachedIterator = new BipartiteSetIterator();
        }
        _cachedIterator.init(list, position, last, idxToObjects);
        return _cachedIterator;
    }

    public final String pretty() {
        final StringBuilder s = new StringBuilder("[");
        for (int i = 0; i <= last.get(); i++) {
            s.append(list[i]).append(i == (last.get()) ? "" : ",");
        }
        return s.append(']').toString();
    }

    //a is not in the list, returns its index k in the table from
    //the end of the list.
    //It basically means that a was the k element to be removed
    public final int findIndexOfInt(final int a) {
        return list.length - position[a];
    }

    /**
     * DO NOT USE : FOR MEMORY OPTIM ONLY
     */
    public final int[] _getStructure() {
        return list;
    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    protected static class BipartiteSetIterator extends DisposableIntIterator {

        private int[] list;

        private int[] position;

        private IndexedObject[] idxToObjects;

        private IStateInt last;

        private int nlast, idx;

        /**
         * Freeze the iterator, cannot be reused.
         */
        public void init(final int[] aList, final int[] aPosition, final IStateInt aLast, final IndexedObject[] anIdxToObjects) {
            super.init();
            idx = 0;
            list = aList;
            position = aPosition;
            idxToObjects = anIdxToObjects;
            last = aLast;
            nlast = last.get();
        }

        /**
         * Returns <tt>true</tt> if the iteration has more elements. (In other
         * words, returns <tt>true</tt> if <tt>next</tt> would return an element
         * rather than throwing an exception.)
         *
         * @return <tt>true</tt> if the iterator has more elements.
         */
        @Override
        public boolean hasNext() {
            return idx <= nlast;
        }

        /**
         * Returns the next element in the iteration.
         *
         * @return the next element in the iteration.
         * @throws java.util.NoSuchElementException
         *          iteration has no more elements.
         */
        @Override
        public int next() {
            return list[idx++];
        }


        public IndexedObject nextObject() {
            return idxToObjects[list[idx++]];
        }

        /**
         * Removes from the underlying collection the last element returned by the
         * iterator (optional operation).  This method can be called only once per
         * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
         * the underlying collection is modified while the iteration is in
         * progress in any way other than by calling this method.
         *
         * @throws UnsupportedOperationException if the <tt>remove</tt>
         *                                       operation is not supported by this Iterator.
         * @throws IllegalStateException         if the <tt>next</tt> method has not
         *                                       yet been called, or the <tt>remove</tt> method has already
         *                                       been called after the last call to the <tt>next</tt>
         *                                       method.
         */
        @Override
        public void remove() {
            idx--;
            final int idxToRem = idx;
            if (idxToRem == nlast) {
                last.add(-1);
                nlast--;
            } else {
                final int temp = list[nlast];
                list[nlast] = list[idxToRem];
                list[idxToRem] = temp;
                position[list[nlast]] = last.get();
                position[temp] = idxToRem;
                last.add(-1);
                nlast--;
            }
        }
    }
}
TOP

Related Classes of util.objects.StoredIndexedBipartiteSet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.