Java 给定一个有向图,找出两个节点之间是否存在路由

Java 给定一个有向图,找出两个节点之间是否存在路由,java,algorithm,graph,graph-algorithm,breadth-first-search,Java,Algorithm,Graph,Graph Algorithm,Breadth First Search,我正试图解决这个问题,我对图形还相当陌生。 我尝试过BFS来解决这个问题,但是我没有得到正确的答案 我做错了什么?还有,除了我正在使用的方法之外,还有更好的方法吗 public static boolean isThereARoute(int[][] graph ,gNode n1 , gNode n2 ) { // where can we move? - anywhere where the value of x and y is 1 - else can't move //

我正试图解决这个问题,我对图形还相当陌生。 我尝试过BFS来解决这个问题,但是我没有得到正确的答案

我做错了什么?还有,除了我正在使用的方法之外,还有更好的方法吗

public static boolean isThereARoute(int[][] graph ,gNode n1 , gNode n2 ) {
    // where can we move? - anywhere where the value of x and y is 1 - else can't move
    // Start with node 1 and then traverse either BFS or DFS to see if the n2 is in the path anywhere

    // using BFS.

    //mark the ones where we can move as true
    boolean[][] canMove= new boolean[graph.length][graph[0].length]; 
    for(int i = 0;i<canMove.length;i++){
        for(int j =0;j<canMove[0].length;j++){
            if(graph[i][j]==-1){
                canMove[i][j] = false;
            }else{
                canMove[i][j] = true;
            }
        }
    }



    // create a queue
    Deque<gNode> queue = new LinkedList<gNode>();
    // insert the first node into the queue
    queue.add(n1);


    while(!queue.isEmpty()){
        gNode top = queue.poll();
        int x = top.x1;
        int y = top.y1;
        // only check the ones where we can go

        if( ( top.x1>=0 && top.x1<= graph.length-1) && (top.y1>=0 && top.y1<= (graph[0].length-1)) ){

            if(canMove[top.x1][top.y1]){

                if((top.x1 == n2.x1) && (top.y1 == n2.y1)){
                    // found our node;
                    return true;
                }

                // else haven't found any - add the nodes to the queue // allowed diagonals as well// therefore for each node 
                // there can be 8 neighbors
                queue.add(new gNode(x-1,y));
                queue.add(new gNode(x,y-1));
                queue.add(new gNode(x+1,y));
                queue.add(new gNode(x,y+1));
                queue.add(new gNode(x-1,y-1));
                queue.add(new gNode(x-1,y+1));
                queue.add(new gNode(x+1,y+1));
                queue.add(new gNode(x+1,y-1));

            }

        }

    }

    return false;
}
publicstaticbooleanistherearoute(int[][]图,gNode n1,gNode n2){
//我们可以移动到哪里?-x和y的值为1的任何地方-否则不能移动
//从节点1开始,然后遍历BFS或DFS以查看n2是否位于路径的任何位置
//使用BFS。
//将我们可以移动的地方标记为真实
boolean[][]canMove=new boolean[graph.length][graph[0].length];

对于(int i=0;i,我想说BFS是适用于这里的正确算法,所以这只是BFS代码的一个问题。看起来您对图形是如何在图形中表示的感到困惑

这是检查邻接矩阵(边)中的特定条目是否已到达,但您只需要检查给定节点是否可到达

您应该将
gNode
表示形式更改为使用单个索引(或者干脆将其删除,改用
int
),并基于邻接矩阵值从第一个节点执行BFS


如果您需要了解算法/数据结构方面的其他帮助,本页似乎是一个很好的参考:。

如果我不太熟悉该语言,我不擅长调试超过10-20行的代码。但是,我可以告诉您,有一种更好的总体方法来判断两个节点x之间是否存在路径和y,而不仅仅是从x开始的BFS或DFS。也就是说,你可以从x开始在前进方向上做BFS,同时从y开始在相反方向上做BFS。也就是说,从k=1开始,你可以找到所有你可以到达的顶点,使用路径从x开始向前移动

1. BFS (most simple and efficient too)
2. Transitive closure (found using Floyd-Warshall algorithm).

我想说BFS是适用于这里的正确算法,所以您可能只是BFS代码中有一个bug。这是一个很好的机会让您学习如何调试!@DaoWen:正确。谢谢。@12rad:小心负索引单元格。这行代码将做什么
queue.add(新gNode(x-1,y));
当x=0和y=10时?@fall-当他轮询它时,它不会做任何事情,因为他在轮询之后过滤掉了不好的坐标(请参阅注释后面的条件”//只检查我们可以去的坐标)。它不会做任何事情,因为((top.x1>=0&&top.x1=0&&top。y1@12rad-不,A不是这样工作的。邻接矩阵条目描述边,而不是节点。节点A只是0,而不是(0,0)。在(0,0)处的值说A没有连接到A。你应该看看维基百科的文章,看看这是否有帮助。好的,我知道问题出在哪里了。我完全错了。我应该从一个节点开始,-计算它的所有邻居(包括对角线)-检查邻居之间的边是否允许,如果允许的话,所有更多的邻居-直到我找到我的dst节点?但是如果我已经到达我的dst节点,我如何找到我的dst节点?@12rad-因为你使用短语“包括对角线”听起来您仍然不明白邻接矩阵是如何工作的。如果您从节点A开始,则读取矩阵第0行中的所有条目以查找其邻居。如果您从节点B开始,则读取矩阵第1行中的所有条目以查找其邻居。例如,1 at
graphD[0][1]
表示从A到B有一条边(因为第0行表示“从节点A开始”,第1列表示“在节点B结束”)。一般来说,这并不快,只是在很多情况下。很容易构建一个反例,在实际速度较慢的地方。例如,在这个图上搜索从A到X的路径时,速度会较慢:注意我说过“通常情况下,我们会发现速度要快得多"。显然,你可以构造一个图,其中只有一条可能的路径从x开始,恰好经过y。但可能还有许多其他路径到达y。关键是,我提出的方法的最坏情况复杂度要比假设存在路径fr,从x开始执行BFS的最坏情况复杂度好om x到y的长度为K,并假设顶点度数有一个界。好吧,这是真的。但是,他对K没有任何界,所以在这种情况下,算法的最坏情况复杂性仍然是相同的,对吧?事实上:)这两种方法基本上都可以通过所有顶点。
            if((top.x1 == n2.x1) && (top.y1 == n2.y1)){
                // found our node;
                return true;
            }
1. BFS (most simple and efficient too)
2. Transitive closure (found using Floyd-Warshall algorithm).