Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added A* algorithm #1451

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions data_structures/graphs/a-star.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

// Structure for storing a graph
struct Graph
{
int vertexNum;
int **edges;
};

// Structure to represent a node in A*
struct Node
{
int f, g, h;
int parent;
bool is_in_closed_set;
};

// Creates a graph with V vertices
void createGraph(struct Graph *G, int V)
{
G->vertexNum = V;
G->edges = (int **)malloc(V * sizeof(int *));
for (int i = 0; i < V; i++)
{
G->edges[i] = (int *)malloc(V * sizeof(int));
for (int j = 0; j < V; j++) G->edges[i][j] = INT_MAX;
G->edges[i][i] = 0;
}
}

// Adds an edge to the graph with a specified weight
void addEdge(struct Graph *G, int src, int dst, int weight)
{
G->edges[src][dst] = weight;
}

// Heuristic function (Manhattan distance for simplicity)
int heuristic(int start, int goal) { return abs(start - goal); }

// Utility function to find the node with the lowest f in the open set
int minFNode(int openSet[], struct Node nodes[], int openSetSize)
{
int minF = INT_MAX;
int minNode = -1;
for (int i = 0; i < openSetSize; i++)
{
int node = openSet[i];
if (nodes[node].f < minF)
{
minF = nodes[node].f;
minNode = node;
}
}
return minNode;
}

// Function to reconstruct and print the path from start to goal
void printPath(struct Node nodes[], int goal)
{
if (nodes[goal].parent != -1)
{
printPath(nodes, nodes[goal].parent);
}
printf("%d ", goal);
}

// A* Algorithm function
void aStar(struct Graph *graph, int start, int goal)
{
int V = graph->vertexNum;
struct Node nodes[V];
int openSet[V];
int openSetSize = 0;

// Initialize nodes and add start to open set
for (int i = 0; i < V; i++)
{
nodes[i].f = nodes[i].g = nodes[i].h = INT_MAX;
nodes[i].parent = -1;
nodes[i].is_in_closed_set = false;
}
nodes[start].g = 0;
nodes[start].h = heuristic(start, goal);
nodes[start].f = nodes[start].g + nodes[start].h;
openSet[openSetSize++] = start;

// Main A* loop
while (openSetSize > 0)
{
int current = minFNode(openSet, nodes, openSetSize);

// If goal is reached, reconstruct path
if (current == goal)
{
printf("Path from %d to %d: ", start, goal);
printPath(nodes, goal);
printf("\n");
return;
}

// Remove current from open set
int index = 0;
while (index < openSetSize && openSet[index] != current) index++;
for (int i = index; i < openSetSize - 1; i++)
openSet[i] = openSet[i + 1];
openSetSize--;

nodes[current].is_in_closed_set = true;

// Check neighbors
for (int neighbor = 0; neighbor < V; neighbor++)
{
if (graph->edges[current][neighbor] != INT_MAX &&
!nodes[neighbor].is_in_closed_set)
{
int tentative_g =
nodes[current].g + graph->edges[current][neighbor];

if (tentative_g < nodes[neighbor].g)
{
nodes[neighbor].parent = current;
nodes[neighbor].g = tentative_g;
nodes[neighbor].h = heuristic(neighbor, goal);
nodes[neighbor].f = nodes[neighbor].g + nodes[neighbor].h;

// Add neighbor to open set if not already present
bool inOpenSet = false;
for (int i = 0; i < openSetSize; i++)
{
if (openSet[i] == neighbor)
{
inOpenSet = true;
break;
}
}
if (!inOpenSet)
openSet[openSetSize++] = neighbor;
}
}
}
}

printf("No path found from %d to %d\n", start, goal);
}

// Driver function
int main()
{
int V, E;
int src, dst, weight;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d", &V);
printf("Enter number of edges: ");
scanf("%d", &E);
createGraph(&G, V);

for (int i = 0; i < E; i++)
{
printf("\nEdge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
printf("Enter weight: ");
scanf("%d", &weight);
addEdge(&G, src, dst, weight);
}

int start, goal;
printf("\nEnter start node: ");
scanf("%d", &start);
printf("Enter goal node: ");
scanf("%d", &goal);

aStar(&G, start, goal);

return 0;
}
Loading