I have an adjacency matrix adj
of the form below:
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
This is the adjacency matrix for a maze with rules adj(x,y) = 1
if:
The maze is as below (beside it are the element numbers):
S X E | 1 2 3
O O O | 4 5 6
O X O | 7 8 9
//S = starting position
//E = ending position
//X = wall
I have a DFS algorithm that will display the nodes to traverse from S
to E
, but it displays unnecessary nodes.
public static void main(String [] args){
int[][] adj = //the adjacency matrix
boolean[] visited = new boolean[adj.length];
int n = adj.length;
int m = 1; //starting position
int o = 3; //ending position
DFS(adjMatrix, visited, n, m, o);
}
public static void DFS(int[][] adj, boolean[] visited, int n, int i, int o){
System.out.print(" " + (i+1));
visited[i]= true;
if (i+1 != o) {
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
DFS(adj, visited, n, j, o);
}
}
}
}
public static void BFS(int[][] adj, boolean[] visited, int n, int i, int o){
queue Q = new queue;
visited[i]= true;
Q.enqueue(i);
while (!Q.isEmpty()) {
//...
}
}
This prints 1 4 5 6 3 9 7
. I'm wracking my head around modifying it so that it will only print 1 4 5 6 3
.
What have I done wrong here?
There are some major issues with the code, in addition to fixes needed for the DFS algorithm:
10X9
- it should be a squared matrix)
List<>
(rather than void
- that populates all the nodes in the current path. If you reached the destination, create the list, otherwise - return null
. Attach elements only when the recursive call returns something that is not null
. Code attached Also note, it prints the nodes in the correct order (and not reversed order)
public static void main(String [] args){
int[][] adj = {
{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}
};
boolean[] visited = new boolean[adj.length];
int n = adj.length;
int m = 1-1; //starting position
int o = 3-1; //ending position
System.out.println(DFS(adj, visited, n, m, o));
}
public static List<Integer> DFS(int[][] adj, boolean[] visited, int n, int i, int o){
visited[i]= true;
if (i == o) return new LinkedList<Integer>(Arrays.asList(i+1));
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
List<Integer> res = DFS(adj, visited, n, j, o);
if (res != null) {
res.add(0, i+1);
return res;
}
}
}
return null; //no path
}
Will result (as expected) with:
[1, 4, 5, 6, 3]
As a side note, though this solution is complete (will always find a solution if such exists), it is not optimal - it might return a longer solution than the shortest one.
If you want to find the shortest path from source to target, consider switching to a BFS
Try with this code:
public static boolean DFS(int[][] adj, boolean[] visited, int n, int i, int o){
visited[i]= true;
boolean good = false;
if (i+1 != o) {
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
good |= DFS(adj, visited, n, j, o);
}
}
} else {
good = true;
}
if (good) System.out.print(" " + (i+1));
return good;
}
This will print paths in reverse (from end to start) - but it will only print nodes that are part of a good path. If you need to print the path in start-to-end order, you can store it in an array and then print it in reverse:
public static void DFS(int[][] adj, boolean[] visited,
ArrayList<int> path, int n, int i, int o){
visited[i]= true;
if (i+1 != o) {
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
path.add(j);
DFS(adj, visited, n, j, o);
path.remove(path.size()-1);
}
}
} else {
// show path
for (int i : path) {
System.out.print(" " + i);
}
}
}
When you finally reach your destination, the method stack will have the path.
ArrayList<Integer> list = new ArrayList<>(); // this will have your path.
public static boolean DFS(int[][] adj, boolean[] visited, int n, int i, int o){
if(i==o){
list.add(o);
//System.out.println(i);
return true;
}
visited[i]= true;
for (int j = 0; j<n;j++){
if(!(visited[j]) && adj[i][j]==1){
if(DFS(adj, visited, n, j, o)){
list.add(0,j);
//System.out.println(j);
return true;
}
}
}
return false;
}
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.