Создать матрицу смежности для взвешенного графа

Я пытаюсь реализовать Флойд-Warshall Алгоритм. Для этого мне нужно настроить adjacency matrix взвешенного графа. Как мне это сделать? Я знаю значения и приложил изображение взвешенного графика. Я попытался найти некоторые онлайн-примеры этого, но я ничего не могу найти. Я понимаю алгоритм Флойда-Уоршелла, мне просто нужна помощь в его настройке, чтобы я мог его реализовать. Вот один, который я построил раньше, но я не сделал должны использовать определенные значения.

код:

public static void buildAdjMatrix()
{

    for (int i = 0; i < 100; i++)
    {
        for (int j = 0; j < 100; j++)
        {
            if (directionAllowed(i, j) == true)
            {
                adjMatrix[i, j] = 1;
            }
            else
            {
                adjMatrix[i, j] = 50;
            }
        }
    }

}

вот конкретный график под рукой:

enter image description here

вот изображение матрицы, которую мне нужно создать.. Извините за ужасное качество...

enter image description here

1 ответов


Итак, вы, кажется, не знакомы с графы, взгляните на Википедию. Также просмотрите некоторые изображения, это становится легче понять.

немного понятие

ваша фотография может быть представлена как Graph. Как правило, графики реализуются с использованием 2 основных видов элементов,Nodes и Links (иногда называют Arcs).

A Node обозначают буквы в твоей картинке, они будут А, B, C и т. д. Ан Arc или Link, это линия, соединяющая два узла, если вы посмотрите связь между H и L, у них есть связь между ними, в взвешенном графике разные связи имеют разные веса.

решение вашей проблемы - Часть 1

то, что мы должны сделать, это представить вашу картину в виде графика в коде, так что давайте начнем создавать основные элементы Node и Arc:

узел

узел имеет Name, поэтому мы можем определить узел. И узел может быть подключен к другим узлам, мы могли бы использовать коллекцию узлов, но ваш-взвешенный график, поэтому каждое из соединений должно быть представлено связанным узлом и его весом. Поэтому мы используем коллекцию Дуг.

public class Node
{
    public string Name;
    public List<Arc> Arcs = new List<Arc>();

    public Node(string name)
    {
        Name = name;
    }

    /// <summary>
    /// Create a new arc, connecting this Node to the Nod passed in the parameter
    /// Also, it creates the inversed node in the passed node
    /// </summary>
    public Node AddArc(Node child, int w)
    {
        Arcs.Add(new Arc
        {
            Parent = this,
            Child = child,
            Weigth = w
        });

        if (!child.Arcs.Exists(a => a.Parent == child && a.Child == this))
        {
            child.AddArc(this, w);
        }

        return this;
    }
}

Arc

действительно простой класс, он содержит связанные узлы и вес соединения:

public class Arc
{
    public int Weigth;
    public Node Parent;
    public Node Child;
}

графика

Graph-это своего рода обертка класс, для целей организации. Я также объявил корень для графика, мы его не используем, но полезно в нескольких случаях:

public class Graph
{
    public Node Root;
    public List<Node> AllNodes = new List<Node>();

    public Node CreateRoot(string name)
    {
        Root = CreateNode(name);
        return Root;
    }

    public Node CreateNode(string name)
    {
        var n = new Node(name);
        AllNodes.Add(n);
        return n;
    }

    public int?[,] CreateAdjMatrix()
    {
        // Matrix will be created here...
    }
}

решение вашей проблемы-Часть 2

теперь у нас есть вся структура данных для хранения графика, давайте заполним его некоторыми данными. Вот код, который инициализирует график, похожий на изображение Куба. Это скучно и скучно, но в реальных случаях график будет создаваться динамически:

