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

时间:2013-07-18 23:30:20

标签: 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
    // 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;
}

支票 -

        int[][] graphD = new int[][]{

        {-1, 1,-1,-1,-1},
        {-1,-1, 1,-1,-1},
        {-1,-1, 1, 1,-1},
        {-1,-1,-1,-1,-1},
        { 1,-1, 1,-1,-1}
    };

    ArrayList<gNode> nodes = new ArrayList<gNode>();
    nodes.add(new gNode(0,0));//node A
    nodes.add(new gNode(1,1)); // node B
    nodes.add(new gNode(2,2)); // node C
    nodes.add(new gNode(3,3)); // node D
    nodes.add(new gNode(4,4)); // node E

    /**
     *  A->b
     * B->C
     * C->C
     * C->D
     * E-A
     * 
     */ 

    System.out.println(" is A -B connected?"+isThereARoute(graphD, nodes.get(0), nodes.get(1)));
    System.out.println(" is A -D connected?"+isThereARoute(graphD, nodes.get(0), nodes.get(3)));
    System.out.println(" is C -A connected?"+isThereARoute(graphD, nodes.get(3), nodes.get(0)));
    System.out.println(" is A -E connected?"+isThereARoute(graphD, nodes.get(0), nodes.get(4)));
    System.out.println(" is C -C connected?"+isThereARoute(graphD, nodes.get(2), nodes.get(2)));

3 个答案:

答案 0 :(得分:1)

我想说BFS是适用于此处的算法,所以这只是你的BFS代码的一个问题。看起来您对如何在Adjacency Matrix中表示图表感到困惑。

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

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

您应该将gNode表示更改为使用单个索引(或者只删除它并使用int),然后根据邻接矩阵值从第一个节点执行BFS。

如果您需要一些额外的帮助来理解算法/数据结构,这个页面似乎是一个很好的参考:Adjacency matrices, BFS, DFS

答案 1 :(得分:1)

如果我不熟悉这种语言,我不擅长调试10到20行代码。但是,我可以告诉你,有一个更好的整体方法来判断两个节点x和y之间是否存在路径,而不仅仅是从x开始的BFS或DFS。也就是说,你可以在向前方向从x开始执行BFS,同时在y方向反向执行BFS。即从k = 1开始,您可以找到使用&lt; = k edge的路径从x向前移动的所有顶点,并且您可以使用&lt; = k edge找到所有可以从y移动反向的顶点,并且您应用基本BFS原理将k增加1.对于每个k,您可以对从x可以到达的顶点进行散列,并对可以从y到达的顶点进行散列,如果在两个集合之间得到匹配w,那么w是中点在从x到y的路径中,因此存在路径。这个从B开始优于BFS的原因是,如果从x到y的路径长度为K,那么从x开始的BFS将找到以K步进入的所有节点,这可能是一个巨大的集合(最坏情况指数为K)。但是如果按照我提出的方式进行,那么你可以在达到k> = K / 2时终止,并且以K / 2步进入的2组顶点通常比在K中可到达的一组顶点小得多。脚步。因此,当存在路径时,您通常会以我提出的方式更快地找到它。

答案 2 :(得分:-1)

可以这样做。

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