I would appreciate any advice. I think I may be looking over something simple.
I tested the main method with
6 8
2 1 5
0 2
0 1 3 4
5 4 2
3 2
3 0
I also am not sure about my bfs method for multiple nodes. I think my logic is right.
If I take the calculated to distTo[w] that would be the number of levels to the traveled node.
Then I could do the same from a second source. The distTo[w] with the largest value is the level
of the node that I am looking at (plus one actually but that is included in the calculation).
Does that logic make sense? This is an assignment.
Thanks for any advice/help in advance.
/*************************************************************************
* Compilation: javac BreadthFirstPaths.java
* Execution: java BreadthFirstPaths G s
* Dependencies: Digraph.java Queue.java Stack.java StdOut.java
* Data files: http://algs4.cs.princeton.edu/41undirected/tinyCG.txt
*
* Run breadth first search on an undirected graph.
* Runs in O(E + V) time.
*
* % java Digraph tinyCG.txt
* 6 8
* 0: 2 1 5
* 1: 0 2
* 2: 0 1 3 4
* 3: 5 4 2
* 4: 3 2
* 5: 3 0
*
* % java BreadthFirstPaths tinyCG.txt 0
* 0 to 0 (0): 0
* 0 to 1 (1): 0-1
* 0 to 2 (1): 0-2
* 0 to 3 (2): 0-2-3
* 0 to 4 (2): 0-2-4
* 0 to 5 (1): 0-5
*
*************************************************************************/
public class BreadthFirstPaths {
private static final int INFINITY = Integer.MAX_VALUE;
private boolean[] marked; // marked[v] = is there an s-v path
private int[] edgeTo; // edgeTo[v] = previous edge on shortest s-v path
private int[] distTo; // distTo[v] = number of edges shortest s-v path
private int [] levels; //levels[i] will keep track of the number of levels from each source
// single source
public BreadthFirstPaths(Digraph G, int s) {
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
bfs(G, s);
assert check(G, s);
}
// multiple sources
public BreadthFirstPaths(Digraph G, Iterable<Integer> sources) {
marked = new boolean[G.V()];
distTo = new int[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); v++) distTo[v] = INFINITY;
bfs(G, sources);
}
// BFS from single soruce
private void bfs(Digraph G, int s) {
Queue<Integer> q = new Queue<Integer>();
for (int v = 0; v < G.V(); v++) distTo[v] = INFINITY;
distTo[s] = 0;
marked[s] = true;
q.enqueue(s);
while (!q.isEmpty()) {
int v = q.dequeue();
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
}
}
}
// BFS from multiple sources
private void bfs(Digraph G, Iterable<Integer> sources) {
Queue<Integer> q = new Queue<Integer>();
int i = 0; //int that will keep track of what spot each new source's level will have in the array
for (int s : sources) {
marked[s] = true;
distTo[s] = 0;
q.enqueue(s);
}
while (!q.isEmpty()) {
int v = q.dequeue();
for (int w : G.adj(v)) {
if (!marked[w]) {
edgeTo[w] = v;
distTo[w] = distTo[v] + 1;
marked[w] = true;
q.enqueue(w);
}
levels[i] = distTo[w];//put the level value in the array
i++;//increase i so that for the next source, the level value will be in the next spot
}
}
int max = levels [0];
int index = 0;
for (int y = 0; y<levels.length; y++)
{
if (levels[y] > max)
{
max = levels[y]; // the new maximum
index = y; // index of current max
}
}
System.out.println("Minimum number of semesters is"+ index);
}
// is there a path between s (or sources) and v?
public boolean hasPathTo(int v) {
return marked[v];
}
// length of shortest path between s (or sources) and v
public int distTo(int v) {
return distTo[v];
}
// shortest path bewteen s (or sources) and v; null if no such path
public Iterable<Integer> pathTo(int v) {
if (!hasPathTo(v)) return null;
Stack<Integer> path = new Stack<Integer>();
int x;
for (x = v; distTo[x] != 0; x = edgeTo[x])
path.push(x);
path.push(x);
return path;
}
// check optimality conditions for single source
private boolean check(Digraph G, int s) {
// check that the distance of s = 0
if (distTo[s] != 0) {
StdOut.println("distance of source " + s + " to itself = " + distTo[s]);
return false;
}
// check that for each edge v-w dist[w] <= dist[v] + 1
// provided v is reachable from s
for (int v = 0; v < G.V(); v++) {
for (int w : G.adj(v)) {
if (hasPathTo(v) != hasPathTo(w)) {
StdOut.println("edge " + v + "-" + w);
StdOut.println("hasPathTo(" + v + ") = " + hasPathTo(v));
StdOut.println("hasPathTo(" + w + ") = " + hasPathTo(w));
return false;
}
if (hasPathTo(v) && (distTo[w] > distTo[v] + 1)) {
StdOut.println("edge " + v + "-" + w);
StdOut.println("distTo[" + v + "] = " + distTo[v]);
StdOut.println("distTo[" + w + "] = " + distTo[w]);
return false;
}
}
}
// check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1
// provided v is reachable from s
for (int w = 0; w < G.V(); w++) {
if (!hasPathTo(w) || w == s) continue;
int v = edgeTo[w];
if (distTo[w] != distTo[v] + 1) {
StdOut.println("shortest path edge " + v + "-" + w);
StdOut.println("distTo[" + v + "] = " + distTo[v]);
StdOut.println("distTo[" + w + "] = " + distTo[w]);
return false;
}
}
return true;
}
// test client
public static void main(String[] args) {
In in = new In(args[0]);
Digraph G = new Digraph(in);
// StdOut.println(G);
int s = Integer.parseInt(args[1]);
BreadthFirstPaths bfs = new BreadthFirstPaths(G, s);
for (int v = 0; v < G.V(); v++) {
if (bfs.hasPathTo(v)) {
StdOut.printf("%d to %d (%d): ", s, v, bfs.distTo(v));
for (int x : bfs.pathTo(v)) {
if (x == s) StdOut.print(x);
else StdOut.print("-" + x);
}
StdOut.println();
}
else {
StdOut.printf("%d to %d (-): not connected\n", s, v);
}
}
}
}

New Topic/Question
Reply



MultiQuote







|