/** * Returns a shortest path between the source vertex {@code s} and vertex {@code v}. * * @param v the destination vertex * @return a shortest path between the source vertex {@code s} and vertex {@code v}; * {@code null} if no such path * @throws IllegalArgumentException unless {@code 0 <= v < V} */ public Iterable<Edge> pathTo(int v) { validateVertex(v); if (!hasPathTo(v)) return null; Stack<Edge> path = new Stack<Edge>(); int x = v; for (Edge e = edgeTo[v]; e != null; e = edgeTo[x]) { path.push(e); x = e.other(x); } return path; }
private Queue<Edge> mst = new Queue<Edge>(); // edges in MST /** * Compute a minimum spanning tree (or forest) of an edge-weighted graph. * @param G the edge-weighted graph */ public KruskalMST(EdgeWeightedGraph G) { // more efficient to build heap by passing array of edges MinPQ<Edge> pq = new MinPQ<Edge>(); for (Edge e : G.edges()) { pq.insert(e); } // run greedy algorithm UF uf = new UF(G.V()); while (!pq.isEmpty() && mst.size() < G.V() - 1) { Edge e = pq.delMin(); int v = e.either(); int w = e.other(v); if (!uf.connected(v, w)) { // v-w does not create a cycle uf.union(v, w); // merge v and w components mst.enqueue(e); // add edge e to mst weight += e.weight(); } } // check optimality conditions assert check(G); }
/** * Computes an Eulerian cycle in the specified graph, if one exists. * * @param G the graph */ public EulerianCycle(Graph G) { // must have at least one edge if (G.E() == 0) return; // necessary condition: all vertices have even degree // (this test is needed or it might find an Eulerian path instead of cycle) for (int v = 0; v < G.V(); v++) if (G.degree(v) % 2 != 0) return; // create local view of adjacency lists, to iterate one vertex at a time // the helper Edge data type is used to avoid exploring both copies of an edge v-w Queue<Edge>[] adj = (Queue<Edge>[]) new Queue[G.V()]; for (int v = 0; v < G.V(); v++) adj[v] = new Queue<Edge>(); for (int v = 0; v < G.V(); v++) { int selfLoops = 0; for (int w : G.adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { Edge e = new Edge(v, w); adj[v].enqueue(e); adj[w].enqueue(e); } selfLoops++; } else if (v < w) { Edge e = new Edge(v, w); adj[v].enqueue(e); adj[w].enqueue(e); } } } // initialize stack with any non-isolated vertex int s = nonIsolatedVertex(G); Stack<Integer> stack = new Stack<Integer>(); stack.push(s); // greedily search through edges in iterative DFS style cycle = new Stack<Integer>(); while (!stack.isEmpty()) { int v = stack.pop(); while (!adj[v].isEmpty()) { Edge edge = adj[v].dequeue(); if (edge.isUsed) continue; edge.isUsed = true; stack.push(v); v = edge.other(v); } // push vertex with no more leaving edges to cycle cycle.push(v); } // check if all edges are used if (cycle.size() != G.E() + 1) cycle = null; assert certifySolution(G); }
/** * Computes an Eulerian path in the specified graph, if one exists. * * @param G the graph */ public EulerianPath(Graph G) { // find vertex from which to start potential Eulerian path: // a vertex v with odd degree(v) if it exits; // otherwise a vertex with degree(v) > 0 int oddDegreeVertices = 0; int s = nonIsolatedVertex(G); for (int v = 0; v < G.V(); v++) { if (G.degree(v) % 2 != 0) { oddDegreeVertices++; s = v; } } // graph can't have an Eulerian path // (this condition is needed for correctness) if (oddDegreeVertices > 2) return; // special case for graph with zero edges (has a degenerate Eulerian path) if (s == -1) s = 0; // create local view of adjacency lists, to iterate one vertex at a time // the helper Edge data type is used to avoid exploring both copies of an edge v-w Queue<Edge>[] adj = (Queue<Edge>[]) new Queue[G.V()]; for (int v = 0; v < G.V(); v++) adj[v] = new Queue<Edge>(); for (int v = 0; v < G.V(); v++) { int selfLoops = 0; for (int w : G.adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { Edge e = new Edge(v, w); adj[v].enqueue(e); adj[w].enqueue(e); } selfLoops++; } else if (v < w) { Edge e = new Edge(v, w); adj[v].enqueue(e); adj[w].enqueue(e); } } } // initialize stack with any non-isolated vertex Stack<Integer> stack = new Stack<Integer>(); stack.push(s); // greedily search through edges in iterative DFS style path = new Stack<Integer>(); while (!stack.isEmpty()) { int v = stack.pop(); while (!adj[v].isEmpty()) { Edge edge = adj[v].dequeue(); if (edge.isUsed) continue; edge.isUsed = true; stack.push(v); v = edge.other(v); } // push vertex with no more leaving edges to path path.push(v); } // check if all edges are used if (path.size() != G.E() + 1) path = null; assert certifySolution(G); }
// run Prim's algorithm private void prim(EdgeWeightedGraph G, int s) { scan(G, s); while (!pq.isEmpty()) { // better to stop when mst has V-1 edges Edge e = pq.delMin(); // smallest edge on pq int v = e.either(), w = e.other(v); // two endpoints assert marked[v] || marked[w];