[英]Traverse a graph, one vertex, all possible round trips
I have an interesting question at hand. 我手头有一个有趣的问题。 I want to solve a problem of starting from a source vertex of a weighted graph, and find out all possible paths that lead back to it.
我想解决一个从加权图的源顶点开始的问题,并找出导致其返回的所有可能路径。
For eg: Consider a directed graph above: 例如:考虑上面的有向图:
Expected Output If I start from Source=A: 如果我从Source = A开始,则预期输出:
1) A -> C -> D -> B-> A 1)A-> C-> D-> B-> A
2) A -> B -> A 2)A-> B-> A
3) A -> D -> B -> A 3)A-> D-> B-> A
Note: 注意:
a) The graph will be weighted and I'am finding the sum(not necessarily minimum sum) of the edges as I traverse. a)图形将被加权,我在遍历时发现边缘的总和(不一定是最小总和)。
b) Planning to represent the graph using a matrix, and the graph may be Cyclic at some places. b)计划使用矩阵表示图,并且该图在某些位置可能是循环的。
b) Which is the most efficient code that'll solve this? b)哪一个最有效的代码可以解决这个问题? I know about BFS and DFS, but they dont calculate round trips!
我知道BFS和DFS,但他们不计算往返行程!
Current DFS CODE: (adjacency graph) 当前的DFS CODE :(邻接图)
void dfs(int cost[][20],int v[],int n, int j)
{
int i;
v[j]=1;
printf("Vistiing %d\n",j);
for(i=0;i<n;i++)
if(cost[j][i]==1 && v[i]==0)
dfs(cost,v,n,i
);
}
This can be solved by modifying DFS (or BFS). 这可以通过修改DFS(或BFS)来解决。
Consider DFS. 考虑DFS。
Once you visit the nodes mark it as visited. 访问节点后,将其标记为已访问。 Once you return from it, mark it un-visited so that other paths can be recognized.
从它返回后,将其标记为未访问,以便可以识别其他路径。
Your example: 你的例子:
Start from A.
Choose a path.
A->B->A.
Return to B. No other paths.
Return to A. Mark B unvisited. Choose another path.
A->D->B->A.
Return to B. No other paths.
Return to D. Mark B unvisited. No other paths.
Return to A. Mark D unvisited. Choose another path.
A->C->D->B->A.
Note: The important thing here is to mark the nodes un-visited. 注意:这里重要的是标记未访问的节点。
This sounds like a nice application case for Backtracking : 这听起来像是回溯的一个很好的应用案例:
This is implemented here as an example. 作为示例在此处实现。 Of course, this (particularly the graph data structure) is only a quick sketch to show that the idea is feasible, in a MCVE :
当然,这(特别是图形数据结构)只是一个简短的草图,可以证明该想法在MCVE中是可行的:
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class GraphRoundTrips
{
static class Vertex
{
String name;
Vertex(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}
static class Edge
{
Vertex v0;
Vertex v1;
Edge(Vertex v0, Vertex v1)
{
this.v0 = v0;
this.v1 = v1;
}
@Override
public String toString()
{
return "("+v0+","+v1+")";
}
}
static class Graph
{
List<Vertex> vertices = new ArrayList<Vertex>();
List<Edge> edges = new ArrayList<Edge>();
void addVertex(Vertex v)
{
vertices.add(v);
}
void addEdge(Edge e)
{
edges.add(e);
}
List<Vertex> getOutNeighbors(Vertex v)
{
List<Vertex> result = new ArrayList<Vertex>();
for (Edge e : edges)
{
if (e.v0.equals(v))
{
result.add(e.v1);
}
}
return result;
}
}
public static void main(String[] args)
{
Vertex A = new Vertex("A");
Vertex B = new Vertex("B");
Vertex C = new Vertex("C");
Vertex D = new Vertex("D");
Graph graph = new Graph();
graph.addVertex(A);
graph.addVertex(B);
graph.addVertex(C);
graph.addVertex(D);
graph.addEdge(new Edge(A,C));
graph.addEdge(new Edge(A,D));
graph.addEdge(new Edge(A,B));
graph.addEdge(new Edge(B,A));
graph.addEdge(new Edge(C,D));
graph.addEdge(new Edge(D,B));
compute(graph, A, null, new LinkedHashSet<Vertex>());
}
private static void compute(Graph g, Vertex startVertex,
Vertex currentVertex, Set<Vertex> currentPath)
{
if (startVertex.equals(currentVertex))
{
List<Vertex> path = new ArrayList<Vertex>();
path.add(startVertex);
path.addAll(currentPath);
System.out.println("Result "+path);
}
if (currentVertex == null)
{
currentVertex = startVertex;
}
List<Vertex> neighbors = g.getOutNeighbors(currentVertex);
for (Vertex neighbor : neighbors)
{
if (!currentPath.contains(neighbor))
{
currentPath.add(neighbor);
compute(g, startVertex, neighbor, currentPath);
currentPath.remove(neighbor);
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.