A * (a star) algorithm go lang implementation

Source: Internet
Author: User
Tags key string
This is a creation in Article, where the information may have evolved or changed.

Before publishing a A * python implementation, connect: Click the Open link

Recently learning the Go language, basic grammar and other things have been mastered. But the paper came to the end of shallow, I know this matter to preach . The necessary practiced hand must be done. It's not that far from writing a * * python version. This example is of medium complexity. You can also put the previous Python implementation is not considered part of the collation.

This version of the go implementation is more modular, while using a binary stack to ensure the openlist of the search performance. It can be said that the application to the implementation of the requirements of the project is not too far away from the gap.

If anyone finds the code useful, you can use it, but you must let me know. That's not a good request.


Package Mainimport ("Container/heap", "FMT" "Math" "strings") Import "StrConv" 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 int erface{}) {//Push and POP use pointer receivers because they modify the slice ' s length,//isn't just its contents.*this = a Ppend (*this, X. (*_astarpoint))}func (This *openlist) POPs () interface{} {old: = *thisn: = Len (old) x: = Old[n-1]*this = old[ 0:n-1]return X}type _point struct {x inty intview string}//======================================================= =================================//saving basic information for a map type map struct {points [][]_pointblocks Map[string]*_pointmaxx intmaxy I Nt}func Newmap (Charmap []string) (M Map) {m.points = make ([][]_point, Len (charmap)) M.blocks = make (Map[string]*_point, le N (CHARMAP) * *) 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 vie W = = "x" {M.blocks[pointaskey (x, y)] = &m.points[x][y]}}//End of cols}//end of Rowm.maxx = Len (m.points) M.maxy = l En (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, &amp ; 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, &amp ; 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, &amp ; 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, &am P;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, &amp ; 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, &amp ; 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, &amp ; 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 *_As Tarpoint, end *_astarpoint) (AP *_astarpoint) {ap = &_astarpoint{*p, father, 0, 0, 0}if end! = Nil {ap.calcfval (end)}r Eturn 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 + Ten} else if deltax = = 0 && DeltaY = = 1 {this.gval = This.father.gVal + ten} else if deltax = = 1 && DeltaY = = 1 {this.gval = This.father.gVal + +) 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 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, S Tarty, "S"}, nil, nil) Sr.end = *newastarpoint (&_point{endx, Endy, "E"}, Nil, nil) Sr. Theroad = Make ([]*_astarpoint, 0) Sr.openset = Do (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)//First add the starting point to the Open list Sr.openset[pointaskey (Sr.start.x, sr.start.y)] = &sr.start// Put the barrier point in the off list for k, V: = range M.blocks {sr.closeli[k] = Newastarpoint (V, nil, nil)}return Sr}func (this *searchroad) findout Road () bool {for Len (This.openli) > 0 {//To move a node from an open list to a closed list. 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) = = Point Askey (this.end.x, THIS.END.Y) {//Find path, Mark path 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 ()//If the new node's G value is not as good as the old node, restore the old node 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 "," ..... ..... ... ",". ..........................",". ".". ".".  . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . . . . . . . . . . . . . . . . . . . .",". . . . . . . . ... ",}m: = Newmap (Presetmap) m.printmap (nil) Searchroad: = newsearchroad (0, 0, 18, 10, &)... AMP;M) if Searchroad.findoutroad () {fmt. Println ("found out, you see! ") M.printmap (Searchroad)} else {fmt. PRINTLN ("Path not found!") ")}}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.