简体   繁体   English

Java-邻接矩阵和DFS

[英]Java - Adjacency Matrix and DFS

I've been working on a program to implement a DFS in Java (by taking an adjacency matrix as input from a file). 我一直在研究在Java中实现DFS的程序(通过从文件中获取邻接矩阵作为输入)。 Basically, assuming vertices are traveled in numerical order, I would like to print the order that vertices become dead ends, the number of connected components in the graph, the tree edges and the back edges. 基本上,假设顶点按数字顺序行进,我想打印顶点变为死角的顺序,图中连接的组件数,树边缘和后边缘。 But I'm not completely there yet. 但是我还没有完全到那儿。 When I run my program, I get the number "1" as output, and nothing more. 当我运行程序时,输出为“ 1”,仅此而已。 I've tried debugging certain parts of the DFS class, but I still can't quite figure out where I'm going wrong. 我已经尝试调试DFS类的某些部分,但是我仍然无法弄清楚哪里出了问题。 Here is my code: 这是我的代码:

A basic "Driver" class: 基本的“驱动程序”类:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class Driver {

public static void main(String[] args) throws FileNotFoundException {
    Scanner scanner = new Scanner(new File("sample1.txt"));
    scanner.useDelimiter("[\\s,]+");

    int input = scanner.nextInt();
    int[][] adjMatrix = new int[8][8];

    for(int i=0; i < input; i++) {
        for (int j=0; j < input; j++) {
             adjMatrix[i][j] = scanner.nextInt();
        }
    }
    scanner.close();

    new DFS(adjMatrix);

}

}

DFS class: DFS类:

import java.util.Stack;

public class DFS {
Stack<Integer> stack;
int first;
int[][] adjMatrix;
int[] visited = new int[7];

public DFS(int[][] Matrix) {

    this.adjMatrix = Matrix;
    stack = new Stack<Integer>();
    int[] node = {0, 1, 2, 3, 4, 5, 6};
    int firstNode = node[0];
    depthFirstSearch(firstNode, 7);
}

public void depthFirstSearch(int first,int n){
     int v,i;

     stack.push(first);

     while(!stack.isEmpty()){
         v = stack.pop();
         if(visited[v]==0) {
             System.out.print("\n"+(v+1));
             visited[v]=1;
         }
         for (i=0;i<n;i++){
             if((adjMatrix[v][i] == 1) && (visited[i] == 0)){
                 stack.push(v);
                 visited[i]=1;
                 System.out.print(" " + (i+1));
                 v = i;
             }
         }
     }
}
}

And the matrix from the input file looks like this: 输入文件中的矩阵如下所示:

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

Take a look at this part: 看一下这一部分:

 int input = scanner.nextInt(); int[][] adjMatrix = new int[8][8]; for(int i=0; i < input; i++) { for (int j=0; j < input; j++) { adjMatrix[i][j] = scanner.nextInt(); } } 

First you read a number, input . 首先,您input一个数字, input Then you read input rows, in each row input columns. 然后,您将读取input行,在每一行的input列中。

This is your input data: 这是您的输入数据:

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

What is the first number, that will be read by scanner.nextInt() . 第一个数字是什么,将由scanner.nextInt()读取。 It's 0. So the loop will do nothing. 它是0。因此循环将不执行任何操作。

Prepend the number 8 to your input, that is: 在输入的数字前加上数字8,即:

 8 0 1 0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 1 0 

Btw, it's a good idea to verify that you have correctly read the matrix. 顺便说一句,验证您已正确读取矩阵是个好主意。 Here's an easy way to do that: 这是一种简单的方法:

for (int[] row : adjMatrix) {
    System.out.println(Arrays.toString(row));
}

There are several other issues in this implementation: 此实现中还有其他几个问题:

  • The number 7 appears in a couple of places. 数字7出现在几个地方。 It's actually a crucial value in the depth-first-search algorithm, and it's actually incorrect. 在深度优先搜索算法中,这实际上是一个至关重要的值,而且实际上是错误的。 It should be 8. And it should not be hardcoded, it should be derived from the size of the matrix. 它应为8。并且不应对其进行硬编码,而应从矩阵的大小中得出。
  • It's not a good practice to do computation in a constructor. 在构造函数中进行计算不是一个好习惯。 The purpose of a constructor is to create an object. 构造函数的目的是创建一个对象。 The depth-first-logic could be moved to a static utility method, there's nothing in the current code to warrant a dedicated class. 可以将“深度优先”逻辑移到静态实用程序方法中,当前代码中没有什么可以保证专用类的。

Fixing the above issues, and a few minor ones too, the implementation can be written a bit simpler and cleaner: 解决了上述问题,并修复了一些小问题,可以将实现的编写更简单,更简洁:

public static void dfs(int[][] matrix) {
    boolean[] visited = new boolean[matrix.length];

    Deque<Integer> stack = new ArrayDeque<>();
    stack.push(0);

    while (!stack.isEmpty()) {
        int v = stack.pop();
        if (!visited[v]) {
            System.out.print("\n" + (v + 1));
            visited[v] = true;
        }
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[v][i] == 1 && !visited[i]) {
                visited[i] = true;
                stack.push(v);
                v = i;
                System.out.print(" " + (i + 1));
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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