简体   繁体   中英

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM