package org.matheclipse.combinatoric;

import java.util.Iterator;

import org.matheclipse.combinatoric.util.ArrayUtils;

/**
 * 

* An iterator that generates combinations of n elements, * C(n), in lexicographic order, based on Rosen's algorithm. *

* * @author Alistair A. Israel * @see "Kenneth H. Rosen, Discrete Mathematics and Its Applications, 2nd * edition (NY: McGraw-Hill, 1991), pp. 284-286" */ public class RosenIterator implements Iterator { protected final int n; protected final int k; private int[] a; protected long count; /** * @param n * the number of elements * @param k * taken k at a time */ public RosenIterator(final int n, final int k) { super(); this.n = n; this.k = k; this.count = count(n, k); } public void reset() { this.count = count(n, k); a = null; } /** * Computes the number of unique combinations of n elements taken * k at a time, which can be computed as: * n! / k! (n - k)! * * @param n * the number of elements * @param k * subset/sample size * @return the number of combinations of n elements taken * k at a time */ public static long count(final int n, final int k) { if (k < 0 || k > n) { throw new IllegalArgumentException("0 <= k <= " + n + "!"); } long count = 1; for (int i = 0; i < k; ++i) { count = count * (n - i) / (i + 1); } return count; } /** * {@inheritDoc} * * @see Iterator#hasNext() */ public final boolean hasNext() { return count > 0; } /** * {@inheritDoc} * * @see Iterator#next() */ public int[] next() { if (a == null) { initialize(); } else { int i = k - 1; while (a[i] == n - k + i) { i--; } a[i] = a[i] + 1; for (int j = i + 1; j < k; j++) { a[j] = a[i] + j - i; } } --count; return a; } /** * */ private void initialize() { this.a = ArrayUtils.identityPermutation(k); } /** * @author Alistair A. Israel */ public static class Factory implements Iterable { private final int n; private final int k; /** * @param n * the number of elements * @param k * taken k at a time */ public Factory(final int n, final int k) { this.n = n; this.k = k; } /** * {@inheritDoc} * * @see java.lang.Iterable#iterator() */ public final Iterator iterator() { return new RosenIterator(n, k); } } @Override public void remove() { throw new UnsupportedOperationException("This iterator doesn't support the remove() method"); } }

Ads help maintain this website.