Skip to content

Commit e400522

Browse files
authored
Update AStarSearch.java
1 parent 8aec567 commit e400522

File tree

1 file changed

+74
-91
lines changed

1 file changed

+74
-91
lines changed
Lines changed: 74 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.thealgorithms.graph;
22

33
import java.util.ArrayList;
4+
import java.util.Collections;
45
import java.util.HashMap;
6+
import java.util.HashSet;
57
import java.util.List;
68
import java.util.Map;
79
import java.util.PriorityQueue;
810
import java.util.Set;
9-
import java.util.HashSet;
10-
import java.util.Collections;
11+
import java.util.Scanner;
1112

1213
/**
1314
* Implementation of the A* Search Algorithm for shortest pathfinding.
@@ -23,70 +24,17 @@
2324
*
2425
* <p>
2526
* Time Complexity: O(E + V log V) with a binary heap priority queue.<br>
26-
* Space Complexity: O(V + E).
27-
* </p>
28-
*
29-
* <p>
30-
* Usage is intended programmatically via the {@link Graph} and {@link #findPath}
31-
* method; interactive input should be handled externally or via tests.
27+
* Space Complexity: O(V + E)
3228
* </p>
3329
*/
3430
public class AStarSearch {
3531

36-
/**
37-
* Represents a weighted directed graph using adjacency lists.
38-
*/
39-
public static class Graph {
40-
private final Map<Integer, List<int[]>> adjacencyList;
41-
42-
/**
43-
* Constructs an empty graph.
44-
*/
45-
public Graph() {
46-
adjacencyList = new HashMap<>();
47-
}
48-
49-
/**
50-
* Adds an undirected edge between nodes {@code u} and {@code v} with a weight.
51-
*
52-
* @param u first node
53-
* @param v second node
54-
* @param weight weight of the edge
55-
*/
56-
public void addEdge(int u, int v, int weight) {
57-
adjacencyList.computeIfAbsent(u, k -> new ArrayList<>()).add(new int[] { v, weight });
58-
adjacencyList.computeIfAbsent(v, k -> new ArrayList<>()).add(new int[] { u, weight });
59-
}
60-
61-
/**
62-
* Returns the adjacency list for a node.
63-
*
64-
* @param node node index
65-
* @return list of int[] {neighbor, weight}
66-
*/
67-
public List<int[]> getEdges(int node) {
68-
return adjacencyList.getOrDefault(node, Collections.emptyList());
69-
}
70-
71-
/**
72-
* Returns all nodes in the graph.
73-
*
74-
* @return set of node indices
75-
*/
76-
public Set<Integer> getNodes() {
77-
return adjacencyList.keySet();
78-
}
79-
}
80-
81-
/**
82-
* Node used in the priority queue for A*.
83-
*/
8432
private static class Node implements Comparable<Node> {
85-
final int id;
86-
final double g; // cost from start
87-
final double h; // heuristic
88-
final double f; // total = g + h
89-
final Node parent;
33+
int id;
34+
double g; // cost from start
35+
double h; // heuristic to goal
36+
double f; // total cost = g + h
37+
Node parent;
9038

9139
Node(int id, double g, double h, Node parent) {
9240
this.id = id;
@@ -97,28 +45,47 @@ private static class Node implements Comparable<Node> {
9745
}
9846

9947
@Override
100-
public int compareTo(Node o) {
101-
return Double.compare(this.f, o.f);
48+
public int compareTo(Node other) {
49+
return Double.compare(this.f, other.f);
10250
}
10351
}
10452

105-
private final Graph graph;
53+
private final Map<Integer, List<int[]>> graph;
54+
55+
/** Constructs an empty graph. */
56+
public AStarSearch() {
57+
graph = new HashMap<>();
58+
}
59+
60+
/**
61+
* Adds an undirected edge between nodes u and v with the given weight.
62+
*
63+
* @param u first node
64+
* @param v second node
65+
* @param weight edge weight
66+
*/
67+
public void addEdge(int u, int v, int weight) {
68+
graph.computeIfAbsent(u, k -> new ArrayList<>()).add(new int[]{v, weight});
69+
graph.computeIfAbsent(v, k -> new ArrayList<>()).add(new int[]{u, weight});
70+
}
10671

10772
/**
108-
* Constructs an A* solver for a given graph.
73+
* Heuristic function for A* (simplified as absolute difference).
10974
*
110-
* @param graph weighted graph
75+
* @param node current node
76+
* @param goal goal node
77+
* @return heuristic estimate
11178
*/
112-
public AStarSearch(Graph graph) {
113-
this.graph = graph;
79+
private double heuristic(int node, int goal) {
80+
return Math.abs(goal - node);
11481
}
11582

11683
/**
117-
* Finds the shortest path from {@code start} to {@code goal} using A* search.
84+
* Finds the shortest path from start to goal using A* algorithm.
11885
*
119-
* @param start starting node
120-
* @param goal goal node
121-
* @return list of nodes representing the shortest path, empty if none
86+
* @param start start node
87+
* @param goal goal node
88+
* @return list of nodes representing the shortest path
12289
*/
12390
public List<Integer> findPath(int start, int goal) {
12491
PriorityQueue<Node> openSet = new PriorityQueue<>();
@@ -130,45 +97,32 @@ public List<Integer> findPath(int start, int goal) {
13097

13198
while (!openSet.isEmpty()) {
13299
Node current = openSet.poll();
133-
134100
if (current.id == goal) {
135101
return reconstructPath(current);
136102
}
137103

138104
closedSet.add(current.id);
139-
140-
for (int[] edge : graph.getEdges(current.id)) {
105+
for (int[] edge : graph.getOrDefault(current.id, new ArrayList<>())) {
141106
int neighbor = edge[0];
142107
double tentativeG = current.g + edge[1];
143-
144-
if (closedSet.contains(neighbor)) continue;
108+
if (closedSet.contains(neighbor)) {
109+
continue;
110+
}
145111

146112
if (tentativeG < gScore.getOrDefault(neighbor, Double.MAX_VALUE)) {
147113
gScore.put(neighbor, tentativeG);
148114
openSet.add(new Node(neighbor, tentativeG, heuristic(neighbor, goal), current));
149115
}
150116
}
151117
}
152-
153118
return Collections.emptyList();
154119
}
155120

156121
/**
157-
* Simple heuristic: absolute difference between node indices.
158-
*
159-
* @param node current node
160-
* @param goal goal node
161-
* @return heuristic value
162-
*/
163-
private double heuristic(int node, int goal) {
164-
return Math.abs(goal - node);
165-
}
166-
167-
/**
168-
* Reconstructs the path from goal to start following parent links.
122+
* Reconstructs the path by following parent nodes.
169123
*
170124
* @param node end node
171-
* @return list of node indices from start to goal
125+
* @return path from start to end
172126
*/
173127
private List<Integer> reconstructPath(Node node) {
174128
List<Integer> path = new ArrayList<>();
@@ -179,4 +133,33 @@ private List<Integer> reconstructPath(Node node) {
179133
Collections.reverse(path);
180134
return path;
181135
}
136+
137+
/** Reads input dynamically and runs A* algorithm. */
138+
public static void main(String[] args) {
139+
Scanner sc = new Scanner(System.in);
140+
AStarSearch aStar = new AStarSearch();
141+
142+
System.out.print("Enter number of edges: ");
143+
int edges = sc.nextInt();
144+
System.out.println("Enter edges in format: u v weight");
145+
for (int i = 0; i < edges; i++) {
146+
int u = sc.nextInt();
147+
int v = sc.nextInt();
148+
int w = sc.nextInt();
149+
aStar.addEdge(u, v, w);
150+
}
151+
152+
System.out.print("Enter start node: ");
153+
int start = sc.nextInt();
154+
System.out.print("Enter goal node: ");
155+
int goal = sc.nextInt();
156+
157+
List<Integer> path = aStar.findPath(start, goal);
158+
if (path.isEmpty()) {
159+
System.out.println("No path found from " + start + " → " + goal);
160+
} else {
161+
System.out.println("Shortest path from " + start + " → " + goal + ": " + path);
162+
}
163+
sc.close();
164+
}
182165
}

0 commit comments

Comments
 (0)