astar function

List<int>? astar(
  1. WeightedAdjacency graph,
  2. int start,
  3. int goal,
  4. double heuristic(
    1. int node
    ),
)

A* from start to goal. heuristic must be admissible (never overestimate). Returns path from start to goal (empty if not found), or null if no path.

Implementation

List<int>? astar(
  WeightedAdjacency graph,
  int start,
  int goal,
  double Function(int node) heuristic,
) {
  if (start == goal) return <int>[start];
  final List<double> g = List.filled(graph.length, double.infinity);
  g[start] = 0;
  final List<int?> parent = List.filled(graph.length, null);
  final List<double> f = List.filled(graph.length, double.infinity);
  f[start] = heuristic(start);
  final List<int> open = <int>[start];
  while (open.isNotEmpty) {
    open.sort((int a, int b) => f[a].compareTo(f[b]));
    final int u = open.removeAt(0);
    if (u == goal) {
      final List<int> path = <int>[];
      for (int? p = goal; p != null; p = parent[p]) {
        path.add(p);
      }
      return path.reversed.toList();
    }
    for (final (int v, double w) in graph[u]) {
      final double gNew = g[u] + w;
      if (gNew < g[v]) {
        g[v] = gNew;
        parent[v] = u;
        f[v] = gNew + heuristic(v);
        if (!open.contains(v)) open.add(v);
      }
    }
  }
  return null;
}