package org.matheclipse.combinatoric;
import org.matheclipse.combinatoric.util.ArrayUtils;
/**
* Partition an ordered multi-set and visit all steps of the algorithm with a
* IStepVisitor
*
* @see IStepVisitor
*/
public class MultisetPartitionsIterator {
private final int n;
private final int[] multiset;
private final int[][] result;
private RosenNumberPartitionIterator rosen;
private IStepVisitor handler;
/**
* Partition an ordered multi-set and visit all steps of the algorithm with an
* IStepVisitor.
*
* @param visitor
* the visitor which controls the steps of the algorithm
* @param k
* the number of partitioning the n elements into k parts
*/
public MultisetPartitionsIterator(IStepVisitor visitor, final int k) {
int[] mset = visitor.getMultisetArray();
this.n = mset.length;
this.multiset = mset;
this.result = new int[k][];
this.rosen = new RosenNumberPartitionIterator(n, k);
this.handler = visitor;
}
public void reset() {
rosen.reset();
for (int i = 0; i < result.length; i++) {
result[i] = null;
}
}
public boolean execute() {
try {
while (rosen.hasNext()) {
final int[] actualRosen = rosen.next();
recursiveMultisetCombination(multiset, actualRosen, 0);
}
} catch (StopException e) {
// stop this algorithm immediately
return false;
}
return true;
}
private void recursiveMultisetCombination(int[] multiset, final int[] actualRosen, int i) throws StopException {
if (i < actualRosen.length) {
final MultisetCombinationIterator iter = new MultisetCombinationIterator(multiset, actualRosen[i]);
while (iter.hasNext()) {
final int[] currentSubset = iter.next();
result[i] = currentSubset;
// Status status = handler.verify(i, result);
// if (status != Status.OK) {
// if (status == Status.FORWARD) {
// continue;
// } else if (status == Status.BACKTRACK) {
// return;
// }
// throw new StopException();
// }
int[] wc = ArrayUtils.deleteSubset(multiset, currentSubset);
recursiveMultisetCombination(wc, actualRosen, i + 1);
}
} else {
if (!handler.visit(result)) {
throw new StopException();
}
}
}
}
Ads help maintain this website.