The original approach to name cleaning was O(n) for consolidating subkeys.  (e.g. delete a word or two from a long key and see it matches a shorter key)

This new approach is O(n^2) and compares all keys to all other keys to see if one is a subset of the other.  It takes a lot longer to run, but is still tractable, and yields a better result.
Updated tests per improved performance.
 My original definition of "optimal" was whether the test path was equal to the path returned by Dijkstra's algorithm.  Now instead the costs of the shortest path and the test path are compared and if they are equal, the test path is predicted as optimal (one of perhaps many optimal paths).

This results in much better performance, position 47 on the leaderboard.
First draft of final project paper.