1212 */
1313public class AStarSearch {
1414
15- @ FunctionalInterface
16- public interface Heuristic {
17- double estimate (int node , int goal );
18- }
19-
2015 static class Node implements Comparable <Node > {
2116 int id ;
2217 double g ; // Cost from start
@@ -36,48 +31,25 @@ static class Node implements Comparable<Node> {
3631 public int compareTo (Node o ) {
3732 return Double .compare (this .f , o .f );
3833 }
39-
40- @ Override
41- public boolean equals (Object o ) {
42- if (this == o ) return true ;
43- if (!(o instanceof Node )) return false ;
44- Node node = (Node ) o ;
45- return id == node .id ;
46- }
47-
48- @ Override
49- public int hashCode () {
50- return Objects .hash (id );
51- }
5234 }
5335
5436 private final Map <Integer , List <int []>> graph ;
55- private final Heuristic heuristic ;
5637
57- /**
58- * Constructor with default heuristic (|goal - node|).
59- */
6038 public AStarSearch () {
61- this .graph = new HashMap <>();
62- this .heuristic = (node , goal ) -> Math .abs (goal - node );
39+ graph = new HashMap <>();
6340 }
6441
65- /**
66- * Constructor with custom heuristic.
67- */
68- public AStarSearch (Heuristic heuristic ) {
69- this .graph = new HashMap <>();
70- this .heuristic = heuristic ;
71- }
72-
73- /**
74- * Adds an undirected edge between nodes u and v with the given weight.
75- */
42+ /** Adds an undirected edge between nodes u and v with the given weight. */
7643 public void addEdge (int u , int v , int weight ) {
7744 graph .computeIfAbsent (u , k -> new ArrayList <>()).add (new int []{v , weight });
7845 graph .computeIfAbsent (v , k -> new ArrayList <>()).add (new int []{u , weight });
7946 }
8047
48+ /** Heuristic function (simplified for numeric nodes). */
49+ private double heuristic (int node , int goal ) {
50+ return Math .abs (goal - node );
51+ }
52+
8153 /**
8254 * Finds the shortest path from start to goal using A* algorithm.
8355 *
@@ -90,35 +62,38 @@ public List<Integer> findPath(int start, int goal) {
9062 Map <Integer , Double > gScore = new HashMap <>();
9163 Set <Integer > closedSet = new HashSet <>();
9264
93- openSet .add (new Node (start , 0 , heuristic . estimate (start , goal ), null ));
65+ openSet .add (new Node (start , 0 , heuristic (start , goal ), null ));
9466 gScore .put (start , 0.0 );
9567
9668 while (!openSet .isEmpty ()) {
9769 Node current = openSet .poll ();
9870
99- if (current .id == goal ) return reconstructPath (current );
71+ if (current .id == goal ) {
72+ return reconstructPath (current );
73+ }
10074
10175 closedSet .add (current .id );
10276
10377 for (int [] edge : graph .getOrDefault (current .id , new ArrayList <>())) {
10478 int neighbor = edge [0 ];
10579 double tentativeG = current .g + edge [1 ];
10680
107- if (closedSet .contains (neighbor )) continue ;
81+ if (closedSet .contains (neighbor )) {
82+ continue ;
83+ }
10884
10985 if (tentativeG < gScore .getOrDefault (neighbor , Double .MAX_VALUE )) {
11086 gScore .put (neighbor , tentativeG );
111- Node next = new Node (neighbor , tentativeG , heuristic . estimate (neighbor , goal ), current );
87+ Node next = new Node (neighbor , tentativeG , heuristic (neighbor , goal ), current );
11288 openSet .add (next );
11389 }
11490 }
11591 }
92+
11693 return Collections .emptyList ();
11794 }
11895
119- /**
120- * Reconstructs path by following parent nodes.
121- */
96+ /** Reconstructs path by following parent nodes. */
12297 private List <Integer > reconstructPath (Node node ) {
12398 List <Integer > path = new ArrayList <>();
12499 while (node != null ) {
0 commit comments