/*******************************************************************************
* Copyright (C) 2008-2012 Dominik Jain.
*
* This file is part of ProbCog.
*
* ProbCog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProbCog is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProbCog. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package probcog.bayesnets.util;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Vector;
import edu.ksu.cis.bnj.ver3.core.BeliefNode;
/**
*
* @author Dominik Jain
*/
public class TopologicalOrdering implements Iterable<Integer> {
/**
* a vector of tiers reflecting the partial ordering of the nodes; the nodes in each tier (sub-vector) are equivalent with respect to the ordering
*/
Vector<Vector<Integer>> partialOrder;
/**
* a mapping from belief nodes to 0-based tier indices (i.e. depth in the ordering)
*/
HashMap<BeliefNode, Integer> tierMap;
public TopologicalOrdering(Vector<Vector<Integer>> partialOrder, HashMap<BeliefNode, Integer> tierMap) {
this.partialOrder = partialOrder;
this.tierMap = tierMap;
}
public java.util.Iterator<Integer> iterator() {
return new Iterator(this);
}
public static class Iterator implements java.util.Iterator<Integer> {
int idxCurrentLevel;
Vector<Integer> currentLevel;
Random random;
TopologicalOrdering ordering;
public Iterator(TopologicalOrdering ordering) {
this.ordering = ordering;
idxCurrentLevel = 0;
currentLevel = new Vector<Integer>(ordering.partialOrder.get(0));
random = new Random();
}
public boolean hasNext() {
return currentLevel != null && !currentLevel.isEmpty();
}
public Integer next() {
if(!hasNext())
throw new NoSuchElementException();
int idxNext = random.nextInt(currentLevel.size());
int nextElem = currentLevel.remove(idxNext);
if(currentLevel.isEmpty()) {
++idxCurrentLevel;
if(idxCurrentLevel < ordering.partialOrder.size())
currentLevel = new Vector<Integer>(ordering.partialOrder.get(idxCurrentLevel));
else
currentLevel = null;
}
return nextElem;
}
public void remove() {
throw new RuntimeException("remove() is not supported by this constant iterator.");
}
}
/**
* gets the tier (i.e. depth in the ordering) of the given node
* @param n a belief node
* @return 0-based tier
*/
public int getTier(BeliefNode n) {
if(tierMap == null)
throw new RuntimeException("Topological ordering has no tier map!");
return tierMap.get(n);
}
public int getNumTiers() {
return partialOrder.size();
}
/**
* gets the vector of indices of nodes belonging to the given tier
* @param index
* @return
*/
public Vector<Integer> getTier(int index) {
return partialOrder.get(index);
}
public Vector<Vector<Integer>> getTiers() {
return partialOrder;
}
}