簡體   English   中英

給定一個有向圖,找出兩個節點之間是否存在路由

[英]Given a directed graph, find out whether there is a route between two nodes

我正在嘗試解決這個問題,我對圖形還很陌生。 我試圖通過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)));

我會說BFS是在這里應用的正確算法,因此這只是您的BFS代碼的問題。 您似乎對圖在鄰接矩陣中的表示方式感到困惑。

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

這是在檢查是否已到達鄰接矩陣(邊)中的特定條目,但是您只是要檢查給定節點是否可到達。

您應該更改gNode表示形式以使用單個索引(或者只是刪除它並使用int代替),並根據鄰接矩陣值從第一個節點開始執行BFS。

如果您在了解算法/數據結構方面需要其他幫助,則此頁面似乎是不錯的參考: 鄰接矩陣,BFS,DFS

如果我不太熟悉該語言,則我不擅長調試10-20行以上的代碼。 但是,我可以告訴您,有一種更好的整體方法來判斷兩個節點x和y之間是否存在路徑,而不是僅僅從x開始的BFS或DFS。 即,您可以從x的正方向進行BFS,同時從y的方向進行BFS。 即從k = 1開始,您發現可以使用<= k條邊的路徑從x向前移動的所有頂點,並找到您使用<= k邊條的從y反向移動的所有頂點,然后應用BFS的基本原理是將k增加1。對於每個k,對可以從x到達的頂點進行哈希處理,對可以從y達到的頂點進行哈希處理,如果在兩個集合之間獲得匹配w,則w是其中的中點從x到y的路徑,因此存在路徑。 之所以比從x開始的BFS更可取,是因為如果從x到y的路徑的長度為K,則從x開始的BFS會發現所有以K步可達的節點,這可能是一個龐大的集合(在K)。 但是,如果按照我建議的方式進行操作,則可以在達到k> = K / 2時終止,並且以K / 2步可達的2組頂點通常會比以K步可達的一組頂點小得多。 。 因此,當存在路徑時,通常會比我提出的方法快得多。

可以這樣處理。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM