Search code examples
javaalgorithmgraphbreadth-first-searchadjacency-matrix

Breadth-first algorithm on adjacency matrix: premature ending of search, returns queue of size 1?


adj is an adjacency matrix:

0 0 0 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 0 
1 0 0 0 1 0 1 0 0 
0 0 0 1 0 1 0 0 0 
0 0 1 0 1 0 0 0 1 
0 0 0 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 0 

adj maps adjacency for a maze below (to the side is the element #):

S X E | 0 1 2
O O O | 3 4 5
O X O | 6 7 8

I'm using the adjacency matrix to traverse elements in the maze. Here's a Breadth-first-search algorithm to traverse the matrix.

queue Q = new queue();
boolean[] visited = new boolean[];
int num = 9; //number of elements
int begin = 0; //begin point as defined 'S'
int end = 2; //end point as defined 'E'
private queue BFS(int[][] adj, int begin) {
    visited[begin] = true;
    Q.enqueue(begin);
    while (!Q.isEmpty()) {
        int element = Q.dequeue();
        int temp = element;
        while (temp <= num) {
            if ((!visited[temp]) && (adj[element][temp] == 1)) {
                if (temp == end) {
                    return Q;
                }
                Q.enqueue(temp);
                visited[temp] = true;
            }
            temp++;
        }
    }
    return Q;
}

Doing BFS() returns a queue of size() 1. Specifically, the queue only contains begin (in this case, 0). The algorithm should produce a queue of [0, 3, 4, 5, 2]. Inserting a System.out.println("blah") right after the first while() opening shows it only iterates once.

Why does my algorithm stop prematurely? How can I tweak it to get my desired output? My goal is to device an algorithm that finds the shortest path possible between '0' and '2' in this scenario.


Solution

  • You hit the condition temp == end at the first iteration because your temp starts from 0, then it's 1 without inserting element to queue(because it's not adjacent to 0), then it's 2 without inserting, and here you are, under condition temp == end (both equal 2) you return Q that contains only begin as nothing yet has been inserted. So you only have one iteration of outer loop and three iterations of inner loop.

    I would suggest following modification

    queue Q = new queue();
    boolean[] visited = new boolean[];
    int num = 9; //number of elements
    int begin = 0; //begin point as defined 'S'
    int end = 2; //end point as defined 'E'
    private void BFS(int[][] adj, int begin) {
        visited[begin] = true;
        Q.enqueue(begin);
        while (!Q.isEmpty()) {
            int element = Q.dequeue();
            if (element == end) {
                return Q;
            }
            int temp = 0;
            while (temp < num) {
                if ((!visited[temp]) && (adj[element][temp] == 1)) {
                    Q.enqueue(temp);
                    visited[temp] = true;
                }
                temp++;
            }
        }
        return Q;
    }