簡體   English   中英

遍歷圖,一個頂點,所有可能的往返

[英]Traverse a graph, one vertex, all possible round trips

我手頭有一個有趣的問題。 我想解決一個從加權圖的源頂點開始的問題,並找出導致其返回的所有可能路徑。

例如:考慮上面的有向圖: 在此處輸入圖片說明


如果我從Source = A開始,則預期輸出:

1)A-> C-> D-> B-> A

2)A-> B-> A

3)A-> D-> B-> A

注意:


a)圖形將被加權,我在遍歷時發現邊緣的總和(不一定是最小總和)。

b)計划使用矩陣表示圖,並且該圖在某些位置可能是循環的。

b)哪一個最有效的代碼可以解決這個問題? 我知道BFS和DFS,但他們不計算往返行程!

當前的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
);
}

這可以通過修改DFS(或BFS)來解決。

考慮DFS。

訪問節點后,將其標記為已訪問。 從它返回后,將其標記為未訪問,以便可以識別其他路徑。

你的例子:

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.

注意:這里重要的是標記未訪問的節點。

這聽起來像是回溯的一個很好的應用案例:

  • 從所需的節點開始
  • 如果第二次到達起始節點,則返回結果
  • 否則:對於每個鄰居
    • 將鄰居添加到當前路徑
    • 進行遞歸
    • 從當前路徑中刪除鄰居

作為示例在此處實現。 當然,這(特別是圖形數據結構)只是一個簡短的草圖,可以證明該想法在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM