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

org.jgrapht.experimental.permutation.IntegerPermutationIter Maven / Gradle / Ivy

/* ==========================================
 * JGraphT : a free Java graph-theory library
 * ==========================================
 *
 * Project Info:  http://jgrapht.sourceforge.net/
 * Project Creator:  Barak Naveh (http://sourceforge.net/users/barak_naveh)
 *
 * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
 *
 * This program and the accompanying materials are dual-licensed under
 * either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation, or (at your option) any
 * later version.
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */
/* -----------------
 * IntegerPermutationIter.java
 * -----------------
 * (C) Copyright 2005-2008, by Assaf Lehr and Contributors.
 *
 * Original Author:  Assaf Lehr
 * Contributor(s):   -
 *
 * $Id$
 *
 * Changes
 * -------
 */
package org.jgrapht.experimental.permutation;

import java.util.*;


/**
 * Iterates through permutations of N elements.
 *
 * 
    *
  1. use getNext() to get the next permutation order, for example(N=4): * perm0=[1,2,3,4] perm1=[1,2,4,3] perm2=[1,3,2,4] . *
  2. use hasNext() or verify by counter<getTotalNumberOfPermutations () * that you do not overflow the max number. RunTimeException will be thrown if * you do. Getting the next permutation is done in O(N) Note: This class is not * thread safe. *
* * @author Assaf * @since May 20, 2005 */ public class IntegerPermutationIter implements Iterator, ArrayPermutationsIter { private int [] Value; private int N; private long permutationCounter; private boolean endWasReached = false; private boolean wasNextValueCalculatedAlready = false; /** * Will hold the current value. Will be changed only by getNext() */ private int [] currentValueBackup; /** * Creates an array of size N with elements 1,2,...,n-1 Useful for * describing regular permutations. See IntegerPermutationIter(int[] array) * for the other kind of permutations; efficency of initiation is O(N) * * @param N */ public IntegerPermutationIter(int N) { int [] newArray = new int[N]; // fill the array with 1,2,3... for (int i = 0; i < newArray.length; i++) { newArray[i] = i; } init(newArray); } /** * Uses a predefined array (sorted), for example: * [3,1,1,2,1]-->[1,1,1,2,3]; note that there are much less than 5! * premutations here, because of the repetitive 1s. * * @param array creates a copy of it (so sort / later changes will not * matter) */ public IntegerPermutationIter(int [] array) { int [] newArray = new int[array.length]; System.arraycopy(array, 0, newArray, 0, array.length); Arrays.sort(newArray); init(newArray); } private void init(int [] array) { this.N = array.length; this.Value = array; this.currentValueBackup = this.Value; permutationCounter = 0; } /** * Swaps by array indexes * * @param i * @param j */ private void swap(int i, int j) { int temp = this.Value[i]; this.Value[i] = this.Value[j]; this.Value[j] = temp; } private int [] arrayClone(int [] sourceArray) { int [] destArray = new int[sourceArray.length]; System.arraycopy(sourceArray, 0, destArray, 0, sourceArray.length); return destArray; } private int [] getNextStartingWith2() { permutationCounter++; int i = N - 1; if (i <= 0) // may happen only on N<=1 { this.endWasReached = true; return null; } /** while (Value[i-1] >= Value[i]) { i = i-1; }*/ while (Value[i - 1] >= Value[i]) { i = i - 1; if (i == 0) { this.endWasReached = true; return null; } } int j = N; while (Value[j - 1] <= Value[i - 1]) { j = j - 1; } swap(i - 1, j - 1); // swap values at positions (i-1) and (j-1) i++; j = N; while (i < j) { swap(i - 1, j - 1); i++; j--; } return this.Value; } /** * Efficiency: O(N) implementation, try to take the next! */ @Override public boolean hasNext() { if ((this.permutationCounter == 0) || (this.wasNextValueCalculatedAlready)) { return true; } else if (this.endWasReached) { return false; } boolean result = true; // calculate the next value into this.value save the current result. in // the end swap the arrays there is no way to know when to stop , but // the out-of-bound /* try * { * this.wasNextValueCalculatedAlready=true; * getNextStartingWith2(); * } * catch (ArrayIndexOutOfBoundsException outOfBoundException) * { * endWasReached=true; * result=false; * }*/ getNextStartingWith2(); this.wasNextValueCalculatedAlready = true; if (endWasReached) { return false; } ////////////////////////////// return result; } @Override public Object next() { return getNext(); } /** * Facade. use it with getNext. efficency: O(N) * * @return a new Array with the permutatation order. for example: * perm0=[1,2,3,4] perm1=[1,2,4,3] perm2=[1,3,2,4] */ public int [] getNext() { if (!hasNext()) { throw new RuntimeException( "IntegerPermutationIter exceeds the total number of permutaions." + " Suggestion: do a check with hasNext() , or count till getTotalNumberOfPermutations" + " before using getNext()"); } // if it is the first one , return original int [] internalArray; if (this.permutationCounter == 0) { this.permutationCounter++; internalArray = this.Value; } else { // if hasNext() has precaclulated it , take this value. if (this.wasNextValueCalculatedAlready) { internalArray = this.Value; this.wasNextValueCalculatedAlready = false; } else { internalArray = getNextStartingWith2(); if (this.endWasReached) { return null; } } } this.currentValueBackup = arrayClone(internalArray); return arrayClone(internalArray); } public int [] getCurrent() { return arrayClone(this.currentValueBackup); } /** * Utility method to convert the array into a string examples: [] [0] * [0,1][1,0] * * @param array */ public String toString(int [] array) { if (array.length <= 0) { return "[]"; } StringBuffer stBuffer = new StringBuffer("["); for (int i = 0; i < (array.length - 1); i++) { stBuffer.append(array[i]).append(","); } stBuffer.append(array[array.length - 1]).append("]"); return stBuffer.toString(); } /** * UNIMPLEMENTED. always throws new UnsupportedOperationException * * @see java.util.Iterator#remove() */ @Override public void remove() { throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see ArrayPermutationsIter#nextPermutation() */ @Override public int [] nextPermutation() { return (int []) next(); } /* (non-Javadoc) * @see ArrayPermutationsIter#hasNextPermutaions() */ @Override public boolean hasNextPermutaions() { return hasNext(); } } // End IntegerPermutationIter.java




© 2015 - 2024 Weber Informatics LLC | Privacy Policy