在好例子网,分享、交流、成长!
您当前所在位置:首页Others 开发实例一般编程问题 → A*算法VB实例(A星算法(八方向))

A*算法VB实例(A星算法(八方向))

一般编程问题

下载此实例
  • 开发语言:Others
  • 实例大小:5.68KB
  • 下载次数:17
  • 浏览次数:1086
  • 发布时间:2018-07-21
  • 实例类别:一般编程问题
  • 发 布 人:DearChen
  • 文件格式:.rar
  • 所需积分:2
 相关标签: 算法 实例 vb A星

实例介绍

【实例简介】A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法算法中的距离估算值与实际值越接近,最终搜索速度越快。

【实例截图】

from clipboard

【核心代码】


Option Explicit

Private Const 障碍 As Integer = 1
Private Const 通道 As Integer = 0

Public Type POINTS
        x As Integer
        y As Integer
End Type

Private Type AStarNode
        pos As POINTS           '该节点的坐标
        father As POINTS
        G As Integer
        H As Integer
        style As Integer        '类型,是否可行走
End Type

Public OpenNum As Integer '开启列表中的总结点数-1
Public CloseNum As Integer '关闭列表中的总结点数-1

Public OpenList() As AStarNode         '开启表
Public CloseList() As AStarNode        '关闭表
Public AStarMap() As AStarNode       '地图

'计算出来的地图尺寸
Private minX As Integer
Private minY As Integer
Private maxX As Integer
Private maxY As Integer

 '参数:要寻路的二维地图,寻路起点,寻路终点
 '返回值:1找到路径,路径存在AStarPath中 0未找到路径
Public AStarPath() As POINTS           '路径
Public PathLength As Integer          '路径长度
Public Function AStar(map() As Integer, startP As POINTS, endP As POINTS) As Integer
        Dim AstartP As AStarNode        '起点
        Dim AendP As AStarNode          '终点
        Dim p As POINTS                         '指针
        Dim ArrLength As Long           '数组长度
        
        Dim minFP As AStarNode       '最小F值的节点
        Dim i As Integer                '找最小F值for循环的循环变量
        

        
        '只算一次,降低时间开销
        minX = LBound(map, 1)
        maxX = UBound(map, 1)
        
        minY = LBound(map, 2)
        maxY = UBound(map, 2)
        
        ArrLength = (UBound(map, 1) - LBound(map, 1) 1) * (UBound(map, 2) - LBound(map, 2) 1) - 1
        ReDim OpenList(ArrLength) '确定最大范围
        ReDim CloseList(ArrLength)
        ReDim AStarPath(ArrLength)
        
        '初始化
        OpenNum = -1: CloseNum = -1
        PathLength = 0
        
        AstartP.pos = startP     '将传进来的坐标转换成AStar的节点类型
        AendP.pos = endP
        CreateAStarMap map, AstartP, AendP              '根据游戏地图创建本次寻路的A星地图
        
        AddOpenList AStarMap(AstartP.pos.x, AstartP.pos.y)    '将起点加入开启表
        
        Do
                If OpenNum = -1 Then AStar = 0: Exit Do   '当开启列表为空时,退出循环(没有找到路径)

                '把开启列表中G H值最小的点找出来(有多个相同最小值的话,找出靠前的那个)
                minFP = OpenList(0)
                For i = 0 To OpenNum
                        If minFP.G minFP.H > OpenList(i).G OpenList(i).H Then       '找数组中最小数
                                minFP = OpenList(i)
                        End If
                Next i
                
                '把这个点从开启列表中删除,加入到关闭列表
                DelOpenList minFP
                AddCloseList minFP
                
                '搜索该点的邻居
                Call Neighbor_Search(minFP, 0, -1)      '上
                Call Neighbor_Search(minFP, 0, 1)      '下
                Call Neighbor_Search(minFP, -1, 0)     '左
                Call Neighbor_Search(minFP, 1, 0)      '右
                
                '这里是八方寻路,用不上可以直接注释掉
                Call Neighbor_Search(minFP, -1, -1)      '上左
                Call Neighbor_Search(minFP, 1, -1)     '上右
                Call Neighbor_Search(minFP, -1, 1)     '下左
                Call Neighbor_Search(minFP, 1, 1)      '下右
                
                
                If CheckCloseNode(AendP) = True Then    '如果终点在关闭列表中,就说明找到了通路,用回溯的方法记录路径
                        AStar = 1
                        '寻找回路
                        p = AendP.pos
                        Do
                                AStarPath(PathLength) = p
                                PathLength = PathLength 1
                                p = AStarMap(p.x, p.y).father           '指针移动
                                If p.x = startP.x And p.y = startP.y Then Exit Do
                        Loop
                        Exit Function
                End If
        Loop
        
        AStar = 0
        'Debug.Print AStarMap(0, 0).H: Debug.Print AStarMap(1, 1).H
End Function