static void Main(string[] args)
{
    var graph = new Graph();

    var a = graph.CreateRoot("A");
    var b = graph.CreateNode("B");
    var c = graph.CreateNode("C");
    var d = graph.CreateNode("D");
    var e = graph.CreateNode("E");
    var f = graph.CreateNode("F");
    var g = graph.CreateNode("G");
    var h = graph.CreateNode("H");
    var i = graph.CreateNode("I");
    var j = graph.CreateNode("J");
    var k = graph.CreateNode("K");
    var l = graph.CreateNode("L");
    var m = graph.CreateNode("M");
    var n = graph.CreateNode("N");
    var o = graph.CreateNode("O");
    var p = graph.CreateNode("P");

    a.AddArc(b, 1)
     .AddArc(c, 1);

    b.AddArc(e, 1)
     .AddArc(d, 3);

    c.AddArc(f, 1)
     .AddArc(d, 3);

    c.AddArc(f, 1)
     .AddArc(d, 3);

    d.AddArc(h, 8);

    e.AddArc(g, 1)
     .AddArc(h, 3);

    f.AddArc(h, 3)
     .AddArc(i, 1);

    g.AddArc(j, 3)
     .AddArc(l, 1);

    h.AddArc(j, 8)
     .AddArc(k, 8)
     .AddArc(m, 3);

    i.AddArc(k, 3)
     .AddArc(n, 1);

    j.AddArc(o, 3);

    k.AddArc(p, 3);

    l.AddArc(o, 1);

    m.AddArc(o, 1)
     .AddArc(p, 1);

    n.AddArc(p, 1);

    // o - Already added

    // p - Already added

    int?[,] adj = graph.CreateAdjMatrix(); // We're going to implement that down below

    PrintMatrix(ref adj, graph.AllNodes.Count); // We're going to implement that down below
}

решении ваших проблема - Часть 3

Итак, у нас есть полностью инициализированный граф, давайте создадим матрицу. Следующий метод создает матрицу двух измерений, N на n, где n-количество узлов, которые мы получаем из класса graph. Для поиска узлов, если у них есть ссылка, Если у них есть ссылка, заполненная матрица в соответствующем положении. Посмотрите, что в вашем примере матрицы смежности у вас есть только 1s, Здесь я кладу вес ссылки, я положил этот путь, так что нет смысла в имея взвешенный график!

public int?[,] CreateAdjMatrix()
{
    int?[,] adj = new int?[AllNodes.Count, AllNodes.Count];

    for (int i = 0; i < AllNodes.Count; i++)
    {
        Node n1 = AllNodes[i];

        for (int j = 0; j < AllNodes.Count; j++)
        {
            Node n2 = AllNodes[j];

            var arc = n1.Arcs.FirstOrDefault(a => a.Child == n2);

            if (arc != null)
            {
                adj[i, j] = arc.Weigth;
            }
        }
    }
    return adj;
}

сделал

это сделано, у вас есть взвешенная матрица смежности, каким-то образом ее распечатать:

private static void PrintMatrix(ref int?[,] matrix, int Count)
{
    Console.Write("       ");
    for (int i = 0; i < Count; i++)
    {
        Console.Write("{0}  ", (char)('A' + i));
    }

    Console.WriteLine();

    for (int i = 0; i < Count; i++)
    {
        Console.Write("{0} | [ ", (char)('A' + i));

        for (int j = 0; j < Count; j++)
        {
            if (i == j)
            {
                Console.Write(" &,");
            }
            else if (matrix[i, j] == null)
            {
                Console.Write(" .,");
            }
            else
            {
                Console.Write(" {0},", matrix[i, j]);
            }

        }
        Console.Write(" ]\r\n");
    }
    Console.Write("\r\n");
}

что дает нам следующий выход:

       A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P
A | [  &, 1, 1, ., ., ., ., ., ., ., ., ., ., ., ., ., ]
B | [  1, &, ., 3, 1, ., ., ., ., ., ., ., ., ., ., ., ]
C | [  1, ., &, 3, ., 1, ., ., ., ., ., ., ., ., ., ., ]
D | [  ., 3, 3, &, ., ., ., 8, ., ., ., ., ., ., ., ., ]
E | [  ., 1, ., ., &, ., 1, 3, ., ., ., ., ., ., ., ., ]
F | [  ., ., 1, ., ., &, ., 3, 1, ., ., ., ., ., ., ., ]
G | [  ., ., ., ., 1, ., &, ., ., 3, ., 1, ., ., ., ., ]
H | [  ., ., ., 8, 3, 3, ., &, ., 8, 8, ., 3, ., ., ., ]
I | [  ., ., ., ., ., 1, ., ., &, ., 3, ., ., 1, ., ., ]
J | [  ., ., ., ., ., ., 3, 8, ., &, ., ., ., ., 3, ., ]
K | [  ., ., ., ., ., ., ., 8, 3, ., &, ., ., ., ., 3, ]
L | [  ., ., ., ., ., ., 1, ., ., ., ., &, ., ., 1, ., ]
M | [  ., ., ., ., ., ., ., 3, ., ., ., ., &, ., 1, 1, ]
N | [  ., ., ., ., ., ., ., ., 1, ., ., ., ., &, ., 1, ]
O | [  ., ., ., ., ., ., ., ., ., 3, ., 1, 1, ., &, ., ]
P | [  ., ., ., ., ., ., ., ., ., ., 3, ., 1, 1, ., &, ]