我有一个包含大量节点的图表,其中一个起始节点(所有边缘都在外面)和一个结束节点(所有边缘朝向它)。它是一个单向且未加权的图。如何在这种图中优化搜索以找出两个节点之间是否存在路径?我知道BFS提供了一个解决方案。是否有优化搜索(如添加一些额外信息),因为我将在图表上频繁搜索?
编辑:要添加有关图表的更多信息,图表有一个具有多个外边缘的起始节点和一个具有多个内边缘的结束节点。在这两者之间,有数百万个节点连接在一起。它是一个未加权的DAG。并且没有涉及启发式。只需检查isConnected(节点a,节点b)。
答案 0 :(得分:2)
考虑到你的图表是非循环的,这是一种方法: -
图表上的DFS是否以源顶点开始(只有outgoiong边缘)
对于连接图中的每条边(u,v)[u] [v] = true
- 醇>
尝试将前一个节点存储在阵列中的DFS堆栈中。对于每个顶点v访问,检查堆栈中的先前节点并执行 connected [u] [v] = true其中u是前一个节点。
如果图形不是非循环的,那么首先使用Kosaraju或Tarjan计算SCC,然后将图形缩小为非循环,并对SCC中的每对进行连接[u] [v] = true
修改后的DFS例程的伪代码: -
bool connected[n][n] = {false};
bool visited[n] = {false};
int stack[n];
for each source vertex v do :
DFS(v,stack,0);
void DFS(int u,int stack[n],int depth) {
if(!visited[v]) {
visited[v] = true;
for(int i=0;i<depth;i++) {
connected[stack[i]][v] = true;
}
stack[depth] = u;
for each edge(u,v) {
connected[u][v] = true;
DFS(v,stack,depth+1);
}
}
}
空间复杂性:O(V^2)
时间复杂度:O(V^2)
注意: - 强>
如果您的查询数量较少,请尝试单独使用DFS并缓存结果,因为这样会比这更耗时。