From 15c5aa6e4869a4ca81e3e1c4c29e322ebea9262b Mon Sep 17 00:00:00 2001 From: fromer Date: Thu, 19 Aug 2010 14:14:37 +0000 Subject: [PATCH] Efficient iteration over all possible combinations of variable assignments, for variables of arbitrary cardinalities git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@4059 348d0f76-0448-11de-a6fe-93d51630548a --- .../sting/utils/CardinalityCounter.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 java/src/org/broadinstitute/sting/utils/CardinalityCounter.java diff --git a/java/src/org/broadinstitute/sting/utils/CardinalityCounter.java b/java/src/org/broadinstitute/sting/utils/CardinalityCounter.java new file mode 100644 index 000000000..13ba4699f --- /dev/null +++ b/java/src/org/broadinstitute/sting/utils/CardinalityCounter.java @@ -0,0 +1,67 @@ +package org.broadinstitute.sting.utils; + +import java.util.Iterator; + +/** + * Created by IntelliJ IDEA. + * User: fromer + * Date: Aug 19, 2010 + * Time: 9:33:54 AM + * To change this template use File | Settings | File Templates. + */ + +/* +* CardinalityCounter object allows user to iterate over all assignment of arbitrary-cardinality variables. + */ +public class CardinalityCounter implements Iterator, Iterable { + private int[] cards; + private int[] valList; + private boolean hasNext; + + public CardinalityCounter(int[] cards) { + this.cards = cards; + this.valList = new int[cards.length]; + for (int i = 0; i < cards.length; i++) { + if (this.cards[i] <= 0) + throw new IllegalArgumentException("CANNOT have zero cardinalities!"); + this.valList[i] = 0; + } + this.hasNext = true; + } + + public boolean hasNext() { + return hasNext; + } + + public int[] next() { + if (!hasNext()) + throw new StingException("CANNOT iterate past end!"); + + // Copy the assignment to be returned: + int[] nextList = new int[valList.length]; + for (int i = 0; i < valList.length; i++) + nextList[i] = valList[i]; + + // Find the assignment after this one: + hasNext = false; + int i = cards.length - 1; + for (; i >= 0; i--) { + if (valList[i] < (cards[i] - 1)) { + valList[i]++; + hasNext = true; + break; + } + valList[i] = 0; + } + + return nextList; + } + + public void remove() { + throw new RuntimeException("Cannot remove from CardinalityCounter!"); + } + + public Iterator iterator() { + return this; + } +}