Boost C++ Libraries: Ticket #11735: A* Out of Range Error on 2D grid if width or height is 1 https://svn.boost.org/trac10/ticket/11735 <p> astar_search fails an out of range assertion for grid_graphs (or filtered_graphs thereof) if they have a size of 1 along one dimension. </p> <p> I understand that in this case the dimension is redundant, but still... </p> <p> Only tested with 2D grids in both 1.58 and 1.59. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11735 Trac 1.4.3 willi+boost@… Sat, 17 Oct 2015 20:39:08 GMT attachment set https://svn.boost.org/trac10/ticket/11735 https://svn.boost.org/trac10/ticket/11735 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">main.cpp</span> </li> </ul> <p> test case triggering the bug </p> Ticket willi+boost@… Sat, 17 Oct 2015 20:40:35 GMT <link>https://svn.boost.org/trac10/ticket/11735#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11735#comment:1</guid> <description> <p> Similar test case also on <a class="ext-link" href="http://melpon.org/wandbox/permlink/sBTZXMRmPWxVezKy"><span class="icon">​</span>http://melpon.org/wandbox/permlink/sBTZXMRmPWxVezKy</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 21 Feb 2018 16:33:26 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11735#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11735#comment:2</guid> <description> <p> A much simpler way to trigger the bug is the following: </p> <pre class="wiki">#include &lt;boost/graph/grid_graph.hpp&gt; #include &lt;boost/graph/graph_traits.hpp&gt; int main () { using graph_type = boost::grid_graph&lt;2&gt;; using graph_traits = boost::graph_traits&lt;graph_type&gt;; using vertex_descriptor = typename graph_traits::vertex_descriptor; graph_type graph {vertex_descriptor{2,1}}; assert(num_vertices(graph) == 2); assert(num_edges(graph) == 2); assert(out_degree(vertex_descriptor{0,0},graph) == 1); assert(in_degree(vertex_descriptor{0,0},graph) == 1); } </pre><p> grid_graph calculates the number of vertices and edges correctly, but gets the {in|out}_degree (and hence {in|out}_edge_iterators) wrong. There is no reason this should be a restriction, as the fix is trivial: </p> <pre class="wiki">--- grid_graph.hpp.orig 2017-01-07 11:43:21.000000000 -0700 +++ grid_graph.hpp 2018-02-21 08:48:37.000000000 -0700 @@ -633,7 +633,7 @@ // wraps or not. if ((vertex[dimension_index] == 0) || (vertex[dimension_index] == (length(dimension_index) - 1))) { - out_edge_count += (wrapped(dimension_index) ? 2 : 1); + out_edge_count += length(dimension_index) == 1 ? 0 : (wrapped(dimension_index) ? 2 : 1); } else { // Next and previous edges, regardless or wrapping </pre><p> Yes, there may be some runtime cases with wrapping where lengths of 1 make no sense, but that is a misuse of the library by the user. The library should not enforce artificial restrictions that limits legitimate use cases like run-time specified 2x1 grids. </p> </description> <category>Ticket</category> </item> <item> <author>brook@…</author> <pubDate>Thu, 22 Feb 2018 14:31:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11735#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11735#comment:3</guid> <description> <p> An even better patch might be the following. Note that I did not reindent the original code to emphasize the substantive change. </p> <pre class="wiki">--- boost/graph/grid_graph.hpp.orig 2017-01-07 11:43:21.000000000 -0700 +++ boost/graph/grid_graph.hpp 2018-02-22 07:20:18.000000000 -0700 @@ -630,7 +630,8 @@ // If the vertex is on the edge of this dimension, then its // number of out edges is dependent upon whether the dimension - // wraps or not. + // wraps or not, but only if the length is &gt; 1. + if (length(dimension_index) &gt; 1) { if ((vertex[dimension_index] == 0) || (vertex[dimension_index] == (length(dimension_index) - 1))) { out_edge_count += (wrapped(dimension_index) ? 2 : 1); @@ -639,6 +640,7 @@ // Next and previous edges, regardless or wrapping out_edge_count += 2; } + } } return (out_edge_count); </pre> </description> <category>Ticket</category> </item> </channel> </rss>