断开连接的图形上的 DFS
DFS on disconnected Graphs
对于断开连接的图,DFS(G,v) 的行为如何?
假设一个图有 3 个连通分量,并且 DFS 应用于这 3 个连通分量之一,那么我们是访问每个分量还是只访问应用 DFS 的顶点。
意思是
这样说对吗
DFS on a graph having many components covers only 1 component.
我也尝试过在线 DFS 可视化工具来处理断开连接的图形,它们也支持只覆盖 1 个组件。但我还是想确认一下
在断开连接的图形的单个组件上开始搜索将仅搜索该组件;否则怎么可能呢?没有信息可以决定何时、如何或在何处将搜索移动到不同的组件。
如果您想对断开连接的图执行完整搜索,您有两个高级选项:
- 启动对每个组件的单独搜索,然后添加一些逻辑以在多个结果中做出选择(如有必要)。这具有用于 运行 并行搜索的简单分区逻辑的优点。
- 添加逻辑以指示如何将组件组合成 "single" 图形。两个想法:
- 添加一个虚拟根节点,并将组件作为其子节点。对于只涵盖一个组件但您想同时使用所有三个组件的工具,这将是一个巧妙的解决方法。这也意味着,如果您正在搜索单个最佳结果,则可以保证您获得全局最佳结果而无需任何额外检查。
- 将您的组件放在一个列表中,并添加在当前搜索完成时跳转到下一个组件的逻辑。如有必要,添加额外的逻辑来比较多个潜在的搜索结果。
请注意,同样的推理也适用于广度优先搜索。
我想出了一种 DFS 可以搜索图中断开连接的部分的方法,我不知道这是否是最好的,但下面是。
function Node(id, val){
this.id = id;
this.val = val;
this.nodeChildren = {};
}
Node.prototype.addAssociation = function(node){
this.nodeChildren[node.val] = node;
}
function Graph(){
this.nodes = [];
this.countNodes = 0;
}
Graph.prototype.addNode = function(val){
var n = new Node(this.countNodes, val);
this.nodes.push(n);
this.countNodes++;
return n;
}
Graph.prototype.search = function(val){
var nodeIndex = 0;
var visited = {}; //Hashmap
var found = null;
//Loop within the nodes and check if we didn't found a result yet
while(nodeIndex < this.nodes.length && found ==null ){
if(nodeIndex == this.nodes.length) return null;
var currentNode = this.nodes[nodeIndex];
nodeIndex++;
console.log("searching from", currentNode.val, visited);
found = this.searchDFS(val, visited, currentNode);
}
return found;
}
Graph.prototype.searchDFS = function(val, visited, currentNode){
//Node already visited skip
if(visited[currentNode.id] ==1 ) {
console.log("already visited, skipping");
return null;
}
//Found the node return it
if(currentNode.val == val){
return currentNode;
}
visited[currentNode.id] = 1;
var keys = Object.keys(currentNode.nodeChildren);
for(var i=0; i<keys.length; i++){
var childNode = currentNode.nodeChildren[keys[i]];
if(visited != 1){
return this.searchDFS(val, visited, childNode);
}
}
}
var g = new Graph();
var n1 = g.addNode("a");
var n2 = g.addNode("b");
var n3 = g.addNode("c");
g.addNode("c1").addAssociation(n3);
g.addNode("c2").addAssociation(n2);
var n4 = g.addNode("d");
var n5 = g.addNode("e");
n1.addAssociation(n2);
n1.addAssociation(n3);
n2.addAssociation(n3);
n3.addAssociation(n4);
console.log("found", g.search("e"));
对于断开连接的图,DFS(G,v) 的行为如何?
假设一个图有 3 个连通分量,并且 DFS 应用于这 3 个连通分量之一,那么我们是访问每个分量还是只访问应用 DFS 的顶点。
意思是
这样说对吗DFS on a graph having many components covers only 1 component.
我也尝试过在线 DFS 可视化工具来处理断开连接的图形,它们也支持只覆盖 1 个组件。但我还是想确认一下
在断开连接的图形的单个组件上开始搜索将仅搜索该组件;否则怎么可能呢?没有信息可以决定何时、如何或在何处将搜索移动到不同的组件。
如果您想对断开连接的图执行完整搜索,您有两个高级选项:
- 启动对每个组件的单独搜索,然后添加一些逻辑以在多个结果中做出选择(如有必要)。这具有用于 运行 并行搜索的简单分区逻辑的优点。
- 添加逻辑以指示如何将组件组合成 "single" 图形。两个想法:
- 添加一个虚拟根节点,并将组件作为其子节点。对于只涵盖一个组件但您想同时使用所有三个组件的工具,这将是一个巧妙的解决方法。这也意味着,如果您正在搜索单个最佳结果,则可以保证您获得全局最佳结果而无需任何额外检查。
- 将您的组件放在一个列表中,并添加在当前搜索完成时跳转到下一个组件的逻辑。如有必要,添加额外的逻辑来比较多个潜在的搜索结果。
请注意,同样的推理也适用于广度优先搜索。
我想出了一种 DFS 可以搜索图中断开连接的部分的方法,我不知道这是否是最好的,但下面是。
function Node(id, val){
this.id = id;
this.val = val;
this.nodeChildren = {};
}
Node.prototype.addAssociation = function(node){
this.nodeChildren[node.val] = node;
}
function Graph(){
this.nodes = [];
this.countNodes = 0;
}
Graph.prototype.addNode = function(val){
var n = new Node(this.countNodes, val);
this.nodes.push(n);
this.countNodes++;
return n;
}
Graph.prototype.search = function(val){
var nodeIndex = 0;
var visited = {}; //Hashmap
var found = null;
//Loop within the nodes and check if we didn't found a result yet
while(nodeIndex < this.nodes.length && found ==null ){
if(nodeIndex == this.nodes.length) return null;
var currentNode = this.nodes[nodeIndex];
nodeIndex++;
console.log("searching from", currentNode.val, visited);
found = this.searchDFS(val, visited, currentNode);
}
return found;
}
Graph.prototype.searchDFS = function(val, visited, currentNode){
//Node already visited skip
if(visited[currentNode.id] ==1 ) {
console.log("already visited, skipping");
return null;
}
//Found the node return it
if(currentNode.val == val){
return currentNode;
}
visited[currentNode.id] = 1;
var keys = Object.keys(currentNode.nodeChildren);
for(var i=0; i<keys.length; i++){
var childNode = currentNode.nodeChildren[keys[i]];
if(visited != 1){
return this.searchDFS(val, visited, childNode);
}
}
}
var g = new Graph();
var n1 = g.addNode("a");
var n2 = g.addNode("b");
var n3 = g.addNode("c");
g.addNode("c1").addAssociation(n3);
g.addNode("c2").addAssociation(n2);
var n4 = g.addNode("d");
var n5 = g.addNode("e");
n1.addAssociation(n2);
n1.addAssociation(n3);
n2.addAssociation(n3);
n3.addAssociation(n4);
console.log("found", g.search("e"));