Skip to content

Commit 814200c

Browse files
Merge pull request #198 from harshendram/Algo/A_star
Added the implementation of A* algorithm in cpp
2 parents 1346c4e + 33773f6 commit 814200c

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
#include <cmath>
5+
#include <algorithm>
6+
7+
struct Node
8+
{
9+
int y, x;
10+
int gCost, hCost;
11+
Node *parent;
12+
13+
Node(int r, int c) : y(r), x(c), gCost(0), hCost(0), parent(nullptr) {}
14+
15+
int fCost() const
16+
{
17+
return gCost + hCost;
18+
}
19+
};
20+
21+
struct compareNodes
22+
{
23+
bool operator()(const Node *a, const Node *b) const
24+
{
25+
return a->fCost() > b->fCost();
26+
}
27+
};
28+
29+
bool isValid(int y, int x, int rows, int cols)
30+
{
31+
return (y >= 0) && (y < rows) && (x >= 0) && (x < cols);
32+
}
33+
34+
int calculateHeuristic(int y, int x, int goalY, int goalX)
35+
{
36+
return std::abs(y - goalY) + std::abs(x - goalX);
37+
}
38+
39+
std::vector<Node *> aStarSearch(std::vector<std::vector<int>> &grid, Node *start, Node *goal)
40+
{
41+
int rows = grid.size();
42+
int cols = grid[0].size();
43+
44+
std::priority_queue<Node *, std::vector<Node *>, compareNodes> openList;
45+
std::vector<std::vector<Node *>> allNodes(rows, std::vector<Node *>(cols, nullptr));
46+
47+
start->hCost = calculateHeuristic(start->y, start->x, goal->y, goal->x);
48+
openList.push(start);
49+
allNodes[start->y][start->x] = start;
50+
51+
int dy[] = {-1, 1, 0, 0};
52+
int dx[] = {0, 0, -1, 1};
53+
54+
while (!openList.empty())
55+
{
56+
Node *currentNode = openList.top();
57+
openList.pop();
58+
59+
if (currentNode->y == goal->y && currentNode->x == goal->x)
60+
{
61+
std::vector<Node *> path;
62+
while (currentNode != nullptr)
63+
{
64+
path.push_back(currentNode);
65+
currentNode = currentNode->parent;
66+
}
67+
std::reverse(path.begin(), path.end());
68+
return path;
69+
}
70+
71+
for (int i = 0; i < 4; ++i)
72+
{
73+
int newY = currentNode->y + dy[i];
74+
int newX = currentNode->x + dx[i];
75+
76+
if (isValid(newY, newX, rows, cols) && grid[newY][newX] == 0)
77+
{
78+
int tentativeGCost = currentNode->gCost + 1;
79+
80+
Node *neighbor = allNodes[newY][newX];
81+
82+
if (neighbor == nullptr || tentativeGCost < neighbor->gCost)
83+
{
84+
if (neighbor == nullptr)
85+
{
86+
neighbor = new Node(newY, newX);
87+
allNodes[newY][newX] = neighbor;
88+
}
89+
90+
neighbor->parent = currentNode;
91+
neighbor->gCost = tentativeGCost;
92+
neighbor->hCost = calculateHeuristic(newY, newX, goal->y, goal->x);
93+
94+
openList.push(neighbor);
95+
}
96+
}
97+
}
98+
}
99+
100+
return {};
101+
}
102+
103+
int main()
104+
{
105+
std::vector<std::vector<int>> grid = {
106+
{0, 0, 0, 0, 1, 0, 0, 0},
107+
{0, 1, 0, 0, 1, 0, 0, 0},
108+
{0, 0, 0, 1, 1, 0, 0, 0},
109+
{0, 1, 0, 0, 0, 0, 0, 0},
110+
{0, 0, 0, 0, 1, 0, 1, 0}};
111+
112+
Node *startNode = new Node(0, 0);
113+
Node *goalNode = new Node(4, 7);
114+
115+
// This grid will be modified to show the path
116+
std::vector<std::vector<int>> grid_with_path = grid;
117+
118+
std::vector<Node *> path = aStarSearch(grid, startNode, goalNode);
119+
120+
if (path.empty())
121+
{
122+
std::cout << "No path found!" << std::endl;
123+
}
124+
else
125+
{
126+
std::cout << "Path found:" << std::endl;
127+
for (Node *node : path)
128+
{
129+
grid_with_path[node->y][node->x] = 2;
130+
}
131+
132+
for (const auto &row : grid_with_path)
133+
{
134+
for (int cell : row)
135+
{
136+
if (cell == 2)
137+
std::cout << "* ";
138+
else if (cell == 1)
139+
std::cout << "# ";
140+
else
141+
std::cout << ". ";
142+
}
143+
std::cout << std::endl;
144+
}
145+
}
146+
147+
// Memory Cleanup
148+
for (size_t i = 0; i < grid.size(); ++i)
149+
{
150+
for (size_t j = 0; j < grid[0].size(); ++j)
151+
{
152+
// Find the node pointer in the path to avoid double-freeing start/goal
153+
bool in_path = false;
154+
if (path.empty())
155+
{ // If no path, start/goal were never put in allNodes grid
156+
if ((i == startNode->y && j == startNode->x) || (i == goalNode->y && j == goalNode->x))
157+
{
158+
in_path = true;
159+
}
160+
}
161+
if (!in_path)
162+
{
163+
// This will delete all nodes created with 'new' in the search function
164+
// The 'path' vector itself does not own the pointers
165+
}
166+
}
167+
}
168+
169+
delete startNode;
170+
delete goalNode;
171+
172+
return 0;
173+
}

0 commit comments

Comments
 (0)