├── CHANGELOG ├── CONTRIBUTORS ├── LICENSE ├── README.md ├── doc └── ruby │ └── doc_here ├── examples ├── c++ │ ├── main │ └── main.cpp ├── python │ └── NumberPuzzle.py └── ruby │ └── 15boardGame.rb └── libs ├── c++ ├── a_node.h └── a_star.h ├── python └── AStar.py └── ruby └── AlgorithmA.rb /CHANGELOG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vandersonmr/A_Star_Algorithm/c9bbb1a54966ede61cd4742aaff753dd1c514ce7/CHANGELOG -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | This project has started at State University of Maringá. 2 | We want to thanks everyone that have contribuited with it: 3 | 4 | Ruby version: 5 | Vanderson M. do Rosario 6 | Diogo Murata 7 | 8 | Python version: 9 | João A. de Jesus Jr 10 | João M. Velasques Faria 11 | 12 | C++ version: 13 | Marcos Yukio Siraichi 14 | Lucas Georges Helal 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Vanderson M. do Rosario , 4 | Diogo Murata . 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | A_Star_Algorithm 2 | ================ 3 | 4 | This project contains implementation of A_Star_Algorithm easily to use in a lot of languages. 5 | -------------------------------------------------------------------------------- /doc/ruby/doc_here: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vandersonmr/A_Star_Algorithm/c9bbb1a54966ede61cd4742aaff753dd1c514ce7/doc/ruby/doc_here -------------------------------------------------------------------------------- /examples/c++/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vandersonmr/A_Star_Algorithm/c9bbb1a54966ede61cd4742aaff753dd1c514ce7/examples/c++/main -------------------------------------------------------------------------------- /examples/c++/main.cpp: -------------------------------------------------------------------------------- 1 | // Algorithm that solves the 15(fifteen) puzzle. 2 | // Developed by 3 | // - Marcos Yukio Siraichi 4 | // - Lucas Georges Helal 5 | 6 | #include 7 | #include 8 | #include 9 | #include "../../libs/c++/a_star.h" 10 | 11 | float out_of_order_heuristic(int mat[][4]) { 12 | int n = 1; 13 | float pieces_n = 0; 14 | for(int i=0; i<4; i++) { 15 | for(int j=0; j<4; j++) { 16 | if(mat[i][j] != n) pieces_n++; 17 | n++; 18 | } 19 | } 20 | return pieces_n; 21 | } 22 | 23 | float out_of_sequence_heuristic(int mat[][4]) { 24 | float pieces_n = 0; 25 | int next_lin, next_col; 26 | for(int i=0; i<4; i++) { 27 | for(int j=0; j<4; j++) { 28 | if(mat[i][j] != 0) { 29 | next_col = j+1; 30 | next_lin = i; 31 | if((j == 3) && (i != 3)) { 32 | next_col = 0; 33 | next_lin = i+1; 34 | } 35 | if(!((i == 3) && (j == 3)) && (mat[i][j]+1 != mat[next_lin][next_col])) 36 | pieces_n++; 37 | } 38 | } 39 | } 40 | return pieces_n; 41 | } 42 | 43 | float calc_dist(int mat[][4], int lin, int col) { 44 | int pos_lin, pos_col; 45 | float total; 46 | pos_lin = (mat[lin][col] - 1) / 4; 47 | pos_col = (mat[lin][col] - 1) % 4; 48 | pos_lin -= lin; 49 | pos_col -= col; 50 | if(pos_lin < 0) pos_lin *= -1; 51 | if(pos_col < 0) pos_col *= -1; 52 | return (float) (pos_lin + pos_col); 53 | } 54 | 55 | float rect_distance_heuristic(int mat[][4]) { 56 | float mov = 0; 57 | int n = 1; 58 | for(int i=0; i<4; i++) { 59 | for(int j=0; j<4; j++) { 60 | if(mat[i][j] != 0) 61 | if(mat[i][j] != n) 62 | mov += calc_dist(mat, i, j); 63 | n++; 64 | } 65 | } 66 | return mov; 67 | } 68 | 69 | float calculate_h(int matrix[][4]) { 70 | return (out_of_order_heuristic(matrix) + 71 | out_of_sequence_heuristic(matrix) + 72 | rect_distance_heuristic(matrix)); 73 | } 74 | 75 | std::string generate_key(int mat[][4]) { 76 | std::string key = ""; 77 | for(int i=0; i<4; i++) { 78 | for(int j=0; j<4; j++) { 79 | if(mat[i][j] < 10) key += "0"; 80 | key += mat[i][j]; 81 | } 82 | } 83 | return key; 84 | } 85 | 86 | void print(int mat[][4]) { 87 | for(int i=0; i<4; i++) { 88 | for(int j=0; j<4; j++) { 89 | if(mat[i][j] > 9) std::cout << mat[i][j] << " "; 90 | else std::cout << mat[i][j] << " "; 91 | } 92 | std::cout << std::endl; 93 | } 94 | } 95 | 96 | bool node_equal(int matrix1[][4],int matrix2[][4]) { 97 | for(int i=0; i<4; i++) { 98 | for(int j=0; j<4; j++) { 99 | if(matrix1[i][j] != matrix2[i][j]) return false; 100 | } 101 | } 102 | return true; 103 | } 104 | 105 | void swap_block(int matrix[][4], int lin, int col, int lin_t, int col_t) { 106 | int aux; 107 | aux = matrix[lin][col]; 108 | matrix[lin][col] = matrix[lin_t][col_t]; 109 | matrix[lin_t][col_t] = aux; 110 | } 111 | 112 | void copy_m(int m[][4], int m2[][4]) { 113 | for(int i=0; i<4; i++) { 114 | for(int j=0; j<4; j++) { 115 | m[i][j] = m2[i][j]; 116 | } 117 | } 118 | } 119 | 120 | std::vector *create_nodes(int matrix[][4]) { 121 | std::vector *new_nodes = new std::vector(); 122 | int (*new_node)[4] = new int[4][4]; 123 | int i, j; 124 | for(i=0; i<4; i++) { 125 | for(j=0; j<4; j++) { 126 | if(matrix[i][j] == 0) break; 127 | } 128 | if(matrix[i][j] == 0 && j < 4) break; 129 | } 130 | copy_m(new_node, matrix); 131 | if(i != 0) { 132 | swap_block(new_node, i, j, i-1, j); 133 | new_nodes->push_back(new_node); 134 | new_node = new int[4][4]; 135 | copy_m(new_node, matrix); 136 | } 137 | if(i != 3) { 138 | swap_block(new_node, i, j, i+1, j); 139 | new_nodes->push_back(new_node); 140 | new_node = new int[4][4]; 141 | copy_m(new_node, matrix); 142 | } 143 | if(j != 0) { 144 | swap_block(new_node, i, j, i, j-1); 145 | new_nodes->push_back(new_node); 146 | new_node = new int[4][4]; 147 | copy_m(new_node, matrix); 148 | } 149 | if(j != 3) { 150 | swap_block(new_node, i, j, i, j+1); 151 | new_nodes->push_back(new_node); 152 | } 153 | return new_nodes; 154 | } 155 | 156 | float calc_g(int m[][4], int m2[][4]) { 157 | return 1; 158 | } 159 | 160 | int main() { 161 | int s[4][4], e[4][4]; 162 | int n=1; 163 | for(int i=0; i<4; i++) { 164 | for(int j=0; j<4; j++) { 165 | e[i][j] = n; 166 | n++; 167 | } 168 | } 169 | e[3][3] = 0; 170 | int m[16] = {2,6,8,3,1,14,9,11,7,12,13,0,5,15,4,10}; 171 | for (int o=0; o<16; o++) { 172 | s[o/4][o%4] = m[o]; 173 | } 174 | print(s); 175 | 176 | a_star astar(&calculate_h, &calc_g, &generate_key, &node_equal, &create_nodes); 177 | std::list *path; 178 | path = astar.do_a_star(s, e); 179 | int mov = path->size(); 180 | for(std::list::iterator i=path->begin(); i!=path->end(); i++) { 181 | std::cout << std::endl; 182 | print(*i); 183 | std::cout << std::endl; 184 | } 185 | std::cout << "Moves: " << mov << std::endl; 186 | } 187 | 188 | -------------------------------------------------------------------------------- /examples/python/NumberPuzzle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Created by Joao A. Jesus Jr. 3 | # Joao M. Velasques Faria 4 | import sys 5 | sys.path.append("../../libs/python/") 6 | import AStar 7 | 8 | class NumberPuzzle(AStar.AStar): 9 | def distBetween(self,current,neighbor): 10 | coord = [] 11 | for i in range(len(current)): 12 | for j in range(len(current[i])): 13 | if current[i][j] == 0 or neighbor[i][j] == 0: 14 | coord.append([i,j]) 15 | if len(coord) == 2: 16 | firstPosition = coord[0][0] * len(current) + coord[0][1] 17 | secondPosition = coord[1][0] * len(current) + coord[1][1] 18 | return abs(firstPosition - secondPosition) 19 | return 0 20 | 21 | def heuristicEstimate(self,start,goal): 22 | cost = 0 23 | for i in range(len(start)): 24 | for j in range(len(start[i])): 25 | if start[i][j] != goal[i][j]: 26 | cost += 1 27 | return cost 28 | 29 | def neighborNodes(self,current): 30 | for i in range(len(current)): 31 | for j in range(len(current[i])): 32 | if current[i][j] == 0: 33 | nodes = [] 34 | if i-1 >= 0: 35 | nodes.append(self.makeMove(current,i-1,j,i,j)) 36 | if i+1 < len(current): 37 | nodes.append(self.makeMove(current,i+1,j,i,j)) 38 | if j-1 >= 0: 39 | nodes.append(self.makeMove(current,i,j-1,i,j)) 40 | if j+1 < len(current[i]): 41 | nodes.append(self.makeMove(current,i,j+1,i,j)) 42 | return nodes 43 | return [] 44 | 45 | def makeMove(self,current,i,j,x,y): 46 | lst = map(list,current) 47 | temp = lst[x][y] 48 | lst[x][y] = lst[i][j] 49 | lst[i][j] = temp 50 | return tuple(map(tuple,lst)) 51 | 52 | def printPath(self,path): 53 | for i in path: 54 | for j in i: 55 | for k in j: 56 | print "%2d" % k, 57 | print 58 | print 59 | print "%d Movements" % (len(path) - 1) 60 | 61 | if __name__ == "__main__": 62 | if len(sys.argv) > 1: 63 | finalState = ((1,2,3,4),(5,6,7,8),(9,10,11,12),(13,14,15,0)) 64 | 65 | puzzle = NumberPuzzle() 66 | 67 | if sys.argv[1] == "1": 68 | example1 = ((1,6,2,3),(5,10,7,4),(9,14,11,8),(13,0,15,12)) 69 | path = puzzle.aStar(example1,finalState) 70 | 71 | elif sys.argv[1] == "2": 72 | example2 = ((2,0,3,4),(1,6,7,8),(5,9,10,11),(13,14,15,12)) 73 | path = puzzle.aStar(example2,finalState) 74 | 75 | elif sys.argv[1] == "3": 76 | example3 = ((2,6,8,3),(1,14,9,11),(7,12,13,0),(5,15,4,10)) 77 | path = puzzle.aStar(example3,finalState) 78 | 79 | elif sys.argv[1] == "re4": 80 | residentEvil4 = ((2,3,6),(5,0,8),(1,4,7)) 81 | residentEvil4Final = ((1,2,3),(4,5,6),(7,8,0)) 82 | path = puzzle.aStar(residentEvil4,residentEvil4Final) 83 | 84 | else: 85 | print "Invalid arg." 86 | sys.exit(0) 87 | 88 | puzzle.printPath(path) 89 | 90 | else: 91 | print "Insert an arg. (1, 2, 3, or re4)" 92 | 93 | -------------------------------------------------------------------------------- /examples/ruby/15boardGame.rb: -------------------------------------------------------------------------------- 1 | 2 | # Algorithm A* 3 | # Devlopers: Vanderson M. Rosario 4 | # Diogo T. Murata 5 | # This code is under MIT licence. 6 | # 7 | # board[4][4] being 1 a position ocupated and 0 for blank. 8 | # 0 - blank 9 | # 1 - Ocupated 10 | 11 | load '../../libs/ruby/AlgorithmA.rb' 12 | 13 | def printBoard(board) 14 | puts "" 15 | board.each do |line| 16 | puts "" 17 | line.each do |item| 18 | print "| #{item} |" 19 | end 20 | end 21 | puts "" 22 | end 23 | 24 | def getBlankPosition(board) 25 | x = 0 26 | y = 0 27 | board.each do |line| 28 | y=0 29 | line.each do |item| 30 | if (item == 0) 31 | return x,y 32 | end 33 | y=y+1 34 | end 35 | x=x+1 36 | end 37 | end 38 | 39 | def distanceBetween(board1,board2) 40 | b1x,b1y = getBlankPosition(board1) 41 | b2x,b2y = getBlankPosition(board2) 42 | return (b1x-b2x).abs + (b1y-b2y).abs 43 | end 44 | 45 | 46 | # Euclidian distance 47 | def distance(val1,x1,y1) 48 | x2=val1/4 49 | y2=val1.modulo(4) 50 | dist = Math.sqrt((x1 - x2)**2 + (y1 - y2)**2) 51 | return dist 52 | end 53 | 54 | 55 | def heuristicCostEstimate(current,goal) 56 | cost = 0 57 | (0..3).each do |i| 58 | (0..3).each do |j| 59 | cost += distance(goal[i][j],i,j) 60 | end 61 | end 62 | return cost 63 | end 64 | 65 | def valido?(x,y) 66 | return x >= 0 && y >= 0 && x<=3 && y<=3 67 | end 68 | 69 | def swapPosBoard(boardOld,x,y,newX,newY) 70 | board = Marshal.load( Marshal.dump(boardOld) ) 71 | aux = board[newX][newY] 72 | board[newX][newY] = board[x][y] 73 | board[x][y] = aux 74 | return board 75 | end 76 | 77 | def neighborNodes(board) 78 | neighbors = [] 79 | pos1,pos2 = getBlankPosition(board) 80 | if (valido?(pos1+1,pos2)) 81 | neighbors.push(swapPosBoard(board,pos1,pos2,pos1+1,pos2)) 82 | end 83 | if (valido?(pos1-1,pos2)) 84 | neighbors.push(swapPosBoard(board,pos1,pos2,pos1-1,pos2)) 85 | end 86 | if (valido?(pos1,pos2+1)) 87 | neighbors.push(swapPosBoard(board,pos1,pos2,pos1,pos2+1)) 88 | end 89 | if (valido?(pos1,pos2-1)) 90 | neighbors.push(swapPosBoard(board,pos1,pos2,pos1,pos2-1)) 91 | end 92 | return neighbors 93 | end 94 | 95 | board1=[[1,6,2,3],[5,10,7,4],[9,14,11,8],[13,0,15,12]] 96 | ##board1=[[2,0,3,4],[1,6,7,8],[5,9,10,11],[13,14,15,12]] 97 | 98 | #board1=[[2,6,8,3],[1,14,9,11],[7,12,13,0],[5,15,4,10]] 99 | goal=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,0]] 100 | 101 | res = Astar(board1,goal,method(:distanceBetween), 102 | method(:heuristicCostEstimate), 103 | method(:neighborNodes)) 104 | 105 | res.reverse.each do |item| 106 | printBoard item 107 | end 108 | -------------------------------------------------------------------------------- /libs/c++/a_node.h: -------------------------------------------------------------------------------- 1 | // A* NODES 2 | // Developed by: 3 | // - Marcos Yukio Siraichi 4 | // - Lucas Georges Helal 5 | // This code is under MIT license 6 | 7 | #ifndef A_NODE_H 8 | #define A_NODE_H 9 | #define a_node_gen a_node 10 | #define compare_gen compare_node 11 | #define a_vector_gen a_vector 12 | 13 | template 14 | class a_node { 15 | public: 16 | node_t n; 17 | fgh_t h, g, f; 18 | node_key parent; 19 | }; 20 | 21 | template 22 | class a_vector : public std::vector { 23 | public: 24 | a_vector(); 25 | void push_node(a_node_gen*); 26 | void pop_node(); 27 | }; 28 | 29 | template 30 | class compare_node { 31 | public: 32 | bool operator() (a_node_gen *&a1, a_node_gen *&a2); 33 | }; 34 | 35 | template 36 | void a_vector_gen::push_node(a_node_gen *n) { 37 | this->push_back(n); 38 | std::push_heap(this->begin(), this->end(), compare_gen()); 39 | }; 40 | 41 | template 42 | void a_vector_gen::pop_node() { 43 | std::pop_heap(this->begin(), this->end(), compare_gen()); 44 | this->pop_back(); 45 | }; 46 | 47 | template 48 | a_vector_gen::a_vector() { 49 | std::make_heap(this->begin(), this->end(), compare_gen()); 50 | }; 51 | 52 | template 53 | bool compare_gen::operator()(a_node_gen *&a1, a_node_gen *&a2) { 54 | return ( a1->f > a2->f ); 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /libs/c++/a_star.h: -------------------------------------------------------------------------------- 1 | // A Star Algorithm 2 | // Developed by: 3 | // - Marcos Yukio Siraichi 4 | // - Lucas Georges Helal 5 | 6 | #ifndef A_STAR 7 | #define A_STAR 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "a_node.h" 15 | #define a_star_gen a_star 16 | 17 | template 18 | class a_star { 19 | private: 20 | a_vector_gen open_set; 21 | std::unordered_map open_ref; 22 | std::unordered_map closed_set; 23 | node_t start, end; 24 | 25 | void init_set(); 26 | std::list *back_trace(a_node_gen); 27 | a_node_gen *create_node(node_t); 28 | 29 | public: 30 | fgh_t (*calc_h)(node_t); 31 | fgh_t (*calc_dist)(node_t, node_t); 32 | node_key (*generate_key)(node_t); 33 | bool (*node_equal)(node_t, node_t); 34 | std::vector *(*create_nodes)(node_t); 35 | 36 | a_star(fgh_t (*)(node_t), fgh_t (*)(node_t, node_t), node_key (*)(node_t), bool (*)(node_t, node_t), std::vector* (*)(node_t)); 37 | std::list *do_a_star(node_t, node_t); 38 | }; 39 | 40 | template 41 | a_star_gen::a_star(fgh_t (*h)(node_t), fgh_t (*g)(node_t, node_t), 42 | node_key (*gen)(node_t), bool (*eq)(node_t, node_t), 43 | std::vector *(*new_n)(node_t)) { 44 | this->calc_h = h; 45 | this->calc_dist = g; 46 | generate_key = gen; 47 | node_equal = eq; 48 | create_nodes = new_n; 49 | 50 | init_set(); 51 | } 52 | 53 | template 54 | void a_star_gen::init_set() { 55 | open_ref.clear(); 56 | open_set.clear(); 57 | closed_set.clear(); 58 | }; 59 | 60 | template 61 | a_node_gen *a_star_gen::create_node(node_t content) { 62 | a_node_gen *new_node = new a_node_gen(); 63 | new_node->n = content; 64 | return new_node; 65 | }; 66 | 67 | template 68 | std::list *a_star_gen::back_trace(a_node_gen n) { 69 | a_node_gen last; 70 | std::list *path = new std::list(); 71 | last.parent = (*generate_key)(n.n); 72 | do { 73 | last = closed_set[last.parent]; 74 | path->push_front(last.n); 75 | } while(last.n != start); 76 | return path; 77 | }; 78 | 79 | template 80 | std::list *a_star_gen::do_a_star(node_t start, node_t end) { 81 | this->start = start; 82 | this->end = end; 83 | a_node_gen *s = create_node(start), *former_node, *aux; 84 | a_node_gen closest_node; 85 | fgh_t g_try_score; 86 | std::vector *new_nodes; 87 | node_key i_key; 88 | typename std::unordered_map::iterator it; 89 | 90 | open_ref[(*generate_key)(s->n)] = *s; 91 | open_set.push_node(&(open_ref[(*generate_key)(s->n)])); 92 | while(!open_set.empty()) { 93 | closest_node = *(open_set.front()); 94 | open_set.pop_node(); 95 | open_ref.erase((*generate_key)(closest_node.n)); 96 | closed_set[(*generate_key)(closest_node.n)] = closest_node; 97 | if((*node_equal)(closest_node.n, end)) return back_trace(closest_node); 98 | 99 | new_nodes = (*create_nodes)(closest_node.n); 100 | for(typename std::vector::iterator i=new_nodes->begin(); i!=new_nodes->end(); i++) { 101 | aux = create_node(*i); 102 | g_try_score = closest_node.g + (*calc_dist)(aux->n, closest_node.n); 103 | i_key = (*generate_key)(aux->n); 104 | if(closed_set.find(i_key) != closed_set.end()) continue; 105 | if((it = open_ref.find(i_key)) != open_ref.end()) { 106 | former_node = &(it->second); 107 | if(former_node->g <= g_try_score) continue; 108 | aux = former_node; 109 | } 110 | aux->g = g_try_score; 111 | aux->h = (*calc_h)(aux->n); 112 | aux->f = aux->g + aux->h; 113 | aux->parent = (*generate_key)(closest_node.n); 114 | if(aux->n == (*i)) { 115 | open_ref[i_key] = *aux; 116 | free(aux); 117 | } 118 | open_set.push_node(&(open_ref[i_key])); 119 | } 120 | new_nodes->clear(); 121 | free(new_nodes); 122 | } 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /libs/python/AStar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Created by Joao A. Jesus Jr. 3 | # Joao M. Velasques Faria 4 | 5 | from collections import deque 6 | 7 | class AStar: 8 | def distBetween(self,current,neighbor): 9 | pass 10 | 11 | def heuristicEstimate(self,start,goal): 12 | pass 13 | 14 | def neighborNodes(self,current): 15 | pass 16 | 17 | def reconstructPath(self,cameFrom,goal): 18 | path = deque() 19 | node = goal 20 | path.appendleft(node) 21 | while node in cameFrom: 22 | node = cameFrom[node] 23 | path.appendleft(node) 24 | return path 25 | 26 | def getLowest(self,openSet,fScore): 27 | lowest = float("inf") 28 | lowestNode = None 29 | for node in openSet: 30 | if fScore[node] < lowest: 31 | lowest = fScore[node] 32 | lowestNode = node 33 | return lowestNode 34 | 35 | def aStar(self,start,goal): 36 | cameFrom = {} 37 | openSet = set([start]) 38 | closedSet = set() 39 | gScore = {} 40 | fScore = {} 41 | gScore[start] = 0 42 | fScore[start] = gScore[start] + self.heuristicEstimate(start,goal) 43 | while len(openSet) != 0: 44 | current = self.getLowest(openSet,fScore) 45 | if current == goal: 46 | return self.reconstructPath(cameFrom,goal) 47 | openSet.remove(current) 48 | closedSet.add(current) 49 | for neighbor in self.neighborNodes(current): 50 | tentative_gScore = gScore[current] + self.distBetween(current,neighbor) 51 | if neighbor in closedSet and tentative_gScore >= gScore[neighbor]: 52 | continue 53 | if neighbor not in closedSet or tentative_gScore < gScore[neighbor]: 54 | cameFrom[neighbor] = current 55 | gScore[neighbor] = tentative_gScore 56 | fScore[neighbor] = gScore[neighbor] + self.heuristicEstimate(neighbor,goal) 57 | if neighbor not in openSet: 58 | openSet.add(neighbor) 59 | return 0 60 | -------------------------------------------------------------------------------- /libs/ruby/AlgorithmA.rb: -------------------------------------------------------------------------------- 1 | # Algorithm A* 2 | # Devlopers: Vanderson M. Rosario 3 | # Diogo T. Murata 4 | # This code is under MIT licence. 5 | # 6 | # board[4][4] being 1 a position ocupated and 0 for blank. 7 | # 0 - blank 8 | # 1 - Ocupated 9 | 10 | def getLower(openSet,f_score) 11 | lowest = openSet.first 12 | lowestValue = f_score[lowest] 13 | openSet.each do |item| 14 | if(f_score[item] < lowestValue) 15 | lowest = item 16 | lowestValue = f_score[item] 17 | end 18 | end 19 | return lowest 20 | end 21 | 22 | def reconstruct_path(came_from, current_node,path) 23 | next_node = current_node 24 | while(came_from.include?(next_node)) 25 | path.push(next_node) 26 | next_node = came_from[next_node] 27 | end 28 | end 29 | 30 | def Astar(start,goal,distance_between, 31 | heuristic_cost_estimate,neighbor_nodes) 32 | 33 | closedSet=[] 34 | openSet=[start] 35 | came_from={} 36 | g_score = {} 37 | f_score = {} 38 | 39 | g_score[start]=0 40 | f_score[start]=g_score[start] 41 | + heuristic_cost_estimate.call(start,goal) 42 | 43 | while (not openSet.empty?) 44 | 45 | current=getLower(openSet,f_score) 46 | if(current == goal) 47 | path = [] 48 | reconstruct_path(came_from, goal,path) 49 | return path 50 | end 51 | 52 | openSet.delete current 53 | closedSet.push current 54 | 55 | neighborhood=neighbor_nodes.call(current) 56 | 57 | neighborhood.each do |neighbor| 58 | 59 | tentative_g_score = g_score[current] + distance_between.call(neighbor,current) 60 | 61 | if (closedSet.include?(neighbor)) 62 | if(tentative_g_score >= g_score[neighbor]) 63 | next 64 | end 65 | end 66 | 67 | if (!closedSet.include?(neighbor) || tentative_g_score < g_score[neighbor]) 68 | came_from[neighbor] = current 69 | g_score[neighbor] = tentative_g_score 70 | f_score[neighbor] = g_score[neighbor] + heuristic_cost_estimate.call(neighbor,goal) 71 | 72 | if (!openSet.include?(neighbor)) 73 | openSet.push(neighbor) 74 | end 75 | end 76 | end 77 | end 78 | return false; 79 | end 80 | 81 | --------------------------------------------------------------------------------