簡體   English   中英

遍歷以鄰接矩陣表示的圖形

[英]Traverse a graph represented in an adjacency matrix

我想使用深度優先和廣度優先的方法來遍歷圖形。 我以前在一個簡單的節點列表上做過這個,但是我從來沒有用鄰接矩陣試過它,老實說,我甚至不知道從哪里開始。

這是我的矩陣:

999999999 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 999999999 0 3 1 0 0 0 0 0 0 0 0 0 0 0 
1 0 999999999 3 0 1 0 0 0 0 0 0 0 0 0 0 
0 3 3 999999999 0 0 0 8 0 0 0 0 0 0 0 0 
0 1 0 0 999999999 0 1 3 0 0 0 0 0 0 0 0 
0 0 1 0 0 999999999 0 3 1 0 0 0 0 0 0 0 
0 0 0 0 1 0 999999999 0 0 3 0 1 0 0 0 0 
0 0 0 8 3 3 0 999999999 0 8 8 0 3 0 0 0 
0 0 0 0 0 1 0 0 999999999 0 3 0 0 1 0 0 
0 0 0 0 0 0 3 8 0 999999999 0 0 0 0 3 0 
0 0 0 0 0 0 0 8 3 0 999999999 0 0 0 0 3 
0 0 0 0 0 0 1 0 0 0 0 999999999 0 0 1 0 
0 0 0 0 0 0 0 3 0 0 0 0 999999999 0 1 1 
0 0 0 0 0 0 0 0 1 0 0 0 0 999999999 0 1 
0 0 0 0 0 0 0 0 0 3 0 1 1 0 999999999 0 
0 0 0 0 0 0 0 0 0 0 3 0 1 1 0 999999999

這是我創建這個矩陣(C#)的方法:

private static int[,] CreateMatrix()
        {
            int A = 0;
            int B = 1;
            int C = 2;
            int D = 3;
            int E = 4;
            int F = 5;
            int G = 6;
            int H = 7;
            int I = 8;
            int J = 9;
            int K = 10;
            int L = 11;
            int M = 12;
            int N = 13;
            int O = 14;
            int P = 15;

            int[,] matrix = new int[16, 16];

            matrix[A, B] = 1;
            matrix[A, C] = 1;
            matrix[B, D] = 3;
            matrix[B, E] = 1;
            matrix[C, D] = 3;
            matrix[C, F] = 1;
            matrix[D, H] = 8;
            matrix[E, G] = 1;
            matrix[E, H] = 3;
            matrix[F, H] = 3;
            matrix[F, I] = 1;
            matrix[G, J] = 3;
            matrix[G, L] = 1;
            matrix[H, J] = 8;
            matrix[H, K] = 8;
            matrix[H, M] = 3;
            matrix[I, K] = 3;
            matrix[I, N] = 1;
            matrix[J, O] = 3;
            matrix[K, P] = 3;
            matrix[L, O] = 1;
            matrix[M, O] = 1;
            matrix[M, P] = 1;
            matrix[N, P] = 1;


            matrix[B, A] = 1;
            matrix[C, A] = 1;
            matrix[D, B] = 3;
            matrix[E, B] = 1;
            matrix[D, C] = 3;
            matrix[F, C] = 1;
            matrix[H, D] = 8;
            matrix[G, E] = 1;
            matrix[H, E] = 3;
            matrix[H, F] = 3;
            matrix[I, F] = 1;
            matrix[J, G] = 3;
            matrix[L, G] = 1;
            matrix[J, H] = 8;
            matrix[K, H] = 8;
            matrix[M, H] = 3;
            matrix[K, I] = 3;
            matrix[N, I] = 1;
            matrix[O, J] = 3;
            matrix[P, K] = 3;
            matrix[O, L] = 1;
            matrix[O, M] = 1;
            matrix[P, M] = 1;
            matrix[P, N] = 1;

            for (int i = 0; i < 16; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    if (matrix[i, j] == 0)
                        matrix[i, j] = 0;

                    if (i == j)
                        matrix[i, j] = 999999999;

                }
            }

            return matrix;
        }

任何幫助,將不勝感激!!

此矩陣表示的圖表:

在此輸入圖像描述

在計算機科學中,除了每隔一個問題可以通過增加更多的抽象來解決。

首先以最抽象的方式編寫廣度優先遍歷:

void BreadthFirstTraversal(Graph graph, Vertex start)
{
    /* A miracle happens */
}

我們有一種方法可以滿足我們的需求。 除了它尚未寫入。 所以用稍微抽象的方式寫它:

void BreadthFirstTraversal(Graph graph, Vertex start)
{
    /* make a queue of vertices */
    /* make a mark set of vertices */
    /* enqueue and mark start */
    /* while the queue is not empty */
        /* dequeue a vertext */
        /* enqueue and mark all the unmarked neighbours of the vertex */
}

繼續前進,刪除越來越多的抽象。

void BreadthFirstTraversal(Graph graph, Vertex start)
{
    var queue = new VertexQueue();
    var markSet = new VertexMarkSet();
    queue.Enqueue(start);
    markSet.Add(start);
    while(queue.NotEmpty())
    {
        var vertex = queue.Dequeue();
        foreach(Vertex neighbour in graph.ListNeighbours(vertex))
        {
            if (!markSet.Contains(neighbour))
            {
                markSet.Add(neighbour);
                queue.Enqueue(neighbour);
            }
        }
     }
}

好了,現在你已經有了一個適用於任何圖形的算法,無論它在內部表示什么。 所以你要做的就是寫ListNeighbours(Vertex) ,你就完成了。 (假設您已經知道如何編寫隊列和集合,或者是否願意使用基類庫附帶的類型。)您將如何做到這一點?

你看我在那里如何使用抽象? 我真的不在乎它是一個鄰接矩陣還是一個鄰接列表,我所關心的是圖形為我提供了給我一個頂點鄰居的服務。

那么,給定鄰接矩陣,你將如何編寫ListNeighbours(Vertex)

兩種可能的解決方案:

  • 使Graph.ListNeighbours(Vertex)方法返回List<Vertex> 構建列表並將其交付。

  • 使其返回IEnumerable<Vertex>並使用yield return來生成一系列相鄰頂點。


更新:好的,那么我們如何從鄰接矩陣中實際創建一系列鄰居呢?

讓我們假設每個頂點都有編號,所以Vertex實際上是int ; 傳統上,這是通過鄰接矩陣完成的。 我們想要接受一個頂點 - 一個int - 並返回一個鄰居的頂點序列。

我們有一個數組,如果頂點j是頂點i的鄰居,則array[i, j]非零。

再次,開始抽象並努力實現:

public List<int> ListNeighbours(int vertex)
{
    /* a miracle happens */
}

我們需要做些什么才能讓奇跡發生?

public List<int> ListNeighbours(int vertex)
{
    /* create a new list */
    /* for each vertex j in the graph */
        /* if j is a neighbour of i then add it to the list */
    /* return the list */
}

或者,您可以使用yield return來創建序列:

public IEnumerable<int> ListNeighbours(int vertex)
{
    /* for each vertex j in the graph */
        /* if j is a neighbour of i then yield return j */
}

yield return迭代器往往更簡單,但初學者程序員經常很難擺脫控制流。 嘗試兩種方式編寫,看看它是如何進行的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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