Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ParallelDijkstra
{
class Program
{
static void Main(string[] args)
{
int[,] c=new int[5,5];
Parallel.For(0, 5, (i) =>
{
Parallel.For(0, 5, (j) =>
{
c[i,j] = Dijkstra.MaxInt;
}
);
}
);
c[0, 1] = c[1, 0] = 10;
c[0, 3] = c[3, 0] = 30;
c[0, 4] = c[4, 0] = 100;
c[1, 2] = c[2, 1] = 50;
c[2, 4] = c[4, 2] = 10;
c[3, 2] = c[2, 3] = 20;
c[3, 4] = c[4, 3] = 60;
int[] dist;
int[] prev;
Dijkstra.Execute(5, 0, c, out dist, out prev);
string path = Dijkstra.ParsePath(prev,0,4);
Console.WriteLine(path);
Console.ReadKey();
}
}
}
Dijkstra.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ParallelDijkstra
{
public class Dijkstra
{
public static int MaxInt = 999999;
/// <summary>
/// 执行最短路径分析
/// </summary>
/// <param name="n">结点个数</param>
/// <param name="v">源点</param>
/// <param name="c">路径权值矩阵</param>
/// <param name="dist">从源点出发至各节点的最短路径值列表</param>
/// <param name="prev">记录每一个结点的前一个最短路径结点</param>
public static void Execute(int n, int v, int[,] c,out int[] dist, out int[] prev)
{
int[] tmpDist=new int[n];
int[] tmpPrev=new int[n];
bool[] s = new bool[100]; // 判断是否已存入该点到S集合中
Parallel.For(0, n, (i) =>
{
tmpDist[i] = c[v,i];
s[i] = false;
if (tmpDist[i] == MaxInt)
tmpPrev[i] = -1;
else
tmpPrev[i] = v;
}
);
tmpDist[v] = 0;
s[v] = true;
//依次将未放入S集合的结点中,取dist[]最小值的结点,放入集合S之中
//一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
Parallel.For(1, n, (i) =>
{
int tmp = MaxInt;
int u = v;
// 找出当前未使用的点j的dist[j]最小值
Parallel.For(0, n, (j) =>
{
if (!s[j] && tmpDist[j] < tmp)
{
u = j; //u保存当前邻接点中距离最小的点的号码
tmp=tmpDist[j];
}
}
);
s[u] = true; //表示u点已存入S集合中
//更新dist
Parallel.For(0, n, (j) =>
{
if (!s[j] && c[u,j] < MaxInt)
{
int newDist = tmpDist[u] + c[u,j];
if (newDist < tmpDist[j])
{
tmpDist[j] = newDist;
tmpPrev[j] = u;
}
}
}
);
}
);
dist=tmpDist;
prev=tmpPrev;
}
/// <summary>
/// 获取从点v至点u的最短路径描述字符串
/// </summary>
/// <param name="prev">记录每一个结点的前一个最短路径结点</param>
/// <param name="v">起点</param>
/// <param name="u">终点</param>
/// <returns>从点v至点u的最短路径描述字符串</returns>
public static String ParsePath(int[] prev, int v, int u)
{
String path = "没有有效路径.";
int tot=0;
List<int> que = new List<int>();
que.Add(u);
tot++;
int tmp=prev[u];
while (tmp != v && tmp != -1)
{
que.Add(tmp);
tot++;
tmp=prev[tmp];
}
if (tmp != -1)
{
que.Add(v);
path=String.Empty;
for (int i = tot; i > 0; i--)
{
path += que[i].ToString() + "-->";
}
path += que[0].ToString();
}
return path;
}
}
}
输出结果:
0-->3-->2-->4