Warm tip: This article is reproduced from serverfault.com, please click

Why aren't my Words connecting in Undirected/Unweighted Graph when using BFS?

发布于 2020-11-26 14:07:19

Issue in my code, not sure why NO connections are found in the Graph built with the words.

ArrayList<String> words = new ArrayList<String>();
words.add("hello");
words.add("there");
words.add("here");
words.add("about");
                
Graph g = new Graph(words.size());
for(String word: words) {
  for(String word2: words){
       g.addEdge(words.indexOf(word), words.indexOf(word2));
  }
}

BufferedReader readValues = 
    new BufferedReader(new InputStreamReader(new FileInputStream("values.txt")));

while(true)
{
    String line = readTestFile.readLine();
    if (line == null) { break; }
    assert line.length() == 11; 
    String start = line.substring(0, 5);
    String goal = line.substring(6, 11);
            
    BreadthFirstPaths bfs = new BreadthFirstPaths(g, words.indexOf(start));
    if (bfs.hasPathTo(words.indexOf(goal))) {
    System.out.println(bfs.distTo(words.indexOf(goal)));
     for (int v : bfs.pathTo(words.indexOf(goal))) {
               System.out.println(v);
     }
    }
    else System.out.println("Nothing");
}

Contents of the Text file:

hello there
hello here
about here

I seem to get:

Nothing
Nothing
Nothing
Nothing
Nothing 

Not sure of why?

EDIT: OP seems to have trouble with the code here, especially, the graph. I do not know specifically why, but, I am sure there are those who do.

Questioner
user14368465
Viewed
11
jccampanero 2020-11-29 19:35:46

I suppose you are using the source code from the excellent book from Robert Sedgewick and Kevin Wayne about algorithms implementation in Java Algorithms, 4th Edition.

There is no reason why your code should not work fine. Please, consider the following test based on your code:

public static void main(String... args) throws IOException {
  ArrayList<String> words = new ArrayList<String>();
  words.add("hello");
  words.add("there");
  words.add("here");
  words.add("about");

  Graph g = new Graph(words.size());
  for(String word: words) {
    for(String word2: words){
      g.addEdge(words.indexOf(word), words.indexOf(word2));
    }
  }

  BufferedReader readValues = null;

  try {

    readValues =
        new BufferedReader(new InputStreamReader(new FileInputStream("values.txt")));

    String line = null;
    while ((line = readValues.readLine()) != null) {
      // assert line.length() == 11;
      String[] tokens = line.split(" ");
      String start = tokens[0];
      String goal = tokens[1];

      BreadthFirstPaths bfs = new BreadthFirstPaths(g, words.indexOf(start));
      if (bfs.hasPathTo(words.indexOf(goal))) {
        System.out.println("Shortest path distance from " + start + " to " + goal + " = " + bfs.distTo(words.indexOf(goal)));
        StringBuilder path = new StringBuilder();
        String sep = "";
        for (int v : bfs.pathTo(words.indexOf(goal))) {
          path.append(sep).append(v);
          sep = " -> ";
        }

        System.out.println("Shortest path = " + path.toString());
      } else System.out.println("Nothing");
    }

  } finally {
    if (readValues != null) {
      try {
        readValues.close();
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }
  }
}

If you run this program with the text file that you indicated it will produce an output similar to the following:

Shortest path distance from hello to there = 1
Shortest path = 0 -> 1
Shortest path distance from hello to here = 1
Shortest path = 0 -> 2
Shortest path distance from about to here = 1
Shortest path = 3 -> 2

The main change I introduced is the code related with the calculation of the start and goal variables:

String[] tokens = line.split(" ");
String start = tokens[0];
String goal = tokens[1];

I assume you are using another text file, perhaps another code; with the one provided the assertion will fail or a StringIndexOutOfBounds exception will be raised when you calculate goal as the substring from index 6 to 11.

Apart from that, the algorithm should work fine.

That being said, please, be aware that you are constructing a graph hyperconnected, in which every node has a direct path to a different node and itself. Maybe that could be your objective, but be aware that things get interesting when you do some other kind of stuff.

For instance, if instead of this code:

for(String word: words) {
  for(String word2: words){
    g.addEdge(words.indexOf(word), words.indexOf(word2));
  }
}

You try something like this:

g.addEdge(words.indexOf("hello"), words.indexOf("there"));
g.addEdge(words.indexOf("hello"), words.indexOf("about"));
g.addEdge(words.indexOf("about"), words.indexOf("here"));

The output of the algorithm has more sense:

Shortest path distance from hello to there = 1
Shortest path = 0 -> 1
Shortest path distance from hello to here = 2
Shortest path = 0 -> 3 -> 2
Shortest path distance from about to here = 1
Shortest path = 3 -> 2