| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 500 人关注过本帖
标题:关于Dijkstra算法的问题
只看楼主 加入收藏
shmily009
Rank: 1
等 级:新手上路
帖 子:6
专家分:5
注 册:2007-3-10
收藏
 问题点数:0 回复次数:4 
关于Dijkstra算法的问题
假定无向图为:
图片附件: 游客没有浏览图片的权限,请 登录注册


用于查的两公交站之前最少车站数,查找3到14路不正确,大家看看出了什么问题~详看注释...

程序代码:
Option Explicit

Private Sub Command1_Click()
    Dim a As Long, b As Long
    Dim w() As Long
    Dim tNum As Long
    Dim i As Long, j As Long
   
    tNum = 15
    '初始化权值,与自己的距离为0,若I与J不相邻为-1
    ReDim w(tNum - 1, tNum - 1)
    For i = 0 To tNum - 1
        For j = 0 To tNum - 1
            w(i, j) = IIf(i = j, 0, -1)
        Next
    Next
   
    '下面是手工添加的一些权值,方便测试假设各点间距离为都相同
   
    w(0, 1) = 1
    w(0, 2) = 1
    w(1, 2) = 1
    w(1, 4) = 1
    w(1, 0) = 1
    w(2, 0) = 1
    w(2, 1) = 1
    w(2, 4) = 1
    w(4, 1) = 1
    w(4, 2) = 1
    w(4, 3) = 1
    w(4, 7) = 1
    w(4, 8) = 1
    w(4, 11) = 1
    w(3, 4) = 1
    w(3, 5) = 1
    w(5, 3) = 1
    w(5, 7) = 1
    w(5, 6) = 1
    w(5, 12) = 1
    w(6, 5) = 1
    w(6, 7) = 1
    w(6, 9) = 1
    w(7, 4) = 1
    w(7, 5) = 1
    w(7, 6) = 1
    w(7, 9) = 1
    w(8, 4) = 1
    w(8, 9) = 1
    w(8, 10) = 1
    w(9, 8) = 1
    w(9, 7) = 1
    w(9, 6) = 1
    w(10, 8) = 1
    w(11, 4) = 1
    w(12, 5) = 1
    w(12, 13) = 1
    w(13, 12) = 1
    w(13, 14) = 1
    w(14, 13) = 1
   
    '下面调用显示结果
    a = 3
    b = 10
    Text1.Text = Dijkstra(a, b, tNum, w)                    '这里的结果是正常的3-->4-->8-->10
   
    '更换起点和终点
    a = 3
    b = 14
    Text2.Text = Dijkstra(a, b, tNum, w)                    '这里的结果是3-->14,明显不对,正常应该是3-->5-->12-->13-->14
   
End Sub


'改自网上的一个算法
Function Dijkstra(begin_p As Long, end_p As Long, pointNum As Long, w() As Long) As String
   
    Dim d() As Long
    Dim Bj() As Boolean
    Dim pre() As Long
   
    Dim i As Long
    Dim j As Long
    Dim n As Long
   
    n = pointNum - 1
   
    ReDim d(n)
    ReDim Bj(n)
    ReDim pre(n)
   
    For i = 0 To n
        d(i) = -1
    Next
   
    For i = 0 To n
        Bj(i) = False
    Next
   
    For i = 0 To n
        d(i) = w(begin_p, i)
        pre(i) = begin_p
    Next
   
    Dim dis As Long
    Dim p_num As Long
   
    Bj(begin_p) = True
   
    For i = 0 To n
       
        dis = -1
        p_num = -1
       
        For j = 0 To n
           
            If Not Bj(j) Then
                If (dis = -1) Or (d(j) > 0 And dis > d(j)) Then
                    dis = d(j)
                    p_num = j
                End If
            End If
        Next
       
       
        If p_num > 0 Then
           
            Bj(p_num) = True
           
            For j = 0 To n
               
                If w(p_num, j) > 0 And Not Bj(j) Then
                   
                    If (d(j) = -1) Or (d(j) > -1 And d(p_num) + w(p_num, j) < d(j)) Then
                        d(j) = d(p_num) + w(p_num, j)
                        pre(j) = p_num
                    End If
                End If
            Next
        Else
            Exit For
        End If
    Next
   
    Dim str As String
   
    i = end_p
    str = Trim(i)
    Do While (i <> begin_p)
        i = pre(i)
        str = Trim(i) & "-->" & str
    Loop
   
    Dijkstra = str
   
End Function


搜索更多相关主题的帖子: color 
2013-04-06 21:52
shmily009
Rank: 1
等 级:新手上路
帖 子:6
专家分:5
注 册:2007-3-10
收藏
得分:0 
版主不好意思哈,原来要审核,发了两次...
2013-04-06 22:12
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
有些节点权值未输入,如5,2.
以前只做过图像里的最近路径算法,像素点固定为8个方向的走向(米字形),这个节点的走向不固定,有的1个,有的6个,因此算法不一样。按照你的要求写了个,为方便调试,我并没有做最近路径判断,只是把程序组合到的路径都显示出来,同时还显示了中间数据倒树形结构用于调试,运行效果图如下:
图片附件: 游客没有浏览图片的权限,请 登录注册


