00001 package gov.nasa.arc.ase.util.graph;
00002
00003 import java.io.IOException;
00004
00005
00006
00007
00008
00009 import java.util.List;
00010 import java.util.Iterator;
00011 import java.util.LinkedList;
00012
00013
00014 public class SCC {
00015 private static class SCCState {
00016 public int N = 0;
00017 public int SCC = 0;
00018 public List L = new LinkedList();
00019 }
00020
00021 public static void help() {
00022 System.err.println("usage:");
00023 System.err.println("\tDegenalize [-join|-degeneralize] [outfile]");
00024 System.exit(1);
00025 }
00026 public static void main(String[] args) {
00027 String outname = null;
00028
00029 for(int i = 0, l = args.length; i < l; i++) {
00030 if(outname == null)
00031 outname = args[i];
00032 else
00033 help();
00034 }
00035
00036 try {
00037
00038 Graph g = Graph.load(System.getProperty("user.dir")+java.io.File.separator+"out.sm");
00039
00040
00041
00042
00043 List scc = scc(g);
00044
00045 for(Iterator i = scc.iterator(); i.hasNext(); ) {
00046 List l = (List)i.next();
00047 System.out.println("component:");
00048 for(Iterator j = l.iterator(); j.hasNext(); ) {
00049 Node n = (Node)j.next();
00050
00051 System.out.println(" " + n.getStringAttribute("label"));
00052 }
00053 System.out.println();
00054 }
00055
00056 if(outname == null)
00057 g.save();
00058 else
00059
00060 g.save(System.getProperty("user.dir")+java.io.File.separator+outname);
00061
00062
00063
00064 } catch(IOException e) {
00065 e.printStackTrace();
00066 return;
00067 }
00068 }
00069 public static void print(List sccs) {
00070 System.out.println("Strongly connected components:");
00071
00072 int cnt = 0;
00073 for(Iterator i = sccs.iterator(); i.hasNext(); ) {
00074 List scc = (List)i.next();
00075
00076 System.out.println("\tSCC #" + (cnt++));
00077 for(Iterator j = scc.iterator(); j.hasNext(); ) {
00078 Node n = (Node)j.next();
00079 System.out.println("\t\t" + n.getId() + " - " +
00080 n.getStringAttribute("label"));
00081 }
00082 }
00083 }
00084 public static List scc(Graph g) {
00085 Node init = g.getInit();
00086
00087 if(init == null) return new LinkedList();
00088
00089 init.setBooleanAttribute("_reached", true);
00090 SCCState s = new SCCState();
00091 visit(init, s);
00092
00093 final List[] scc = new List[s.SCC];
00094 for(int i = 0; i < s.SCC; i++)
00095 scc[i] = new LinkedList();
00096
00097 g.forAllNodes(new EmptyVisitor() {
00098 public void visitNode(Node n) {
00099 scc[n.getIntAttribute("_scc")].add(n);
00100
00101 n.setBooleanAttribute("_reached", false);
00102 n.setBooleanAttribute("_dfsnum", false);
00103 n.setBooleanAttribute("_low", false);
00104 n.setBooleanAttribute("_scc", false);
00105 }
00106 });
00107
00108 List list = new LinkedList();
00109 for(int i = 0; i < s.SCC; i++)
00110 list.add(scc[i]);
00111
00112 return list;
00113 }
00114 private static void visit(Node p, SCCState s) {
00115 s.L.add(0, p);
00116 p.setIntAttribute("_dfsnum", s.N);
00117 p.setIntAttribute("_low", s.N);
00118 s.N++;
00119 for(Iterator i = p.getOutgoingEdges().iterator(); i.hasNext(); ) {
00120 Edge e = (Edge)i.next();
00121 Node q = e.getNext();
00122
00123 if(!q.getBooleanAttribute("_reached")) {
00124 q.setBooleanAttribute("_reached", true);
00125 visit(q, s);
00126 p.setIntAttribute("_low", Math.min(p.getIntAttribute("_low"),
00127 q.getIntAttribute("_low")));
00128 } else
00129 if(q.getIntAttribute("_dfsnum") < p.getIntAttribute("_dfsnum"))
00130 if(s.L.contains(q))
00131 p.setIntAttribute("_low", Math.min(p.getIntAttribute("_low"),
00132 q.getIntAttribute("_dfsnum")));
00133 }
00134
00135 if(p.getIntAttribute("_low") == p.getIntAttribute("_dfsnum")) {
00136 Node v;
00137 do {
00138 v = (Node)s.L.remove(0);
00139 v.setIntAttribute("_scc", s.SCC);
00140 } while(v != p);
00141 s.SCC++;
00142 }
00143 }
00144 }