最短路径算法
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; matrix = new float[nodCount][]; for (int i = 0; i < nodCount; ++i) { matrix[i] = new float[nodCount]; } int idx = 0; for (int i = 0; i < nodCount; ++i) { for (int j = 0; j < nodCount; ++j) { matrix[i][j] = matr[idx]; idx++; } } Distance = new float[nodCount]; for (int i = 1; i < nodCount; ++i) Distance[i] = -1; flags = new bool[nodCount]; 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; } } }