'*****************代码如下********************
程序代码:
Private Type nearP
  pP As Integer  '父节点
  sP As Integer  '子节点
End Type

Function Dijkstra(Begin_p As Long, End_p As Long, W() As Long) As String
  Dim i As Integer, j As Integer, k As Long, l As Integer, b() As nearP, c() As String, f As Boolean, m As Integer
  k = 1
  For i = 0 To UBound(W, 1) - 1
    l = 0
    For j = i + 1 To UBound(W, 2)
      If W(i, j) = 1 Then l = l + 1
    Next
    If l > 0 Then k = k * l
  Next
  ReDim b(k) As nearP   '获取最大可能的路径组合
  ReDim c(k) As String
  For i = 0 To UBound(b)
    '初始化父节点和子节点值为-1
    b(i).pP = -1
    b(i).sP = -1
    c(i) = ""
  Next
  b(0).sP = Begin_p
  l = 0
  For i = 0 To UBound(b)
    '穷尽路径节点链路,倒树形结构
    If b(i).sP < 0 Then Exit For
    If b(i).sP <> End_p Then
      For j = 0 To UBound(W, 2)
        If W(b(i).sP, j) = 1 Then
          f = True
          For k = l To 0 Step -1
            If (j = b(k).pP And b(i).sP = b(k).sP) Or (j = b(k).sP And b(i).sP = b(k).pP) Then f = False
          Next
          If f Then
            l = l + 1
            b(l).pP = b(i).sP
            b(l).sP = j
          End If
        End If
      Next
    End If
  Next
  m = 0
  Dijkstra = ""
  For i = 0 To UBound(b)
    '显示倒树形结构数据,用于调试
    If b(i).sP < 0 And b(i).pP < 0 Then Exit For
    Dijkstra = Dijkstra & b(i).pP & "," & b(i).sP & "  "
  Next
  Dijkstra = Dijkstra & vbCrLf
  While m < l
    '显示路径组合,肯定包含最近路径,为便于调试,没有做最近路径判断
    k = End_p
    For i = l To 1 Step -1
      j = b(i).sP
      If j = k Then
        c(m) = "-->" & k & c(m)
        k = b(i).pP
        If j = End_p Then b(i).sP = -1
      End If
    Next
    If c(m) <> "" Then
      c(m) = Begin_p & c(m)
      Dijkstra = Dijkstra & c(m) & vbCrLf
    Else
      m = l
    End If
    m = m + 1
  Wend
End Function

Private Sub Command1_Click()
    Dim a As Long, b As Long
    Dim W() As Long
    Dim tNum As Long
    Dim i As Long, j As Long
  
    tNum = 15
    '初始化权值,与自己的距离为0,若I与J不相邻为-1
    ReDim W(tNum - 1, tNum - 1)
    For i = 0 To tNum - 1
        For j = 0 To tNum - 1
            W(i, j) = IIf(i = j, 0, -1)
        Next
    Next
  
    '下面是手工添加的一些权值,方便测试假设各点间距离为都相同
    W(0, 1) = 1: W(0, 2) = 1
    W(1, 4) = 1: W(1, 2) = 1: W(1, 0) = 1
    W(2, 0) = 1: W(2, 1) = 1: W(2, 4) = 1: W(2, 5) = 1
    W(3, 4) = 1: W(3, 5) = 1
    W(4, 1) = 1: W(4, 2) = 1: W(4, 3) = 1: W(4, 7) = 1: W(4, 8) = 1: W(4, 11) = 1
    W(5, 2) = 1: W(5, 3) = 1: W(5, 6) = 1: W(5, 7) = 1: W(5, 12) = 1
    W(6, 5) = 1: W(6, 7) = 1: W(6, 9) = 1
    W(7, 4) = 1: W(7, 5) = 1: W(7, 6) = 1: W(7, 9) = 1
    W(8, 4) = 1: W(8, 9) = 1: W(8, 10) = 1
    W(9, 6) = 1: W(9, 7) = 1: W(9, 8) = 1
    W(10, 8) = 1
    W(11, 4) = 1
    W(12, 5) = 1: W(12, 13) = 1
    W(13, 12) = 1: W(13, 14) = 1
    W(14, 13) = 1
  
    '下面调用显示结果
    Text1 = ""
    Text1 = Dijkstra(Val(Text2), Val(Text3), W)                   

 End Sub
2013-04-09 07:15
shmily009
Rank: 1
等 级:新手上路
帖 子:6
专家分:5
注 册:2007-3-10
收藏
得分:0 
非常感谢版主认真热情的回复~

贴出来的算法已经找到问题所在,除了您说的权值没写完整,还忽略“0”结点的情况,加上就OK了~

另外,您给出的程序,如果是找出全路径,那结点3到结点9理论上应该不止三条才对吧,像3-4-7-9也算是一条存在的路径径,给出的例子截图好像没有~
2013-04-09 11:15
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:652
专家分:3402
注 册:2008-5-7
收藏
得分:0 
回复 4楼 shmily009
嗯,算法有待改进,全路径数目应该是:起点路径数目*路径2数目*...*终点路径数目
2013-04-09 12:41
快速回复:关于Dijkstra算法的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.037125 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved