package org.matheclipse.core.generic.combinatoric;
import java.util.Iterator;
/**
* This class returns the indexes for partitioning a list of N elements.
* Usage pattern:
*
*
* final KPartitionsIterable iter = new KPartitionsIterable(n, k);
* for (int[] partitionsIndex : iter) {
* ...
* }
*
*
* Example: KPartitionsIterable(3,5) gives the following sequences [0, 1, 2],
* [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4]
* If you interpret these integer lists as indexes for a list {a,b,c,d,e} which
* should be partitioned into 3 parts the results are:
* {{{a},{b},{c,d,e}}, {{a},{b,c},{d,e}}, {{a},{b,c,d},{e}}, {{a,b},{c},{d,e}},
* {{a,b},{c,d},{e}}, {{a,b,c},{d},{e}}}
*
*
*
* See Wikipedia -
* Partition of a set
*/
public class KPartitionsIterable implements Iterator, Iterable {
final private int fLength;
final private int fNumberOfParts;
final private int fPartitionsIndex[];
final private int fCopiedResultIndex[];
private int fResultIndex[];
public KPartitionsIterable(final int length, final int parts) {
super();
fLength = length;
fNumberOfParts = parts;
fPartitionsIndex = new int[fNumberOfParts];
fCopiedResultIndex = new int[fNumberOfParts];
fPartitionsIndex[0] = -1;
fResultIndex = nextBeforehand();
}
public final void reset() {
fResultIndex = null;
for (int i = 1; i < fNumberOfParts; i++) {
fPartitionsIndex[i] = 0;
}
fPartitionsIndex[0] = -1;
fResultIndex = nextBeforehand();
}
/**
* Get the index array for the next partition.
*
* @return null if no further index array could be generated
*/
private final int[] nextBeforehand() {
if (fPartitionsIndex[0] < 0) {
for (int i = 0; i < fNumberOfParts; ++i) {
fPartitionsIndex[i] = i;
}
return fPartitionsIndex;
} else {
int i = 0;
for (i = fNumberOfParts - 1; (i >= 0) && (fPartitionsIndex[i] >= fLength - fNumberOfParts + i); --i) {
}
if (i <= 0) {
return null;
}
fPartitionsIndex[i]++;
for (int m = i + 1; m < fNumberOfParts; ++m) {
fPartitionsIndex[m] = fPartitionsIndex[m - 1] + 1;
}
return fPartitionsIndex;
}
}
/**
* Get the index array for the next partition.
*
* @return null if no further index array could be generated
*/
public int[] next() {
System.arraycopy(fResultIndex, 0, fCopiedResultIndex, 0, fResultIndex.length);
fResultIndex = nextBeforehand();
return fCopiedResultIndex;
}
public boolean hasNext() {
return fResultIndex != null;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Iterator iterator() {
return this;
}
}
Ads help maintain this website.