Boost C++ Libraries: Ticket #8433: Algorithm for finding all the elementary circuits in a directed (multi)graph https://svn.boost.org/trac10/ticket/8433 <p> I have implemented the algorithm described in (1) for finding all the elementary circuits of a directed (multi)graph. I implemented it in a generic fashion, planning to propose it for inclusion in Boost. </p> <p> Boost.Graph currently contains the <code>tiernan_all_cycles</code> algorithm for finding all the cycles in a graph. However, it is undocumented and it has a time bound (for which no precise analysis is provided) that makes it unsuitable even for moderately sized graphs. In fact, I implemented <code>hawick_circuits</code> because <code>tiernan_all_cycles</code> did not cut it for my application. </p> <p> My implementation is available at (2). It is licensed under the Boost license and was tested using the test suite at (3). More information on the test suite can be found at (4). </p> <p> Comments on improvements would be appreciated. </p> <p> (1) <a class="ext-link" href="http://www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf"><span class="icon">​</span>http://www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf</a> </p> <p> (2) <a class="ext-link" href="https://github.com/ldionne/hawick_circuits"><span class="icon">​</span>https://github.com/ldionne/hawick_circuits</a> </p> <p> (3) <a class="ext-link" href="https://github.com/josch/cycle_test"><span class="icon">​</span>https://github.com/josch/cycle_test</a> </p> <p> (4) <a class="ext-link" href="http://blog.mister-muffin.de/2012/07/04/enumerating-elementary-circuits-of-a-directed_graph/"><span class="icon">​</span>http://blog.mister-muffin.de/2012/07/04/enumerating-elementary-circuits-of-a-directed_graph/</a> </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8433 Trac 1.4.3 Jeremiah Willcock Mon, 22 Apr 2013 20:14:43 GMT <link>https://svn.boost.org/trac10/ticket/8433#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:1</guid> <description> <p> Here are a few comments on the code: </p> <ul><li>It looks good and is almost ready to put in. </li><li>There is no documentation file that I can see. </li><li>Please use <code>boost::graph_detail::find</code> from <code>&lt;boost/pending/container_traits.hpp&gt;</code> instead of <code>std::find</code>; that code will automatically use a member find to get better performance on types such as <code>set</code> and <code>unordered_set</code>. If you know that you are searching a non-associative container, you can also use <code>boost::container_contains</code> from <code>&lt;boost/detail/algorithm.hpp&gt;</code>. </li><li>What concept is <code>ClosedMatrix</code> expected to model? </li><li>There is no need to use perfect forwarding on the graph type; passing <code>const</code> references is fine. You can also assume vertex descriptors and property maps are inexpensive to copy, but forwarding those is acceptable if you want to do it. </li><li>You refer to citation <code>[1]</code> in the code, but do not provide the full information about the source there. </li><li>Boost.Graph has a Dot parser (and output routines) if you want to use them in your test harness. </li></ul> </description> <category>Ticket</category> </item> <item> <dc:creator>Louis Dionne</dc:creator> <pubDate>Fri, 16 Aug 2013 02:30:54 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8433#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8433#comment:1" title="Comment 1">jewillco</a>: </p> <p> Sorry, I did not notice your reply and now quite a bit of time has passed. Anyway, the algorithm is still a very relevant addition to Boost.Graph. </p> <blockquote class="citation"> <p> Here are a few comments on the code: </p> <ul><li>It looks good and is almost ready to put in. </li><li>There is no documentation file that I can see. </li></ul></blockquote> <p> The documentation that I should write is almost the same as that of <code>tiernan_all_cycles</code>. Is there a way to say "the behavior for <code>hawick_circuits</code> is the same as <code>tiernan_all_cycles</code>, except it detects self-loops and loops involving parallel edges in multigraphs"? </p> <p> Also, what would be the preferred way of providing documentation? I am not familiar with <a class="missing wiki">QuickBook</a>; if it's possible to stick with something else then I'd be happy. </p> <blockquote class="citation"> <ul><li>Please use <code>boost::graph_detail::find</code> from <code>&lt;boost/pending/container_traits.hpp&gt;</code> instead of <code>std::find</code>; that code will automatically use a member find to get better performance on types such as <code>set</code> and <code>unordered_set</code>. If you know that you are searching a non-associative container, you can also use <code>boost::container_contains</code> from <code>&lt;boost/detail/algorithm.hpp&gt;</code>. </li></ul></blockquote> <p> I'm now using <code>boost::container_contains</code>. I do find it awful that <code>&lt;boost/detail/algorithm.hpp&gt;</code> includes so many unneeded headers, though. </p> <blockquote class="citation"> <ul><li>What concept is <code>ClosedMatrix</code> expected to model? </li></ul></blockquote> <p> IIRC, <code>ClosedMatrix</code> is just a two dimensional array of vertices. It is an implementation detail and it is not expected to model any specific concept. </p> <blockquote class="citation"> <ul><li>There is no need to use perfect forwarding on the graph type; passing <code>const</code> references is fine. You can also assume vertex descriptors and property maps are inexpensive to copy, but forwarding those is acceptable if you want to do it. </li></ul></blockquote> <p> I like to use perfect forwarding whenever it makes sense to do it, i.e. whenever I don't use an argument but I only forward it to another function. While it may be useless in some cases, it is never harmful and I feel it captures my intent better. </p> <blockquote class="citation"> <ul><li>You refer to citation <code>[1]</code> in the code, but do not provide the full information about the source there. </li></ul></blockquote> <p> Thanks, fixed. </p> <blockquote class="citation"> <ul><li>Boost.Graph has a Dot parser (and output routines) if you want to use them in your test harness. </li></ul></blockquote> <p> Thanks, but the test harness is made to work with the test suite at <a class="ext-link" href="https://github.com/josch/cycle_test"><span class="icon">​</span>https://github.com/josch/cycle_test</a>. The input format is not exactly Dot. </p> <p> I updated the repository at <a class="ext-link" href="https://github.com/ldionne/hawick_circuits"><span class="icon">​</span>https://github.com/ldionne/hawick_circuits</a>. I guess we have to settle on the documentation and then we'll be good to go. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Jeremiah Willcock</dc:creator> <pubDate>Fri, 16 Aug 2013 14:42:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8433#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:3</guid> <description> <p> Here are responses to your questions: </p> <ol><li>Yes, you can have the documentation refer to another algorithm's documentation, but your page should at least have the function signatures and any differences. Most BGL documentation is in fairly straightforward, hand-written HTML; just copy one of the existing pages and modify it for your algorithm. </li></ol><ol start="2"><li>It looks like <code>container_contains</code> does not do any optimizations, so you should probably use <code>boost::graph_detail::find</code> anyway. </li></ol><ol start="3"><li>That's fine; I see that <code>ClosedMatrix</code> isn't part of a public interface so it can be whatever you want. </li></ol><ol start="4"><li>OK, perfect forwarding is fine as long as your code works in C++03. </li></ol><ol start="5"><li>I'm not seeing exactly where the test graphs (or generators for them) are in the repository you give. How different are they from Graphviz format? </li></ol> </description> <category>Ticket</category> </item> <item> <author>Louis Dionne <ldionne.2@…></author> <pubDate>Fri, 16 Aug 2013 20:34:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8433#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8433#comment:3" title="Comment 3">jewillco</a>: </p> <blockquote class="citation"> <p> Here are responses to your questions: </p> <ol><li>Yes, you can have the documentation refer to another algorithm's documentation, but your page should at least have the function signatures and any differences. Most BGL documentation is in fairly straightforward, hand-written HTML; just copy one of the existing pages and modify it for your algorithm. </li></ol></blockquote> <p> I wrote documentation in Markdown and generated HTML from it. It looks exactly as the rest of the documentation. </p> <blockquote class="citation"> <ol start="2"><li>It looks like <code>container_contains</code> does not do any optimizations, so you should probably use <code>boost::graph_detail::find</code> anyway. </li></ol></blockquote> <p> Since I'm only searching in a vector, there won't be any optimization. I'll stick with <code>container_contains</code>, since that expresses my intent better. </p> <blockquote class="citation"> <ol start="4"><li>OK, perfect forwarding is fine as long as your code works in C++03. </li></ol></blockquote> <p> The code works in C++03 and C++11. It was compiled with Clang 3.3 and G++ 4.9. </p> <blockquote class="citation"> <ol start="5"><li>I'm not seeing exactly where the test graphs (or generators for them) are in the repository you give. How different are they from Graphviz format? </li></ol></blockquote> <p> I'm not providing any tests with the algorithm, that's why. The algorithm is tested using an external test suite, and it would be fairly complicated to migrate those tests to Boost. Basically, you should ignore the <code>hawick_circuits.cpp</code> file at the root of the repository, which is only useful for the external test suite. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Jeremiah Willcock</dc:creator> <pubDate>Fri, 16 Aug 2013 20:41:46 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8433#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:5</guid> <description> <p> Instead of <code>container_contains</code>, it would probably be better to use <code>std::find</code> directly (which I believe you did before). Are you going to have any kind of testing in the Boost version? It would be nice to at least have testing with a small graph or two that makes sure that the code compiles and can run simple problems. Can you use random graphs like the <code>tiernan_all_cycles.cpp</code> test does? </p> </description> <category>Ticket</category> </item> <item> <author>Louis Dionne <ldionne.2@…></author> <pubDate>Fri, 16 Aug 2013 21:22:51 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8433#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/8433#comment:5" title="Comment 5">jewillco</a>: </p> <blockquote class="citation"> <p> Instead of <code>container_contains</code>, it would probably be better to use <code>std::find</code> directly (which I believe you did before). </p> </blockquote> <p> Fixed. </p> <blockquote class="citation"> <p> Are you going to have any kind of testing in the Boost version? It would be nice to at least have testing with a small graph or two that makes sure that the code compiles and can run simple problems. Can you use random graphs like the <code>tiernan_all_cycles.cpp</code> test does? </p> </blockquote> <p> I adapted <code>tiernan_all_cycles.cpp</code> into a reusable header for cycle algorithms, and used it to generate a small unit test for <code>hawick_circuits</code>. It might also be interesting to use that header from <code>tiernan_all_cycles.cpp</code> to reduce code duplication. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Jeremiah Willcock</dc:creator> <pubDate>Sat, 31 Aug 2013 19:29:23 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/8433#comment:7 https://svn.boost.org/trac10/ticket/8433#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/85533" title="Added Hawick circuits code from Louis Dionne; fixes #8433">[85533]</a>) Added Hawick circuits code from Louis Dionne; fixes <a class="reopened ticket" href="https://svn.boost.org/trac10/ticket/8433" title="#8433: Feature Requests: Algorithm for finding all the elementary circuits in a directed ... (reopened)">#8433</a> </p> Ticket Jeremiah Willcock Sat, 31 Aug 2013 19:32:27 GMT <link>https://svn.boost.org/trac10/ticket/8433#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8433#comment:8</guid> <description> <p> I've added your code to the Boost trunk, but I still need a couple of changes (please attach patches to the bug report for those): </p> <ul><li>The documentation files do not include copyright or license information; could you please send a patch with that added? </li><li>Where should your algorithm be in the table of contents of the documentation? I put it in the "Miscellaneous Algorithms" part for now. </li></ul><p> Also, here are some changes I made; please tell me if you disagree: </p> <ul><li>I put the <code>hawick_circuits.cpp</code> file from the root directory of your Github repository into <code>libs/graph/example</code> and added it as a file to build there. </li><li>I removed two lines (<code>typedef</code>s) from <code>cycle_test.hpp</code> to fix GCC warnings about unused <code>typedef</code>s. </li></ul> </description> <category>Ticket</category> </item> <item> <dc:creator>Smithe854</dc:creator> <pubDate>Wed, 22 Apr 2015 06:49:53 GMT</pubDate> <title>status, type, component, version, milestone changed; resolution deleted https://svn.boost.org/trac10/ticket/8433#comment:9 https://svn.boost.org/trac10/ticket/8433#comment:9 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>type</strong> <span class="trac-field-old">Feature Requests</span> → <span class="trac-field-new">Library Submissions</span> </li> <li><strong>component</strong> <span class="trac-field-old">graph</span> → <span class="trac-field-new">xpressive</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost 1.54.0</span> → <span class="trac-field-new">Boost.Build-M3</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Website 1.X</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> I'm truly enjoying the design and layout of your blog. It's a very easy on the eyes which makes it much more pleasant for me to come here and visit more often. Did you hire out a developer to create your theme? Outstanding work! effckkaddggaecee </p> Ticket ldionne.2@… Fri, 13 Nov 2015 17:09:15 GMT type, version, component, milestone changed https://svn.boost.org/trac10/ticket/8433#comment:10 https://svn.boost.org/trac10/ticket/8433#comment:10 <ul> <li><strong>type</strong> <span class="trac-field-old">Library Submissions</span> → <span class="trac-field-new">Feature Requests</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost.Build-M3</span> → <span class="trac-field-new">Boost 1.53.0</span> </li> <li><strong>component</strong> <span class="trac-field-old">xpressive</span> → <span class="trac-field-new">graph</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">Website 1.X</span> → <span class="trac-field-new">To Be Determined</span> </li> </ul> <p> Damn bot. We should be good to close this once <a class="ext-link" href="https://github.com/boostorg/graph/pull/50"><span class="icon">​</span>https://github.com/boostorg/graph/pull/50</a> is merged. </p> Ticket