(原创)Dijkstra算法
2013-03-26 20:34 Keiven_LY 阅读(215) 评论(0) 编辑 收藏 举报说明:该设计可以任意输入起点和终点
一、界面设计
三个listbox,分别为:listbox1,listbox2,listbox3
ListBox1存放起点到终点的最短路径值
ListBox2存放起点到各个顶点最短路径上,各个顶点的上一节点
ListBox3存放起点到终点最短路径上经过的点
两个Label,分别为Label1,Label2,各自的text为起点和终点
两个TextBox,分别为txt1,txt2,分别用于输入起点和终点
两个Button,分别为Button1,Button2,分别为开始和结束按钮
二、代码如下:
Public Class Form1
'定义二维数组w为节点的带权邻接矩阵,并初始化
Dim Inf As Double = Double.PositiveInfinity '表示正无穷大
Dim w(,) = {{0, Inf, Inf, 1.2, 9.2, Inf, 0.5}, {Inf, 0, Inf, 5, Inf, 3.1, 2}, {Inf, Inf, 0, Inf, Inf, 4, 1.5}, {1.2, 5, Inf, 0, 6.7, Inf, Inf}, {9.2, Inf, Inf, 6.7, 0, 15.6, Inf}, {Inf, 3.1, 4, Inf, 15.6, 0, Inf}, {0.5, 2, 1.5, Inf, Inf, Inf, 0}}
Private k As Integer '用于构造顶点集合数组V()、存放顶点路径l()、存放各顶点的上一顶点t()的循环变量
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'**************************初始化*******************************************
Dim startpoint As Integer '起点
Dim endpoint As Integer '终点
startpoint = Convert.ToInt32(txt1.Text)
endpoint = Convert.ToInt32(txt2.Text)
Dim num As Integer
num = w.GetLength(0) '这里num=7
Dim V(num - 1) As Integer '用于存放顶点的集合
For Me.k = 0 To num - 1
V(k) = k
Next
'以上循环是给数组V()赋初值,即所有顶点的集合
Dim l(num - 1) As Double '数组l()用于存放各顶点到起点的最短距离
For Me.k = 0 To num - 1
l(k) = w(startpoint - 1, k)
Next
'上面的循环目的是给数组l()赋初值,即起点到其他个点的初始距离(这里定义源节点为最后一个节点,故初始距离为邻接矩阵的最后一行)
Dim t(num - 1) As Integer '数组t()用于存放各顶点的上一节点
For Me.k = 0 To num - 1
t(k) = startpoint - 1
Next
'上面的循环目的是初始化各顶点的上一顶点,且都设为源节点
Dim ss(num - 2) As Integer '数组ss()用于存放除源节点以外的所有顶点的编号
For Me.k = 0 To num - 2
ss(k) = k
Next
'上面的循环目的是给数组ss()赋值,即除源节点以外的所有顶点编号
'注:这里数组V(),l(),t(),ss()的大小之所以要用num-1,num-2主要是因为数组是从0开始计数的
Dim nn As Integer 'n表示所有顶点个数,nn表示除源点外的顶点个数
nn = ss.Length '这里nn=6
'*******************************初始化工作结束*************************
Dim cont As Integer = 0
Dim X() As Integer '数组X()存放已经找到最短路的顶点,初始第一个为起点
ReDim X(0)
X(0) = startpoint - 1
Dim i, j As Integer '主体循环的循环变量
Dim m As Integer '用于中间变量
For j = 0 To num - 2
m = ss(0)
For i = 0 To nn - 1
If l(m) > l(ss(i)) Then
m = ss(i)
l(m) = l(ss(i)) '在当前一行距离中取最小值
End If
Next
If l(m) = Inf Then '如果当前行最小值是无穷大,则结束
Else '否则m点的最短路找到
cont = cont + 1
ReDim Preserve X(cont)
X(cont) = m '这三句的作用是将符合条件的m加进数组X()中
Array.Sort(X)
Dim index As Integer = 0
For i = 0 To V.Length - 1
If Array.IndexOf(X, V(i)) = -1 Then
ReDim Preserve ss(index)
ss(index) = V(i)
index += 1
End If
Next
Array.Sort(ss)
'这里的循环是比较数组X()和数组V(),将属于数组V()而不属于数组X()的元素取出来,赋给动态数组ss()
nn = ss.Length
End If
If X.Length = num Then
Else
For i = 0 To nn - 1 ' 以m为生长点,如果通过m点会更短,则更改当前最短距离
If l(ss(i)) > l(m) + w(m, ss(i)) Then
l(ss(i)) = l(m) + w(m, ss(i))
t(ss(i)) = m
End If
Next
End If
Next
Dim tt() As Integer
ReDim tt(0)
tt(0) = endpoint - 1 '动态数组tt()的作用是用来存放源到目的顶点最短路径上经过的节点
Dim mm As Integer '变量mm作为中间变量
mm = endpoint - 1
Dim cont_1 As Integer = 1
For i = 0 To num - 1
If mm = startpoint - 1 Then
Else
mm = t(mm)
ReDim Preserve tt(cont_1)
tt(cont_1) = mm
cont_1 += 1
End If
Next
Array.Reverse(tt) '将数组tt反转排序
For i = 0 To num - 1
listbox1.Items.Add(l(i)) 'ListBox1存放起点到终点的最短路径值
Next
For i = 0 To num - 1
listbox2.Items.Add(t(i) + 1) 'ListBox2存放起点到各个顶点最短路径上,各个顶点的上一节点
Next
For i = 0 To tt.Length - 1
listbox3.Items.Add(tt(i) + 1) 'ListBox3存放起点到终点最短路径上经过的点
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.Close()
End Sub
End Class