dijkstra该算法主要应用在求解最短路径,从最近点开始,广度搜索。
假设有向图中有10个顶点,求其中某个顶点a到其它顶点的最短路径。。满足贪心算法的2个标准。时间复杂度为O(N2)
此问题可以进行分解。某个顶点a到到其他顶点c必定是从a直接到c 或者是从a到离a最近的顶点b,再到c。
算法思想:
初始化:
d[] 已计算顶点集合 初始为原点a
s[] 待计算顶点集合 初始为除了a外其他顶点
minlen[] 每次找到的最近点与其它点s[]的距离
过程:
从a点开始,遍历与其他顶点(s[])的距离minlen[]。找到距离a点最近的顶点(x) 把x加到d[]中,s[]中减去,并更新minlen[]中距离
重复这个过程。
所以是两个for循环嵌套,时间复杂度为O(n2)
参照百度cijkstra java写的代码,看到很少有c#的 ,就写了个。
1 static void Main(string[] args) 2 { 3 double[,] path = getpath(10);//随机生成10个点之间的距离矩阵 4 Dictionary<int, double> result = getr(path);//result<点,距离> 5 6 } 7 public static Dictionary<int, double> getr(double[,] da) 8 { 9 Dictionary<int, double> result = new Dictionary<int, double>(); 10 result.Add(0, 0); //默认添加首点 11 int n =Convert.ToInt32(Math.Sqrt(da.Length)); 12 double[] minlen =new double[n];//存储每次找到的最近点距离其它点的距离 13 int[] visit =new int[n]; //一共0到9点 计算过后的点为1 14 for(int i=0;i<n;i++){ 15 minlen[i] = da[0, i];//初始化首点与其它点距离 16 } 17 visit[0] = 1; //默认第一点为原点,已经添加到visit集合 18 int minj = 0; //遍历循环默认第一点最小 19 for (int i = 0; i < n; i++) { 20 double min = double.PositiveInfinity; 21 for (int j =0; j < n ; j++) { 22 if (visit[j] == 0 && minlen[j] < min) {//遍历minlen 找到最小 23 min = minlen[j];//j循环最小值 24 minj = j; //第minj最小 25 } 26 } 27 if (min == double.PositiveInfinity) return result;//测试数据有可能出现x点到其它点没有距离 28 visit[minj] = 1; //第minj点已添加 29 result.Add(minj,min); 30 for (int j = 0; j < n ; j++)//重新计算minlen 31 { 32 if (visit[j] == 0 && minlen[minj] !=double.PositiveInfinity 33 && da[minj,j] != double.PositiveInfinity 34 && minlen[j] > (minlen[minj] + da[minj,j])) 35 { 36 minlen[j] = minlen[minj] + da[minj,j]; 37 } 38 } 39 } 40 return result; 41 } 42 public static double[,] getpath(int num) { 43 Random rd=new Random(); 44 double[,] path = new double[num, num]; 45 for (int i = 0; i < num; i++) 46 { 47 for (int j = 0; j < num; j++) 48 { 49 path[i, j] = rd.Next(1,100);//生成测试数据 50 if (path[i, j] > 60 || i == j) path[i, j] = double.PositiveInfinity; 51 } 52 } 53 return path; 54 }
浙公网安备 33010602011771号