我正在尝试实施Floyd-Warshall Algorithm。要做到这一点,它需要我设置加权图的adjacency matrix
。我该怎么做呢?我知道这些值,并附上了加权图的图片。我试图寻找一些在线的例子,但我似乎找不到任何东西。我理解Floyd-Warshall算法我只是需要帮助才能设置它,所以我能够实现它。这是我之前构建的一个,但我没有必要使用特定的值。
代码:
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;
}
}
}
}
以下是具体的图表:
这是我需要创建的矩阵的图片..抱歉可怕的质量...
答案 0 :(得分:37)
所以,你似乎不熟悉Graphs,看看维基百科。还浏览一些图像,它更容易理解。
您的照片可以表示为Graph
。通常,图表是使用2种基本元素Nodes
和Links
(有时称为Arcs
)实现的。
Node
表示图片中的字母,它们分别是A,B,C等。
Arc
或Link
是连接两个节点的线,如果你看H到L之间的连接,两者之间有一个链接,在加权图中,不同的链接有不同的权重。
我们要做的是在代码中将图片表示为图形,让我们开始创建基本元素Node
和Arc
:
<强>节点强>
节点有Name
,因此我们可以识别节点。并且节点可以连接到其他节点,我们可以使用节点集合,但是您的节点是加权图,因此,每个连接必须由链接节点表示,并且它的权重。因此,我们使用Arcs集合。
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;
}
}
<强>电弧强>
非常简单的类,它包含链接的节点和连接的权重:
public class Arc
{
public int Weigth;
public Node Parent;
public Node Child;
}
<强>图形强>
Graph是一种包装类,用于组织目的。我也为图表声明了一个Root,我们没有使用它,但在几种情况下很有用:
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...
}
}
现在我们拥有了用于保存图形的所有数据结构,让我们用一些数据填充它。这是一些初始化类似于您的立方体图片的图形的代码。它枯燥乏味,但在现实生活中,图表将动态创建:
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
}
因此,我们有一个完整的初始化图,让我们创建矩阵。下一个方法创建一个二维矩阵,n乘n,其中n是我们从图类中得到的节点数。对于节点的Foreach,我们搜索它们是否有链接,如果它们有链接,则在适当的位置填充矩阵。看看在你的邻接矩阵示例中,你只有1
s,这里我把链接的权重,我这样说,所以加权图是没有意义的!
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, ., &, ]