'根据游戏地图创建AStar的寻路地图
Private Sub CreateAStarMap(map() As Integer, startP As AStarNode, endP As AStarNode)

        Dim x  As Integer
        Dim y As Integer

        ReDim AStarMap(maxX - minX, maxY - minY) '根据游戏地图确定寻路地图尺寸
        
        '生成寻路地图
        For x = minX To maxX
                For y = minY To maxY
                        If map(x, y) = 1 Then
                                AStarMap(x, y).style = 障碍
                                AStarMap(x, y).G = 0            '初始化成0,到需要的时候再重新计算
                                AStarMap(x, y).H = (Abs(x - endP.pos.x) Abs(y - endP.pos.y)) * 10    '对于相同的起点和终点,H为定值,我们需要在这里一次性计算好(曼哈顿距离)
                                AStarMap(x, y).pos.x = x
                                AStarMap(x, y).pos.y = y
                        ElseIf map(x, y) = 0 Then
                                AStarMap(x, y).style = 通道
                                AStarMap(x, y).G = 0
                                AStarMap(x, y).H = (Abs(x - endP.pos.x) Abs(y - endP.pos.y)) * 10
                                AStarMap(x, y).pos.x = x
                                AStarMap(x, y).pos.y = y
                        End If
                Next y
        Next x
        
End Sub

'参数:需要添加进来的节点(添加在线性表的尾部)
Private Function AddOpenList(pos As AStarNode) As Integer

        OpenNum = OpenNum 1   '总节点数 1
        OpenList(OpenNum) = pos    '添加节点

End Function

'参数:需要删除的节点(删除后,将线性表尾部节点补充到删除后的空缺位置,为了减小时间复杂度)
Private Function DelOpenList(pos As AStarNode) As Integer

        Dim t  As AStarNode '临时节点,用于做变量交换
        Dim c As AStarNode '临时节点,用于清空对象
        Dim i As Integer
        For i = 0 To OpenNum
                If OpenList(i).pos.x = pos.pos.x And OpenList(i).pos.y = pos.pos.y Then '找到要删除的节点(目标节点)
                        t = OpenList(OpenNum)   't指向开启表中最后一个节点
                        OpenList(OpenNum) = c   '删除最后一个节点
                        OpenList(i) = t         '把最后一个节点覆盖到目标节点
                        OpenNum = OpenNum - 1   '开启表长度-1
                        Exit For        '结束不必要的循环
                End If
        Next i
        
        
End Function

'参数:需要添加进来的节点(添加在线性表的尾部)
Private Function AddCloseList(pos As AStarNode) As Integer

        CloseNum = CloseNum 1   '总节点数 1
        CloseList(CloseNum) = pos    '添加节点

End Function

'确认传入节点是否存在于开启表中
Private Function CheckNode(node As AStarNode) As Boolean

        Dim i As Integer
        For i = 0 To OpenNum
                If OpenList(i).pos.x = node.pos.x And OpenList(i).pos.y = node.pos.y Then       '找到了
                        CheckNode = True
                        Exit Function
                End If
        Next i
        CheckNode = False
        
End Function

'确认是否在关闭表里
Private Function CheckCloseNode(node As AStarNode) As Boolean

        Dim i As Long
        For i = 0 To CloseNum
                If CloseList(i).pos.x = node.pos.x And CloseList(i).pos.y = node.pos.y Then       '找到了
                        CheckCloseNode = True
                        Exit Function
                End If
        Next i
        CheckCloseNode = False
        
End Function

'功能:
'更新开启表中的G值
Private Sub UpdataG()
        Dim i As Integer
        For i = 0 To OpenNum
                If OpenList(i).G <> AStarMap(OpenList(i).pos.x, OpenList(i).pos.y).G Then
                        OpenList(i).G = AStarMap(OpenList(i).pos.x, OpenList(i).pos.y).G
                End If
        Next i
End Sub

Private Sub Neighbor_Search(minFP As AStarNode, offsetX As Integer, offsetY As Integer)
                Dim AStep As Integer
                '越界检测
                If minFP.pos.x offsetX > maxX Or minFP.pos.x offsetX < 0 Or minFP.pos.y offsetY > maxY Or minFP.pos.y offsetY < 0 Then Exit Sub
                If offsetX = 0 Or offsetY = 0 Then      ' 设置单位花费
                        AStep = 10
                Else
                        AStep = 14
                End If
                '如果该邻居不是障碍并且不在关闭表中
                If AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).style <> 障碍 And CheckCloseNode(AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY)) = False Then
                        'AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).G = minFP.G AStep      '给G赋值
                        If CheckNode(AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY)) = True Then '存在于开启表中
                                If minFP.G AStep < AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).G Then '如果走新路径更短就更换父节点
                                        AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).G = minFP.G AStep
                                        AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).father = minFP.pos
                                        Call UpdataG    '更新Openlist中的G值
                                End If
                        Else    '不存在于开启表中
                                '设置该邻居的父节点为我们上面找到的最小节点(minFP)
                                AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).father = minFP.pos
                                '计算该点(邻居)的G值
                                AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY).G = minFP.G AStep
                                '把该点加入开启表中
                                AddOpenList AStarMap(minFP.pos.x offsetX, minFP.pos.y offsetY)
                        End If
                End If

End Sub


标签: 算法 实例 vb A星

实例下载地址

A*算法VB实例(A星算法(八方向))

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有1条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警