stlab.adobe.com Adobe Systems Incorporated

dancing_links.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /****************************************************************************************************/
00008 
00009 #ifndef ADOBE_DANCING_LINKS_HPP
00010 #define ADOBE_DANCING_LINKS_HPP
00011 
00012 /****************************************************************************************************/
00013 
00014 #include <adobe/config.hpp>
00015 
00016 #include <boost/function.hpp>
00017 #include <boost/noncopyable.hpp>
00018 #include <adobe/implementation/toroid.hpp>
00019 
00020 /****************************************************************************************************/
00021 
00022 namespace adobe {
00023 
00024 /****************************************************************************************************/
00025 
00026 #ifndef ADOBE_NO_DOCUMENTATION
00027 
00028 /****************************************************************************************************/
00029 
00030 namespace implementation {
00031 
00032 /****************************************************************************************************/
00033 
00034 struct do_nothing_callback_t
00035 {
00036     inline void operator () (std::size_t, bool) const
00037     { }
00038 };
00039 
00040 /****************************************************************************************************/
00041 
00042 struct select_right_heuristic_t
00043 {
00044     template <std::size_t Rows, std::size_t Cols, std::size_t NodeBlockSize>
00045     inline toroid_header_t* operator () (binary_toroid<Rows, Cols, NodeBlockSize>& toroid) const
00046         { return toroid.right_of(&toroid.header_m); }
00047 };
00048 
00049 /****************************************************************************************************/
00050 
00051 struct select_most_constrained_heuristic_t
00052 {
00053     template <std::size_t Rows, std::size_t Cols, std::size_t NodeBlockSize>
00054     inline toroid_header_t* operator () (binary_toroid<Rows, Cols, NodeBlockSize>& toroid) const
00055     {
00056         toroid_header_t* c(toroid.right_of(&toroid.header_m));
00057         std::size_t      sz(c->size_m);
00058 
00059         for (   toroid_header_t* p(toroid.right_of(c));
00060                 p != &toroid.header_m; p = toroid.right_of(p))
00061         {
00062             if (p->size_m < sz)
00063             {
00064                 c = p;
00065                 sz = p->size_m;
00066             }
00067 
00068             if (sz == 1) break;
00069         }
00070 
00071         return c;
00072     }
00073 };
00074 
00075 /****************************************************************************************************/
00076 
00077 } // namespace implementation
00078 
00079 /****************************************************************************************************/
00080 
00081 #endif
00082 
00083 /****************************************************************************************************/
00084 
00085 template <std::size_t Rows, std::size_t Cols>
00086 class dancing_links : boost::noncopyable
00087 {
00088 public:
00089 #ifndef ADOBE_NO_DOCUMENTATION
00090     dancing_links() :
00091         solutions_m(0)
00092     { }
00093 #endif
00094 
00095     inline void set(std::size_t row, std::size_t col)
00096         { toroid_m.set(row, col); }
00097 
00098     inline void set_secondary_column(std::size_t col)
00099         { toroid_m.set_secondary_column(col); }
00100 
00101     template <typename ResultCallback>
00102     inline std::size_t search(std::size_t max_solutions, ResultCallback callback)
00103     {
00104         max_solutions_m = max_solutions;
00105 
00106         toroid_m.finalize();
00107 
00108 #if 1
00109         do_search(0, callback, implementation::select_most_constrained_heuristic_t());
00110 #else
00111         do_search(0, callback, implementation::select_right_heuristic_t());     
00112 #endif
00113 
00114         return solutions_m;
00115     }
00116 
00117     inline std::size_t search(std::size_t max_solutions)
00118         { return search(max_solutions, implementation::do_nothing_callback_t()); }
00119 
00120 private:
00121     template <typename ResultCallback, typename SearchHeuristic>
00122     void do_search(std::size_t k, ResultCallback callback, SearchHeuristic heuristic)
00123     {
00124         if (toroid_m.right_of(&toroid_m.header_m) == &toroid_m.header_m)
00125         {
00126             ++solutions_m;
00127 
00128             for (std::size_t i(0); i < k; ++i)
00129                 callback(toroid_m.row_index_of(output_m[i]), i + 1 == k);
00130 
00131             return;
00132         }
00133 
00134         std::size_t next_k(k + 1);
00135 
00136         toroid_header_t* c(heuristic(toroid_m));
00137 
00138         toroid_m.cover_column(c);
00139 
00140         for (toroid_node_t* r(toroid_m.down_of(c));
00141             r != c; r = toroid_m.down_of(r))
00142         {
00143             output_m[k] = r;
00144 
00145             for (toroid_node_t* j1(toroid_m.right_of(r));
00146                 j1 != r; j1 = toroid_m.right_of(j1))
00147                 { toroid_m.cover_column(toroid_m.column_of(j1)); }
00148 
00149             do_search(next_k, callback, heuristic);
00150 
00151             if (solutions_m >= max_solutions_m) return;
00152 
00153             r = output_m[k];
00154 
00155             c = toroid_m.column_of(r);
00156 
00157             for (toroid_node_t* j(toroid_m.left_of(r));
00158                 j != r; j = toroid_m.left_of(j))
00159                 { toroid_m.uncover_column(toroid_m.column_of(j)); }
00160         }
00161 
00162         toroid_m.uncover_column(c);
00163     };
00164 
00165     binary_toroid<Rows, Cols> toroid_m;
00166     toroid_node_t*            output_m[Cols];
00167     std::size_t               solutions_m;
00168     std::size_t               max_solutions_m;
00169 };
00170 
00171 /****************************************************************************************************/
00172 
00173 } // namespace adobe
00174 
00175 /****************************************************************************************************/
00176 
00177 #endif
00178 
00179 /****************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google