我正在尝试解决这个问题,而且我对图表还不熟悉。 我试过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)));
答案 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).