// GraphAlgs.java - mjd@cs.auckland.ac.nz // // edit log: fixed off-by-one error in maxDistance (30-Aug-2000) // fixed off-by-one error getBFSparents (13-Sep-2000) // zero initialized parents[] in getBFSparents (21-May-2006) // replaced Queue with LinkList from Java 1.5 (05-Sep-2006) // topSort1 now returns 0 for nodes not reached (03-Sep-2007) /* //Update - Enumeration completely removed as the class now uses for each loops. // - many for incremental loops replaced with for each loops (basically if you used take the ith element in an integer array // you now use a for each element of the integer array.) <-- saves you casting and searching // - some of the new Integer(v) things have been changed to just v: where its obvious the addition is an integer; // i.e it is being added to an ArrayList // -when making a undirected graph it now checks what the graph coming in is (either a matrix or lists form) then makes // the appropriate uGraph of it - FIXED // -edited graphADT to take conversion constructors allowing for uGraph = new uGraphLists(G); // where G is any representation of the Graph interface */ package graphAlgs; import graphADT.*; import java.util.ArrayList; import java.util.BitSet; import java.util.LinkedList; public class GraphAlgs{ public static void getBFSparents(Graph G, int v, int[] parent){ // indices off by one int n = G.order(); for (int i=0; i toGrow = new LinkedList(); toGrow.addLast(new Integer(v)); while (toGrow.peek() != null){ int grow = toGrow.removeFirst(); ArrayList nbrs = G.neighbors(grow); for (int i : nbrs){ if (parent[i] == 0){ parent[i] = grow+1; toGrow.addLast(new Integer(i)); } } } return; } public static int BFS(Graph G, int v, int[] LevelOrder){ int n = G.order(); for (int i=0; i toGrow = new LinkedList(); int cnt = 0; LevelOrder[v] = ++cnt; toGrow.addLast(new Integer(v)); while (toGrow.peek() != null){ int grow = toGrow.removeFirst(); ArrayList nbrs = G.neighbors(grow); for (int i : nbrs){ if ( LevelOrder[i] == 0 ){ LevelOrder[i] = ++cnt; toGrow.addLast(new Integer(i)); } } } return cnt; } private static class countPair{ // private counters for DFS search int cnt1, cnt2; int inc1() { return ++cnt1; } // increment and return counters int inc2() { return ++cnt2; } } private static void doDFS(Graph G, int v, int[] PreOrder, int[] PostOrder, countPair cnt){ PreOrder[v] = cnt.inc1(); ArrayList nbrs = G.neighbors(v); for (int i : nbrs){ if ( PreOrder[i] == 0 ){ doDFS(G, i, PreOrder, PostOrder, cnt); } } PostOrder[v] = cnt.inc2(); return; } public static int DFS(Graph G, int v, int[] PreOrder, int[] PostOrder){ int n = G.order(); for (int i=0; i nbrs = G.neighbors(i); for (int k : nbrs){ R.addArc(k,i); } } return (DFS(R,0,pre,post) == n); } public static ArrayList strongComponents(Graph G){ // vector of subsets of V(G) ArrayList SCC = new ArrayList(); // .... return SCC; } public static void getDFSparents(Graph G, int v, int[] parent){ // indices off by one if (parent[v]==0) parent[v]=v+1; // root is its own parent ArrayList nbrs = G.neighbors(v); for (int i : nbrs){ if ( parent[i] == 0 ){ parent[i]=v+1; getDFSparents(G, i, parent); } } } public static boolean isAcyclic(Graph G){ // no directed cycles? int n=G.order(); int[] PreOrder = new int[n]; int[] PostOrder = new int[n]; boolean[] span = new boolean[n]; for (int i=0; i 0) span[j] = true; // if (PreOrder[j] <= 2) continue; // no back-edge cycles ArrayList nbrs = G.neighbors(j); for (int k : nbrs){ if (// PreOrder[k] < PreOrder[j] && PostOrder[k] > PostOrder[j] ) return false; // Bingo! // note: PreOrder[k] > 0 since u is reachable from j } } if (cnt == n) break; // all vertices spanned } return true; } public static boolean isAcyclic(uGraph G){ // no undirected cycles? int n=G.order(); int m=G.size(); // for O(n) running time [adjacency lists] if (m >= n) return false; int[] PreOrder = new int[n]; int[] PostOrder = new int[n]; countPair cnt = new countPair(); int components = 0; for (int i=0; i 0) continue; // try next component with root i doDFS(G, i, PreOrder, PostOrder, cnt); components++; } return n == m + components; } public static int girth(Graph Gin){ // returns minimum girth >= 3. //makes an undirected copy of Gin uGraph G = new uGraphLists(Gin); //uGraph G = new uGraphMatrix(Gin); int n=G.order(); int best = n+1; // girth n+1 if no cycles found for (int i=0; i distList = new ArrayList(); distList.add(i); while (depth*2 <= best && best > 3){ ArrayList nextList = new ArrayList(); for(int e : distList){ ArrayList nbrs = G.neighbors(e); for (int k : nbrs){ if (!span.get(k)){ span.set(k); nextList.add(k); }else{ // we have found some walk/cycle // is there a cross edge at this level // if ( distList.contains(k) ){ best = depth*2-1; break; } // else even length cycle (as upper bound) // if ( nextList.contains(k) ){ best = depth*2; } } } } // for vertices at current depth distList = nextList; // next try set of vertices further away depth++; } } return best; } public static boolean isBipartite(Graph Gin){ //makes an undirected copy of Gin uGraph G = new uGraphLists(Gin); // color underlying graph //uGraph G = new uGraphMatrix(Gin); int n = G.order(); int color[] = new int[n]; // will toggle between 1 and 2 for (int v = 0; v < n; v++){ // start at first vertex if (color[v]>0) continue; color[v] = 1; LinkedList toGrow = new LinkedList();// use BFS queue search toGrow.addLast(new Integer(v)); while (toGrow.peek() != null){ int grow = toGrow.removeFirst(); ArrayList nbrs = G.neighbors(grow); for (int u : nbrs){ if ( color[u] == 0 ){ // not colored yet color[u] = 3 - color[grow]; // set to other color toGrow.addLast(new Integer(u)); }else{ // check for different color if ( color[u] == color[grow] ) return false; } } } // more nodes in this component } // while all components have been checked return true; } public static int[] topSort1(Graph G, int firstV){ int n = G.order(); int[] PreOrder = new int[n]; int[] PostOrder = new int[n]; int[] sort = new int[n]; int cnt = DFS(G, firstV, PreOrder, PostOrder); for (int i=0; i0) sort[i] = cnt-PostOrder[i]+1; return sort; } public static int[] topSort2(Graph G){ int n = G.order(); int[] sort = new int[n]; int[] inDeg = new int[n]; for (int i=0; i nbrs = G.neighbors(v); for (int u : nbrs){ inDeg[u] = inDeg[u] - 1; } } } // for v } // while nodes exist with inDegree == 0. return sort; } public static int maxDistance(Graph G, int v, int dist[]){ int n = G.order(); for (int i=0; i distList = new ArrayList(); distList.add( new Integer(v) ); while ( distList.size() > 0 ){ depth++; ArrayList nextList = new ArrayList(); for (int e : distList){ ArrayList nbrs = G.neighbors(e); for (int u : nbrs){ if (dist[u] == n){ dist[u] = depth; cnt++; nextList.add(u); } } } distList = nextList; // next try set of vertices further away } return cnt == n ? depth-1 : n; } public static int[][] distanceMatrix(Graph G){ int n = G.order(); int D[][] = new int[n][n]; for (int v=0; v max ? d : max; } return max; } } // class GraphAlgs