00001 package edu.tum.cs.bayesnets.util;
00002
00003 import java.util.HashMap;
00004 import java.util.Vector;
00005
00006 import edu.ksu.cis.bnj.ver3.core.BeliefNetwork;
00007 import edu.ksu.cis.bnj.ver3.core.BeliefNode;
00008 import edu.ksu.cis.util.graph.core.Graph;
00009 import edu.ksu.cis.util.graph.core.Vertex;
00010
00011 public class TopologicalSort {
00012 protected BeliefNetwork bn;
00013
00014 public TopologicalSort(BeliefNetwork bn) {
00015 this.bn = bn;
00016 }
00017
00018 public TopologicalOrdering run() throws Exception {
00019 return run(false);
00020 }
00021
00022 public TopologicalOrdering run(boolean createTierMap) throws Exception {
00023 Graph g = bn.getGraph();
00024 BeliefNode[] nodes = bn.getNodes();
00025 HashMap<BeliefNode, Integer> tierMap = null;
00026 if(createTierMap)
00027 tierMap = new HashMap<BeliefNode,Integer>(nodes.length);
00028
00029 Vertex[] vertices = g.getVertices();
00030 int[] indeg = new int[vertices.length];
00031 for(Vertex v : vertices) {
00032 for(Vertex child : g.getChildren(v)) {
00033 assert vertices[child.loc()] != child;
00034 indeg[child.loc()]++;
00035 }
00036 }
00037
00038 Vector<Vector<Integer>> ret = new Vector<Vector<Integer>>();
00039 int numExtracted = 0;
00040 Integer numLevel = 0;
00041 int prevExtracted = -1;
00042 boolean debug = false;
00043 while(numExtracted < vertices.length) {
00044 if(prevExtracted == numExtracted)
00045 throw new Exception(String.format("Topological ordering could not be obtained because of cycles in the network (%d nodes remain).", vertices.length-numExtracted));
00046 prevExtracted = numExtracted;
00047 if(debug) System.out.println(numExtracted + " of " + vertices.length);
00048 Vector<Integer> level = new Vector<Integer>();
00049 int[] indeg2 = new int[indeg.length];
00050 for(int i = 0; i < indeg.length; i++) {
00051 indeg2[i] += indeg[i];
00052 if(indeg[i] == 0) {
00053 numExtracted++;
00054 indeg2[i] = -1;
00055 level.add(i);
00056 if(createTierMap)
00057 tierMap.put(nodes[i], numLevel);
00058 for(Vertex child : g.getChildren(vertices[i]))
00059 indeg2[child.loc()]--;
00060 }
00061 else if(debug)
00062 System.out.println(String.format(" %d %s", indeg[i], nodes[i].getName()));
00063 }
00064 indeg = indeg2;
00065 ret.add(level);
00066 numLevel++;
00067 }
00068 return new TopologicalOrdering(ret, tierMap);
00069 }
00070 }