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呈现 ...
随机推荐
- canvas 绘圆加边框
HTML5中canvas元素,绘制圆形需要使用路径,开始时要取得图形上下文,首先使用路径来勾勒图形的轮廓,然后设置颜色,进行绘制. arc(cx,cy,radius,start_angle,end_a ...
- LevelDb系列之简介
说起LevelDb也许您不清楚,但是如果作为IT工程师,不知道下面两位大神级别的工程师,那您的领导估计会Hold不住了:Jeff Dean和Sanjay Ghemawat.这两位是Google公司重量 ...
- 写一个函数,尽可能高效的,从一个标准 url 里取出文件的扩展名
例如: http://www.sina.com.cn/abc/de/fg.php?id=1 需要取出 php 或 .php function getExt($url){ $arr=parse_url( ...
- 做个伪IE浏览器?!【来自官网】
原文:docwiki.embarcadero.com/RADStudio/Seattle/en/Building_a_VCL_Forms_Web_Browser_Application 选择File ...
- delphi XE7 中的消息
在delphi XE7的程序开发中,消息机制保证进程间的通信. 在程序中,消息来自: 1)系统: 通知你的程序用户输入,涂画以及其他的系统范围的事件: 2)你的程序:不同的程序部分之间的通信信息. ...
- Ajax 异步调用代码
function jsAjax() { var Con; var XmlRequset; var AjaxContent; //返回内容 if (window.XMLHttpRequest) { // ...
- 【J2EE】Java连接SQL Server 2000问题:“com.microsoft.sqlserver.jdbc.SQLServerException:用户'sa'登录失败。该用户与可信SQL Server连接无关联”
1.问题现象 E:\JSP\HibernateDemo\HibernateDemoProject\src\sine>java ConnectSQLServerConnect failed!com ...
- .NET开源工作流RoadFlow-流程设计-流转条件设置(路由)
当一个步骤后面有多个步骤时,可以设置为根据设置条件系统自动判断该流向哪些步骤,也叫路由. roadflow没有单独的路由步骤来设置条件,流程条件通过双击连线弹出条件设置框来设置. 1.sql条件 即通 ...
- Python input()
在Python语言中,我们经常需要与用户实现交互,下面是一个小实例 # -*- coding:UTF-8 -*- #获取输入参数,并将输入的值存储到txt文件中 String1 = input(&qu ...
- oracle 11g 添加控制文件
OS: Oracle Linux Server release 5.7 DB: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - ...