简体   繁体   English

遍历图,一个顶点,所有可能的往返

[英]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 : 这听起来像是回溯的一个很好的应用案例:

  • Start with the desired node 从所需的节点开始
  • If you reached the start node for the second time, return the result 如果第二次到达起始节点,则返回结果
  • Otherwise: For each neighbor 否则:对于每个邻居
    • Add the neighbor to the current path 将邻居添加到当前路径
    • Do the recursion 进行递归
    • Remove the neighbor from the current path 从当前路径中删除邻居

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.

相关问题 图算法计算不同起始顶点和一个结束顶点之间的所有可能路径 - Graph Algorithm to count all possible paths between different starting vertices and one end vertex 在Erlang中查找有向循环图中一个顶点的所有可能路径 - Find all possible paths from one vertex in a directed cyclic graph in Erlang 当存在循环时,是否可以使用 DFS 遍历图中的所有连接节点? - Is it possible to traverse all connected nodes in a graph with DFS when cycles are present? TinkerPop / Graph:遍历边缘,然后按结果顶点和遍历的边缘分组 - TinkerPop/Graph: Traverse edge and then group by resulting vertex and traversed edge 在给定起始顶点和深度限制的情况下查找循环有向图中的所有可能路径 - Finding all possible paths in a cyclic directed graph given a starting vertex and a depth limitation 遍历图(查找链接的所有问题) - python - traverse a graph (find all issues linked) 如何找到有向图中2个特定顶点之间的所有可能路径中存在的顶点? - How to find vertices exist in all possible route between 2 specific vertex in a directed graph? 计算图中从任何给定顶点到另一个顶点的所有可能路径的正确算法是什么? - What's a proper algorithm to count all possible paths from any given vertex to another in a graph? 查找图形中包括顶点的所有路径 - finding all paths in a graph including a vertex 计算无向图中所有具有约束的顶点对 - count all pair of vertex with constraints in an undirected graph
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM