[Graph] New user finding dijkstra's isn't returning shortest paths

In my first use of the boost library, I'm using the BGL's dijkstra_shortest_paths algorithm to try and (obviously) find the shortest path between two points. I am then iterating along the shortest path to a given node to find the total path weight along that path. I compare this value to the path weight along a manhattan path, and find that the manhattan path is shorter. Rather than claim this is a problem with boost (yet), I'm at first believing it's my interpretation of the library. If I've piqued your interest, feel encouraged to read on. My graph is a representation of a 2-dimensional mesh, so I've got an NxN graph, where the vast majority of nodes have out-edges in all four directions (N,S,E,W), and in-edges in all four directions. I generate the graph with the following: typedef adjacency_list < listS, vecS, undirectedS, no_property, property < edge_weight_t, double > > graph_t; graph_t gGraph(num_nodes); then iterating over each node (i) and adding edges as follows: add_edge(i, easterlydest, easterlyweight, gGraph); finally, I call: dijkstra_shortest_paths(gGraph,sourcenum,predecessor_map(&p [0]).distance_map(&d[0])); to evaluate the shortest paths. (Note that much of this is a cut-and- paste from the Dijkstra_shortest_path example found at http:// www.boost.org/libs/graph/example/dijkstra-example.cpp ) Note also that my understanding of the last argument to dijkstra_shortest_paths is probably my weakest part of understanding the library. I then iterate along a given shortest path by using the following loop structure: while(node != sourcenum) // iterate from dest to source, summing as you go { int u = p[node]; int v = node; graph_traits < graph_t >::edge_descriptor e = edge(u,v,graph).first; double this_weight = get(edge_weight,graph,e); path_length += this_weight; node = p[node]; } This returns a value of 1309.16 as the total path weight. I then attempt to determine the manhattan path weights as well, to compare how much of an improvement the shortest path is to the manhattan paths. I attempt to traverse the manhattan paths using a similar approach, with something similar to the following (irrelevant lines omitted): while(node != destnode) // iterate from source to dest, iterating as you go { int nextnode = get_nextnode(xfirst,node); // gets index of next node in an x-first y-next manhattan path int u = node; int v = nextnode; graph_traits < graph_t >::edge_descriptor e = edge(u,v,graph).first; double this_weight = get(edge_weight,graph,e); xfpath_length += this_weight; node = nextnode; } When this runs, I get a path length of 1299.79, a value more than 0.1% smaller. Either I'm determining the manhattan and shortest path weights incorrectly, or it's not actually finding the shortest path. So I did a bit of debugging (as programmers are wont to do). Tracing the paths themselves, I eventually find that at one point, the shortest path (hereafter abbreviated DSP) chooses to follow an out- edge that doesn't have minimum weight. This is perfectly reasonable, as it's possible (and probable) that this choice made now, will have greater returns later, allowing an overall shorter path. However, it never again returns to even equality with the manhattan path - the manhattan path is shorter along the entire length, to the end. I've checked my corner cases, and the paths are only being summed along relevant edges (no off-by-one errors that I can see, at least). If anyone has any ideas on how I might best debug/change my code, or a means by which I can perform some other test, I'd love to hear it. If anyone needs any more information, the code is by no means confidential (though a bit messy) and I've got both .dot (graphviz) format and an svg representation of the graph available. My development platform is currently Mac OS X 10.4.4 PPC using Xcode, if it matters to anyone. Thanks, and I hope you don't mind the rather lengthy post! - Greg Link ---- 20 70 80 95 106

On 2/14/06, Greg Link wrote:
In my first use of the boost library, I'm using the BGL's dijkstra_shortest_paths algorithm to try and (obviously) find the shortest path between two points. I am then iterating along the shortest path to a given node to find the total path weight along that path. I compare this value to the path weight along a manhattan path, and find that the manhattan path is shorter. Rather than claim this is a problem with boost (yet), I'm at first believing it's my interpretation of the library. If I've piqued your interest, feel encouraged to read on.
<snip>
I've checked my corner cases, and the paths are only being summed along relevant edges (no off-by-one errors that I can see, at least). If anyone has any ideas on how I might best debug/change my code, or a means by which I can perform some other test, I'd love to hear it. If anyone needs any more information, the code is by no means confidential (though a bit messy) and I've got both .dot (graphviz) format and an svg representation of the graph available. My development platform is currently Mac OS X 10.4.4 PPC using Xcode, if it matters to anyone.
Thanks, and I hope you don't mind the rather lengthy post! - Greg Link
Greg, Could you zip up your code and the .dot input file and post them, if the file isn't too big? Thanks, Aaron

Aaron (and the rest of the Boost-user's list) - I've attached a link to a .tar.gz of the source code I'm using, which currently requires both boost and the matpack library (for shepard interpolation), however, the only use of the matpack library is in the function "init_tsmap", where two "if(use_interpolation)" statements differentiate the code that needs matpack from a non- matpack codepath that simply instantiates the values in the tsmap to random values (originally put in to allow debugging the rest of the code separately from matpack). Hence, if you don't have matpack, you can just delete/ifdef out the matpack-based codepath. If you do have matpack, the executable " ./a.out 20 70 80 95 106" will read in the "input.dat" file, generate a tsmap object, then a graph, and attempt to find the shortest paths from the node at [20%, 70%] to [80%, 95%], with a graph of 106x106 nodes. Many other calls (such as the same points at a grid size of 105) return a shortest path that is, in fact, shorter than the manhattan paths, but if code fails in one weird case, you can be sure something is wrong somewhere, so can't really claim it works. If you don't have matpack, the code initializes a tsmap with random values, and thus a graph with random weights, so I don't have a case that will cause it to fail available. I have, however, provided a .dot (graphviz) format file "dump-00.dot" of the entire graph, with each edge labeled with the appropriate weight. As a final statement, please forgive the quality of the source provided. It's still very much a work-in-progress, and as the specifications change hourly, so do the data formats, function interfaces, et cetera. Always embarrassing to have something other than one's best work on public display. - Greg To reduce message size, I've provided download links for all files, rather than attaching them directly. Source: http://www.cse.psu.edu/~link/link_dijkstra.cpp.gz Text files listing the paths: http://www.cse.psu.edu/~link/ path_listings.tar.gz Graphviz-format output file (takes a lot of memory to render - over 11 thousand edges): http://www.cse.psu.edu/~link/dump-00.dot.gz SVG-format file demonstrating the problem in a much more useful visual format (viewable in any cutting-edge browser, such as Firefox, Nightly Safari WebKit builds, or using the Adobe SVG plugin) : http:// www.cse.psu.edu/~link/svg-00.svg.gz On Feb 15, 2006, at 6:47 AM, Aaron Windsor wrote: On 2/14/06, Greg Link wrote:
In my first use of the boost library, I'm using the BGL's dijkstra_shortest_paths algorithm to try and (obviously) find the shortest path between two points. I am then iterating along the shortest path to a given node to find the total path weight along that path. I compare this value to the path weight along a manhattan path, and find that the manhattan path is shorter. Rather than claim this is a problem with boost (yet), I'm at first believing it's my interpretation of the library. If I've piqued your interest, feel encouraged to read on.
<snip> Greg, Could you zip up your code and the .dot input file and post them, if the file isn't too big? Thanks, Aaron
participants (2)
-
Aaron Windsor
-
Greg Link