
cs类
using System;
using System.Collections.Generic;
using System.Text;
/*
new DijkstraAlgCls
then SetMatrix
then Dijkstra
for function Dijkstra the return value is the list of idx (node sequence the start node not included)
* ref float dis is the total route distance
for the matrix
is nodCount*nodeCount matrix the diagonal elements all set to zero matrix[i][j] represents the distance from node i to node j
*/
namespace DijkstraImp
{
class Dijkstragao
{
float[][] matrix;
bool[] flags;
List<int>[] routes;
float[] Distance;
int nodCount;
public Dijkstragao()
{
}
//初始化矩阵
public bool SetMatrix(float[] matr)
{
int n = matr.Length; //取数组长度
double dc = Math.Sqrt((double)n); //取数组长度的算术平方根
nodCount = (int)dc; //计算节点数
dc = dc - nodCount;
if (dc > 0) //如果是无理数
return false;
//初始化一个float类型的二维数组
matrix = new float[nodCount][];
for (int i = 0; i < nodCount; ++i)
{
//二维数组赋null
matrix[i] = new float[nodCount];
}
int idx = 0;
//将martr中的值一一赋给matrix二位数组
for (int i = 0; i < nodCount; ++i)
{
for (int j = 0; j < nodCount; ++j)
{
matrix[i][j] = matr[idx];
idx++;
}
}
//距离数组Distance
Distance = new float[nodCount];
//将数组中的值全部赋值-1,默认为0
for (int i = 1; i < nodCount; ++i)
Distance[i] = -1;
//定义布尔型数组
flags = new bool[nodCount];
//给第一个起点赋值为true
flags[0] = true;
routes = new List<int>[nodCount];
for (int i = 0; i < nodCount; ++i)
routes[i] = new List<int>();
return true;
}
void SetCurLeastFlag()
{
int idx = -1;
float value=-1;
//将路径距离值最小的U集合中的节点分配到S集合中
for (int i = 0; i < nodCount; ++i)
{
if (flags[i] == false)
{
if (value < 0 || (Distance[i]>0&&value > 0 && Distance[i] < value))
{
value = Distance[i];
idx = i;
}
}
}
if (idx > 0)
//将此节点放入S集合
flags[idx] = true;
}
void CalculateLeastDis()
{
//将已经计算过的节点列为S集,未计算的节点列为U集
//这一循环过程可理解为:每进行一次CalculateLeastDis函数运算即可向S集合中添加一个节点
//添加节点意味着添加了一条新路径,在循环中遍历每一条路径以确定最短路径下一个节点
for (int i = 0; i < nodCount; ++i)
{
//通过判断将i节点标志位S集,同时可以理解为i个已求得的路径
if (flags[i] == true)
{
for (int j = 0; j < nodCount; ++j)
{
//通过判断将j节点标志位U集
if (flags[j] == false)
{
//判断i,j节点是否连通
if (matrix[i][j] > 0)
{
float newVal = -1;
//Distance[i]代表S集合中的i节点已经具有的路径距离,大于0表示该节点不是起始节点
if (Distance[i]>0)
newVal = matrix[i][j] + Distance[i];
else
newVal = matrix[i][j];
//判断U集合中的当前j节点是否是第一次参与计算
if (Distance[j] < 0)
{
Distance[j] = newVal;
routes[j].Clear();
if (Distance[i] > 0)
{
foreach (int iv in routes[i])
routes[j].Add(iv);
}
routes[j].Add(j);
}
//若当前路径距离小于已有路径距离,为该节点重新分配路径
else
{
if (newVal < Distance[j])
{
Distance[j] = newVal;
routes[j].Clear();
if (Distance[i] > 0)
{
foreach (int iv in routes[i])
routes[j].Add(iv);
}
routes[j].Add(j);
}
}
}
}
}
}
}
//每生成一条新路径,对所有节点便利从而将新节点编制入S集合(通过flags判断)
SetCurLeastFlag();
}
public float Dijkstra(List<int> retList)
{
Console.WriteLine("节点编号:0,1,2,3,4,5,6,7,8");
float dis = -1;
for (int i = 0; i < nodCount; ++i)
{
CalculateLeastDis();
if (flags[nodCount-1] == true)
{
dis = Distance[nodCount - 1];
foreach (int iv in routes[nodCount - 1])
{
retList.Add(iv);
}
break;
}
}
int index = 0;
Console.WriteLine();
foreach (List<int> li in routes)
{
string list = "";
for (int ii = 0; ii < li.Count; ii++)
{
list += li[ii].ToString() + " ";
}
Console.WriteLine();
Console.WriteLine("至"+(index++).ToString()+"号节点路径:"+list);
li.Clear();
}
routes = null;
return dis;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace DijkstraImp
{
class Program
{
static void Main(string[] args)
{
try
{
Dijkstragao dij = new Dijkstragao();
float[] matr = { 0, 2,-1, 9, 6,-1,-1,-1,-1,
-1, 0, 1,-1, 3,-1,-1,-1,-1,
-1,-1, 0,-1, 1,-1, 6,-1,-1,
-1,-1,-1, 0,-1,-1,-1, 4,-1,
-1,-1,-1, 2, 0, 9,-1, 7,-1,
-1,-1,-1,-1,-1, 0, 5,-1, 1,
-1,-1,-1,-1,-1,-1, 0,-1, 5,
-1,-1,-1,-1,-1, 1,-1, 0, 5,
-1,-1,-1,-1,-1,-1,-1,-1, 0};
if (dij.SetMatrix(matr))
{
List<int> route = new List<int>();
float dis = dij.Dijkstra(route);
dij = null;
Console.ReadLine();
}
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}