看起来您对于图形不太熟悉,可以去维基百科了解一下,并浏览一些图片,这样更容易理解。
概念简介
您的图片可以被视为一个图形(Graph)
。通常,图形使用两种基本元素实现,即 节点(Nodes)
和链接(Links)
(有时称为弧(Arcs)
)。
节点(Node)
代表图片中的字母,例如A、B、C等。一个链接(Arc)
或连接(Link)
是连接两个节点的线条,如果您查看H到L之间的连接,它们之间就有一条链接,在加权图中,不同的链接具有不同的权重。
解决问题 - 第1部分
我们需要在代码中将您的图片表示为一个图形,因此让我们开始创建基本元素节点(Node)
和链接(Arc)
:
节点(Node)
一个节点具有名称(Name)
,以便我们可以识别节点。节点可以与其他节点连接,我们可以使用一组节点,但是由于您的图是加权图,因此每个连接都必须由链接节点及其权重表示。因此,我们使用一组链接(Arcs)
。
public class Node
{
public string Name;
public List<Arc> Arcs = new List<Arc>();
public Node(string name)
{
Name = name;
}
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;
}
图形
图形是一种包装类,用于组织目的。我还声明了一个图形的根部,虽然我们没有使用它,但在几种情况下它很有用:
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()
{
}
}
解决您的问题 - 第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);
int?[,] adj = graph.CreateAdjMatrix();
PrintMatrix(ref adj, graph.AllNodes.Count);
}
解决你的问题 - 第 3 部分
现在,我们有了一个完整初始化的图,让我们创建矩阵。下一个方法创建一个二维矩阵,大小为 n X n,其中 n 是从图形类获取的节点数。对于每个节点,我们搜索它们是否具有链接,如果它们具有链接,则在适当的位置填充矩阵。请注意,在你的邻接矩阵示例中,只有 1
,但在这里,我把链接的权重放进去了。我这样做是为了没有意义的带权图!
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, ., &, ]
Node
和Arc
类,将会非常有用。 - RMalke