gpt4 book ai didi

c# - Floyd-Warshall算法如何输出最短路径?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:27:00 29 4
gpt4 key购买 nike

我正在尝试实现 Floyd-Warshall 算法(所有对最短路径)。在下面的代码中,当我输入一些数字时,它会给出最后一个数字作为输入。我知道代码不完整。

现在我应该怎么做才能为每个 i 和 j 打印最短路径?或者你建议我做什么来完成这段代码。谢谢。

private void button10_Click(object sender, EventArgs e)
{

string ab = textBox11.Text;
int matrixDimention = Convert.ToInt32(ab);
int[,] intValues = new int[matrixDimention, matrixDimention];
string[] splitValues = textBox9.Text.Split(',');
for (int i = 0; i < splitValues.Length; i++)
intValues[i / (matrixDimention), i % (matrixDimention)] = Convert.ToInt32(splitValues[i]);
string displayString = "";
for (int inner = 0; inner < intValues.GetLength(0); inner++)
{
for (int outer = 0; outer < intValues.GetLength(0); outer++)
displayString += String.Format("{0}\t", intValues[inner, outer]);
displayString += Environment.NewLine;
}
int n = (int)Math.Pow(matrixDimention, 2);
string strn = n.ToString();

MessageBox.Show("matrix"+strn+ "in" + strn + "is\n\n\n" +displayString);
////before this line i wrote the codes to get the numbers that user enter in textbox and put it in an 2d array
for (int k = 1; k < n+1; k++)

for (int i = 1; i < n+1; i++)

for (int j = 1; j < n+1; j++)

if (intValues[i, j] > intValues[i, k] + intValues[k, j])
{
intValues[i, j] = intValues[i, k] + intValues[k, j];
string str_intvalues = intValues[i, j].ToString();
MessageBox.Show("Shortest Path from i to j is: " + str_intvalues);

}
else
{
string str_intvalues = intValues[i, j].ToString();
MessageBox.Show("Shortest Path from i to j is: " + str_intvalues);
}
}

最佳答案

为了在同一页面上,让我先向您展示 Floyd-Warshall 算法:

让我们有一个图,由矩阵 D 描述,其中 D[i][j] 是边 (i -> j) 的长度 (从图的索引为 i 的顶点到索引为 j 的顶点)

矩阵 D 的大小为 N * N,其中 N 是图中的顶点总数,因为我们可以达到最大值通过将每个图的顶点相互连接来生成路径。

我们还需要矩阵 R,我们将在其中存储最短路径(R[i][j] 包含最短路径中下一个顶点的索引,从顶点 i 开始,到顶点 j 结束。

矩阵 R 的大小与 D 相同。

Floyd-Warshall 算法执行以下步骤:

  1. 用边的端点初始化图中任意两对或顶点之间的所有路径矩阵(这很重要,因为这个值将用于路径重建)

  2. 对于每对连接的顶点(阅读:对于每条边(u -> v))uv,找到形成它们之间最短路径的顶点:如果顶点 k 定义了两条有效边 (u -> k)(k -> v) (如果它们出现在图中),它们一起比路径 (u -> v) 短,然后假设uv 之间的最短路径是通过 k;将边 (u -> v) 的矩阵 R 中的最短轴心点设置为边 (u -> k) 的相应轴心点>

既然我们在同一个页面上定义,算法可以像这样实现:

// Initialise the routes matrix R
for (int i = 0; i < N; i++) {
for (int t = 0; t < N; t++) {
R[i][t] = t;
}
}

// Floyd-Warshall algorithm:
for (int k = 0; k < N; k++) {
for (int u = 0; u < N; u++) {
for (int v = 0; v < N; v++) {
if (D[u, v] > D[u, k] + D[k, v]) {
D[u, v] = D[u, k] + D[k, v];
R[u, v] = R[u, k];
}
}
}
}

但是我们如何读取矩阵D呢?

让我们有一个图表:

Graph

In GraphViz it would be described as follows:

digraph G {
0->2 [label = "1"];
2->3 [label = "5"];
3->1 [label = "2"];
1->2 [label = "6"];
1->0 [label = "7"];
}

我们首先创建一个大小为 4 的二维数组(因为我们的图中恰好有 4 个顶点)

我们初始化它的主对角线(索引相等的项目,例如。G[0, 0]G[1, 1]等) 为零,因为从顶点到自身的最短路径的长度为 0,而其他元素的长度为 (表示它们之间没有边或无限长的边)。定义的元素,对应于图的边,我们用边的长度填充:

int N = 4;
int[,] D = new int[N, N];

for (int i = 0; i < N; i++) {
for (int t = 0; t < N; t++) {
if (i == t) {
D[i, t] = 0;
} else {
D[i, t] = 9999;
}
}
}

D[0, 2] = 1;
D[1, 0] = 7;
D[1, 2] = 6;
D[2, 3] = 5;
D[3, 1] = 2;

算法运行后,矩阵 R 将填充顶点索引,描述它们之间的最短路径。为了重建从顶点 u 到顶点 v 的路径,您需要遵循矩阵 R 的元素:

List<Int32> Path = new List<Int32>();

while (start != end)
{
Path.Add(start);

start = R[start, end];
}

Path.Add(end);

整个代码可以包含在几个方法中:

using System;
using System.Collections.Generic;

public class FloydWarshallPathFinder {
private int N;
private int[,] D;
private int[,] R;

public FloydWarshallPathFinder(int NumberOfVertices, int[,] EdgesLengths) {
N = NumberOfVertices;
D = EdgesLengths;
R = null;
}

public int[,] FindAllPaths() {
R = new int[N, N];

for (int i = 0; i < N; i++)
{
for (int t = 0; t < N; t++)
{
R[i, t] = t;
}
}

for (int k = 0; k < N; k++)
{
for (int v = 0; v < N; v++)
{
for (int u = 0; u < N; u++)
{
if (D[u, k] + D[k, v] < D[u, v])
{
D[u, v] = D[u, k] + D[k, v];
R[u, v] = R[u, k];
}
}
}
}

return R;
}

public List<Int32> FindShortestPath(int start, int end) {
if (R == null) {
FindAllPaths();
}

List<Int32> Path = new List<Int32>();

while (start != end)
{
Path.Add(start);

start = R[start, end];
}

Path.Add(end);

return Path;
}
}

public class MainClass
{
public static void Main()
{
int N = 4;
int[,] D = new int[N, N];

for (int i = 0; i < N; i++) {
for (int t = 0; t < N; t++) {
if (i == t) {
D[i, t] = 0;
} else {
D[i, t] = 9999;
}
}
}

D[0, 2] = 1;
D[1, 0] = 7;
D[1, 2] = 6;
D[2, 3] = 5;
D[3, 1] = 2;

FloydWarshallPathFinder pathFinder = new FloydWarshallPathFinder(N, D);

int start = 0;
int end = 1;

Console.WriteLine("Path: {0}", String.Join(" -> ", pathFinder.FindShortestPath(start, end).ToArray()));
}
}

您可以在 wikipedia 上阅读关于此算法的内容并获取一些自动生成的数据结构here

关于c# - Floyd-Warshall算法如何输出最短路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4526574/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com