This is an extension of the previous gist - while that gist explored a particular question, this one tries to compare some algorithms which have very similar implementations, but different requirements and performance characteristics. It generates a random but somewhat believable geography on a plane and then tries to get from Q to W (noting that there may be more than one connection between two cities, with different costs). Each run is different.
An example result:
====================================================================================
Algorithm A*:
Expanded Q; Agenda = [(E, 308), (P, 190), (D, 289), (A, 497)]
Expanded E; Agenda = [(P, 190), (W, 412), (D, 289), (I, 512), (A, 497)]
Expanded P; Agenda = [(W, 412), (D, 289), (L, 338), (M, 385), (I, 512), (G, 420), (A, 497), (V, 528)]
Expanded W; Goal reached
Path: Q -> E -> W, Cost: 412
====================================================================================
Uniform Cost Search:
Expanded Q; Agenda = [(P, 190), (D, 289), (E, 308), (A, 497)]
Expanded P; Agenda = [(D, 289), (E, 308), (L, 338), (M, 385), (G, 420), (A, 497), (V, 528)]
Expanded D; Agenda = [(E, 308), (L, 338), (M, 385), (G, 420), (W, 444), (B, 486), (A, 497), (V, 528)]
Expanded E; Agenda = [(L, 338), (M, 385), (W, 412), (G, 420), (B, 486), (A, 497), (I, 512), (V, 528)]
Expanded L; Agenda = [(M, 385), (W, 412), (G, 420), (S, 485), (B, 486), (A, 497), (I, 512), (V, 528), (T, 533)]
Expanded M; Agenda = [(W, 412), (G, 420), (U, 460), (S, 485), (B, 486), (A, 497), (I, 512), (H, 523), (V, 528), (T, 533), (C, 598), (J, 713)]
Expanded W; Goal reached
Path: Q -> E -> W, Cost: 412
====================================================================================
Iterative Deepening Search:
Expanded Q; Agenda = [(P, 190), (D, 289), (E, 308), (A, 497)]
Expanded P; Agenda = [(D, 289), (E, 308), (A, 497), (M, 385), (V, 528), (G, 420), (L, 338)]
Expanded D; Agenda = [(E, 308), (A, 497), (M, 385), (V, 528), (G, 420), (L, 338), (W, 444), (B, 486)]
Expanded E; Agenda = [(A, 497), (M, 385), (V, 528), (G, 420), (L, 338), (W, 444), (B, 486), (I, 512)]
Expanded A; Agenda = [(M, 385), (V, 528), (G, 420), (L, 338), (W, 444), (B, 486), (I, 512), (O, 589)]
Expanded M; Agenda = [(V, 528), (G, 420), (L, 338), (W, 444), (B, 486), (I, 512), (O, 589), (U, 460), (S, 623), (H, 523), (J, 713), (C, 598)]
Expanded V; Agenda = [(G, 420), (L, 338), (W, 444), (B, 486), (I, 512), (O, 589), (U, 460), (S, 623), (H, 523), (J, 713), (C, 598), (Y, 917)]
Expanded G; Agenda = [(L, 338), (W, 444), (B, 486), (I, 512), (O, 589), (U, 460), (S, 623), (H, 523), (J, 713), (C, 598), (Y, 917)]
Expanded L; Agenda = [(W, 444), (B, 486), (I, 512), (O, 589), (U, 460), (S, 623), (H, 523), (J, 713), (C, 598), (Y, 917), (T, 533)]
Expanded W; Goal reached
Path: Q -> D -> W, Cost: 444
====================================================================================
Both UCS and A* picked the same route and report the same final cost. This makes sense, because they are both optimal - they find the cheapest solution to any given problem. IDS, however, has taken a different path with a higher cost. That is because it is only complete for this problem - it would be optimal if every path had the same cost. The difference between UCS and A* is that A* has to expand fewer nodes to find the destination.
Notably, each of these algorithms has the same worst case performance characteristics as Breadth-First Search. You kinda have to work pretty hard for this to happen, such as giving A* a heuristic which always returns 0 - essentially turning it into UCS - and then engineering your state space such that the resulting tree forces the agenda to behave like an ordinary queue. I think in practice this is pretty hard, and A* is a fairly popular algorithm for path finding, as well as other, perhaps slightly less intuitive problems.