A*(A星)算法Go lang实现
之前发表一个A*的python实现,连接:点击打开链接
最近正在学习Go语言,基本的语法等东西已经掌握了。但是纸上得来终觉浅,绝知此事要躬行嘛。必要的练手是一定要做的。正好离写python版的A*不那么久远。这个例子复杂度中等。还可以把之前用python实现是没有考虑的部分整理一下。
这一版的GO实现更加模块化了,同时用二叉堆来保证了openlist的查找性能。可以说离应用到实现工程中的要求差距不太远了。
package mainimport ("container/heap""fmt""math""strings")import "strconv"type _Point struct {x inty intview string}//========================================================================================// 保存地图的基本信息type Map struct {points [][]_Pointblocks map[string]*_PointmaxX intmaxY int}func NewMap(charMap []string) (m Map) {m.points = make([][]_Point, len(charMap))m.blocks = make(map[string]*_Point, len(charMap)*2)for x, row := range charMap {cols := strings.Split(row, " ")m.points[x] = make([]_Point, len(cols))for y, view := range cols {m.points[x][y] = _Point{x, y, view}if view == "X" {m.blocks[pointAsKey(x, y)] = &m.points[x][y]}} // end of cols} // end of rowm.maxX = len(m.points)m.maxY = len(m.points[0])return m}func (this *Map) getAdjacentPoint(curPoint *_Point) (adjacents []*_Point) {if x, y := curPoint.x, curPoint.y-1; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x+1, curPoint.y-1; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x+1, curPoint.y; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x+1, curPoint.y+1; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x, curPoint.y+1; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x-1, curPoint.y+1; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x-1, curPoint.y; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}if x, y := curPoint.x-1, curPoint.y-1; x >= 0 && x < this.maxX && y >= 0 && y < this.maxY {adjacents = append(adjacents, &this.points[x][y])}return adjacents}func (this *Map) PrintMap(path *SearchRoad) {fmt.Println("map's border:", this.maxX, this.maxY)for x := 0; x < this.maxX; x++ {for y := 0; y < this.maxY; y++ {if path != nil {if x == path.start.x && y == path.start.y {fmt.Print("S")goto NEXT}if x == path.end.x && y == path.end.y {fmt.Print("E")goto NEXT}for i := 0; i < len(path.TheRoad); i++ {if path.TheRoad[i].x == x && path.TheRoad[i].y == y {fmt.Print("*")goto NEXT}}}fmt.Print(this.points[x][y].view)NEXT:}fmt.Println()}}func pointAsKey(x, y int) (key string) {key = strconv.Itoa(x) + "," + strconv.Itoa(y)return key}//========================================================================================type _AstarPoint struct {_Pointfather *_AstarPointgVal inthVal intfVal int}func NewAstarPoint(p *_Point, father *_AstarPoint, end *_AstarPoint) (ap *_AstarPoint) {ap = &_AstarPoint{*p, father, 0, 0, 0}if end != nil {ap.calcFVal(end)}return ap}func (this *_AstarPoint) calcGVal() int {if this.father != nil {deltaX := math.Abs(float64(this.father.x - this.x))deltaY := math.Abs(float64(this.father.y - this.y))if deltaX == 1 && deltaY == 0 {this.gVal = this.father.gVal + 10} else if deltaX == 0 && deltaY == 1 {this.gVal = this.father.gVal + 10} else if deltaX == 1 && deltaY == 1 {this.gVal = this.father.gVal + 14} else {panic("father point is invalid!")}}return this.gVal}func (this *_AstarPoint) calcHVal(end *_AstarPoint) int {this.hVal = int(math.Abs(float64(end.x-this.x)) + math.Abs(float64(end.y-this.y)))return this.hVal}func (this *_AstarPoint) calcFVal(end *_AstarPoint) int {this.fVal = this.calcGVal() + this.calcHVal(end)return this.fVal}//========================================================================================type OpenList []*_AstarPointfunc (self OpenList) Len() int { return len(self) }func (self OpenList) Less(i, j int) bool { return self[i].fVal < self[j].fVal }func (self OpenList) Swap(i, j int) { self[i], self[j] = self[j], self[i] }func (this *OpenList) Push(x interface{}) {// Push and Pop use pointer receivers because they modify the slice's length,// not just its contents.*this = append(*this, x.(*_AstarPoint))}func (this *OpenList) Pop() interface{} {old := *thisn := len(old)x := old[n-1]*this = old[0 : n-1]return x}//========================================================================================type SearchRoad struct {theMap *Mapstart _AstarPointend _AstarPointcloseLi map[string]*_AstarPointopenLi OpenListopenSet map[string]*_AstarPointTheRoad []*_AstarPoint}func NewSearchRoad(startx, starty, endx, endy int, m *Map) *SearchRoad {sr := &SearchRoad{}sr.theMap = msr.start = *NewAstarPoint(&_Point{startx, starty, "S"}, nil, nil)sr.end = *NewAstarPoint(&_Point{endx, endy, "E"}, nil, nil)sr.TheRoad = make([]*_AstarPoint, 0)sr.openSet = make(map[string]*_AstarPoint, m.maxX+m.maxY)sr.closeLi = make(map[string]*_AstarPoint, m.maxX+m.maxY)heap.Init(&sr.openLi)heap.Push(&sr.openLi, &sr.start) // 首先把起点加入开放列表sr.openSet[pointAsKey(sr.start.x, sr.start.y)] = &sr.start// 将障碍点放入关闭列表for k, v := range m.blocks {sr.closeLi[k] = NewAstarPoint(v, nil, nil)}return sr}func (this *SearchRoad) FindoutRoad() bool {for len(this.openLi) > 0 {// 将节点从开放列表移到关闭列表当中。x := heap.Pop(&this.openLi)curPoint := x.(*_AstarPoint)delete(this.openSet, pointAsKey(curPoint.x, curPoint.y))this.closeLi[pointAsKey(curPoint.x, curPoint.y)] = curPoint//fmt.Println("curPoint :", curPoint.x, curPoint.y)adjacs := this.theMap.getAdjacentPoint(&curPoint._Point)for _, p := range adjacs {//fmt.Println("\t adjact :", p.x, p.y)theAP := NewAstarPoint(p, curPoint, &this.end)if pointAsKey(theAP.x, theAP.y) == pointAsKey(this.end.x, this.end.y) {// 找出路径了, 标记路径for theAP.father != nil {this.TheRoad = append(this.TheRoad, theAP)theAP.view = "*"theAP = theAP.father}return true}_, ok := this.closeLi[pointAsKey(p.x, p.y)]if ok {continue}existAP, ok := this.openSet[pointAsKey(p.x, p.y)]if !ok {heap.Push(&this.openLi, theAP)this.openSet[pointAsKey(theAP.x, theAP.y)] = theAP} else {oldGVal, oldFather := existAP.gVal, existAP.fatherexistAP.father = curPointexistAP.calcGVal()// 如果新的节点的G值还不如老的节点就恢复老的节点if existAP.gVal > oldGVal {// restore fatherexistAP.father = oldFatherexistAP.gVal = oldGVal}}}}return false}//========================================================================================func main() {presetMap := []string{". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .","X . X X X X X X X X X X X X X X X X X X X X X X X X X",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .","X X X X X X X X X X X X X X X X X X X X X X X X . X X",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",}m := NewMap(presetMap)m.PrintMap(nil)searchRoad := NewSearchRoad(0, 0, 18, 10, &m)if searchRoad.FindoutRoad() {fmt.Println("找到了, 你看!")m.PrintMap(searchRoad)} else {fmt.Println("找不到路径!")}}
A*(A星)算法Go lang实现的更多相关文章
- POJ 2449 Remmarguts' Date (SPFA + A星算法) - from lanshui_Yang
题目大意:给你一个有向图,并给你三个数s.t 和 k ,让你求从点 s 到 点 t 的第 k 短的路径.如果第 k 短路不存在,则输出“-1” ,否则,输出第 k 短路的长度. 解题思路:这道题是一道 ...
- 算法起步之A星算法
原文:算法起步之A星算法 用途: 寻找最短路径,优于bfs跟dfs 描述: 基本描述是,在深度优先搜索的基础上,增加了一个启发式算法,在选择节点的过程中,不是盲目选择,而是有目的的选的,F=G+H,f ...
- Cocos2d-x 3.1.1 学习日志16--A星算法(A*搜索算法)学问
A *搜索算法称为A星算法.这是一个在图形平面,路径.求出最低通过成本的算法. 经常使用于游戏中的NPC的移动计算,或线上游戏的BOT的移动计算上. 首先:1.在Map地图中任取2个点,開始点和结束点 ...
- A*搜寻算法(A星算法)
A*搜寻算法[编辑] 维基百科,自由的百科全书 本条目需要补充更多来源.(2015年6月30日) 请协助添加多方面可靠来源以改善这篇条目,无法查证的内容可能会被提出异议而移除. A*搜索算法,俗称A星 ...
- Java开源-astar:A 星算法
astar A星算法Java实现 一.适用场景 在一张地图中,绘制从起点移动到终点的最优路径,地图中会有障碍物,必须绕开障碍物. 二.算法思路 1. 回溯法得到路径 (如果有路径)采用“结点与结点的父 ...
- A星算法(Java实现)
一.适用场景 在一张地图中.绘制从起点移动到终点的最优路径,地图中会有障碍物.必须绕开障碍物. 二.算法思路 1. 回溯法得到路径 (假设有路径)採用"结点与结点的父节点"的关系从 ...
- JAVA根据A星算法规划起点到终点二维坐标的最短路径
工具类 AStarUtil.java import java.util.*; import java.util.stream.Collectors; /** * A星算法工具类 */ public c ...
- AStar A* A星 算法TypeScript版本
一 演示效果 二 参考教程 <ActionScript3.0 高级动画教程> + 源码 http://download.csdn.net/download/zhengchengpeng/ ...
- 基于HTML5的WebGL呈现A星算法3D可视化
http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...
随机推荐
- ThinkPHP之中利用commom被继承控制器控制访问每一个控制器方法都需要验证是否已经登录!
防止 <?php namespace Home\Controller; use Think\Controller; class CommonController extends Controll ...
- delphi 资源文件详解
delphi资源文件详解 一.引子: 现在的Windows应用程序几乎都使用图标.图片.光标.声音等,我们称它们为资源(Resource).最简单的使用资源的办法是把这些资源的源文件打入软件包,以方便 ...
- Java 第三天 Gradle和其它
Gradle 是以 Groovy 语言为基础,面向Java应用为主.基于DSL(领域特定语言)语法的自动化构建工具. 下载地址 http://www.gradle.org/downloads 环境变量 ...
- Python自然语言工具包(NLTK)入门
在本期文章中,小生向您介绍了自然语言工具包(Natural Language Toolkit),它是一个将学术语言技术应用于文本数据集的 Python 库.称为“文本处理”的程序设计是其基本功能:更深 ...
- 关于activity_main.xml与fragment_main.xml
第一种解决办法 新版安装SDK文件一开始有两个XML文件,activity_main.xml和fragment_main.xml,不习惯的可以这样处理:1.删除fragment_main.xml整个文 ...
- webpack 学习笔记 02 快速入门
webpack 的目标 将依赖项分块,按需加载. 减少web app的初始加载时间. 使每一个静态集合都能够作为组件使用. 有能力集成第三方库,作为组件使用. 高度可配置化. 适用于大型项目. INS ...
- SQL基础知识----数据类型
VARCHAR(VERiable CHARacter):可变动字符.用于保存以文本格式处处的信息,最大可以储存255个字符.一般使用为VAECHAR(10) --表示最多可以存储10个字符 INT ...
- Swift 1.2 正式发布 - 带来很多重大改进
Swift 1.2 随着 Xcode 6.3 Beta 正式发布了.这次的 beta 发布包含了对 Swift 编译器显著的改进.还有对 Swift 语言本身的新特性的增加.这篇文章介绍下主要部分. ...
- bootstrap bootstrapTable 隐藏列
主要代码: <script type="text/javascript"> $(function () { LoadingDataListOrderRealItems( ...
- Windows Server 2003服务器.net4.0+IIS6.0的服务器,IE11浏览器访问的不兼容性
工作中发生了一件诡异的事情: 程序在Win7+.NET4.0+IIS7.5的服务器部署,IE8和IE11请求时,响应的样式都正常. 但是在美的同事反映说,Windows Server 2003服务器. ...