Skip to content

Commit 4583def

Browse files
authored
Add files via upload
1 parent 33dee07 commit 4583def

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package com.thealgorithms.backtracking;
2+
// Problem Statement: Find the shortest path from a start node to a goal node using heuristics.
3+
4+
// Example:
5+
// Start (S) -> Goal (G)
6+
// S(0,0) ----- (2,0) ----- G(4,0)
7+
8+
// Heuristic: Manhattan distance.
9+
// Start Node: S(0,0)
10+
// Goal Node: G(4,0)
11+
12+
// A* uses both the actual cost and estimated distance to guide the search.
13+
// Shortest path: S -> (2,0) -> G, with a total cost of 4.
14+
15+
16+
import java.util.*;
17+
18+
// Node class to represent each node in the graph
19+
class Node implements Comparable<Node> {
20+
public int vertex;
21+
public int gCost; // Actual cost to reach this node
22+
public int hCost; // Heuristic cost to goal
23+
public Node parent;
24+
25+
public Node(int vertex, int gCost, int hCost, Node parent) {
26+
this.vertex = vertex;
27+
this.gCost = gCost;
28+
this.hCost = hCost;
29+
this.parent = parent;
30+
}
31+
32+
// f(n) = g(n) + h(n)
33+
public int getFCost() {
34+
return gCost + hCost;
35+
}
36+
37+
@Override
38+
public int compareTo(Node other) {
39+
return Integer.compare(this.getFCost(), other.getFCost());
40+
}
41+
}
42+
43+
// Graph class to represent a weighted graph using adjacency list
44+
class Graph {
45+
private final int V;
46+
private final List<List<Node>> adjacencyList;
47+
48+
public Graph(int V) {
49+
this.V = V;
50+
adjacencyList = new ArrayList<>();
51+
for (int i = 0; i < V; i++) {
52+
adjacencyList.add(new ArrayList<>());
53+
}
54+
}
55+
56+
public void addEdge(int u, int v, int weight) {
57+
adjacencyList.get(u).add(new Node(v, weight, 0, null));
58+
}
59+
60+
public List<List<Node>> getAdjacencyList() {
61+
return adjacencyList;
62+
}
63+
64+
public int getNumberOfVertices() {
65+
return V;
66+
}
67+
}
68+
69+
// Heuristic interface for Strategy Pattern
70+
interface Heuristic {
71+
int calculate(int current, int goal);
72+
}
73+
74+
// Example Heuristic: Manhattan Distance (for grid graphs)
75+
class ManhattanHeuristic implements Heuristic {
76+
private final int[] xCoords;
77+
private final int[] yCoords;
78+
79+
public ManhattanHeuristic(int[] xCoords, int[] yCoords) {
80+
this.xCoords = xCoords;
81+
this.yCoords = yCoords;
82+
}
83+
84+
@Override
85+
public int calculate(int current, int goal) {
86+
return Math.abs(xCoords[current] - xCoords[goal]) + Math.abs(yCoords[current] - yCoords[goal]);
87+
}
88+
}
89+
90+
// Example Heuristic: Euclidean Distance
91+
class EuclideanHeuristic implements Heuristic {
92+
private final int[] xCoords;
93+
private final int[] yCoords;
94+
95+
public EuclideanHeuristic(int[] xCoords, int[] yCoords) {
96+
this.xCoords = xCoords;
97+
this.yCoords = yCoords;
98+
}
99+
100+
@Override
101+
public int calculate(int current, int goal) {
102+
return (int) Math.sqrt(Math.pow(xCoords[current] - xCoords[goal], 2) +
103+
Math.pow(yCoords[current] - yCoords[goal], 2));
104+
}
105+
}
106+
107+
// AStar class for A* algorithm implementation
108+
class AStar {
109+
private final Graph graph;
110+
private final Heuristic heuristic;
111+
112+
public AStar(Graph graph, Heuristic heuristic) {
113+
this.graph = graph;
114+
this.heuristic = heuristic;
115+
}
116+
117+
public List<Integer> findShortestPath(int start, int goal) {
118+
int V = graph.getNumberOfVertices();
119+
PriorityQueue<Node> openSet = new PriorityQueue<>();
120+
Set<Integer> closedSet = new HashSet<>();
121+
122+
Node startNode = new Node(start, 0, heuristic.calculate(start, goal), null);
123+
openSet.add(startNode);
124+
125+
while (!openSet.isEmpty()) {
126+
Node currentNode = openSet.poll();
127+
128+
if (currentNode.vertex == goal) {
129+
return reconstructPath(currentNode);
130+
}
131+
132+
closedSet.add(currentNode.vertex);
133+
134+
for (Node neighbor : graph.getAdjacencyList().get(currentNode.vertex)) {
135+
if (closedSet.contains(neighbor.vertex)) {
136+
continue; // Skip already processed nodes
137+
}
138+
139+
int tentativeGCost = currentNode.gCost + neighbor.gCost;
140+
Node newNeighborNode = new Node(neighbor.vertex, tentativeGCost, heuristic.calculate(neighbor.vertex, goal), currentNode);
141+
142+
openSet.add(newNeighborNode);
143+
}
144+
}
145+
146+
return Collections.emptyList(); // Return an empty list if no path found
147+
}
148+
149+
private List<Integer> reconstructPath(Node goalNode) {
150+
List<Integer> path = new ArrayList<>();
151+
Node currentNode = goalNode;
152+
while (currentNode != null) {
153+
path.add(currentNode.vertex);
154+
currentNode = currentNode.parent;
155+
}
156+
Collections.reverse(path); // Reverse the path to get the correct order
157+
return path;
158+
}
159+
}

0 commit comments

Comments
 (0)