PermLib
|
00001 // --------------------------------------------------------------------------- 00002 // 00003 // This file is part of PermLib. 00004 // 00005 // Copyright (c) 2009-2011 Thomas Rehn <thomas@carmen76.de> 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions 00010 // are met: 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 3. The name of the author may not be used to endorse or promote products 00017 // derived from this software without specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00020 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00021 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00022 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00023 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00024 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00028 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 // 00030 // --------------------------------------------------------------------------- 00031 00032 #ifndef PERMLIB_API_H 00033 #define PERMLIB_API_H 00034 00035 #include <permlib/permutation.h> 00036 #include <permlib/bsgs.h> 00037 #include <permlib/transversal/schreier_tree_transversal.h> 00038 #include <permlib/transversal/orbit_set.h> 00039 #include <permlib/construct/schreier_sims_construction.h> 00040 #include <permlib/change/conjugating_base_change.h> 00041 #include <permlib/search/classic/set_stabilizer_search.h> 00042 #include <permlib/search/classic/set_image_search.h> 00043 #include <permlib/search/orbit_lex_min_search.h> 00044 00045 #include <boost/shared_ptr.hpp> 00046 #include <boost/iterator/counting_iterator.hpp> 00047 00048 namespace permlib { 00049 00050 // --------------------------------------------------------------------- 00051 // useful type definitions 00052 // 00053 00054 typedef Permutation PERMUTATION; 00055 typedef SchreierTreeTransversal<PERMUTATION> TRANSVERSAL; 00056 typedef BSGS<PERMUTATION,TRANSVERSAL> PermutationGroup; 00057 typedef OrbitSet<PERMUTATION,unsigned long> OrbitAsSet; 00058 00059 00060 // --------------------------------------------------------------------- 00061 // BSGS construction 00062 // 00063 00064 template<class InputIterator> 00065 boost::shared_ptr<PermutationGroup> construct(unsigned long n, InputIterator begin, InputIterator end) { 00066 SchreierSimsConstruction<PERMUTATION, TRANSVERSAL> schreierSims(n); 00067 boost::shared_ptr<PermutationGroup> group(new PermutationGroup(schreierSims.construct(begin, end))); 00068 return group; 00069 } 00070 00071 00072 // --------------------------------------------------------------------- 00073 // setwise stabilizer 00074 // 00075 00076 template<class InputIterator> 00077 boost::shared_ptr<PermutationGroup> setStabilizer(const PermutationGroup& group, InputIterator begin, InputIterator end) { 00078 PermutationGroup copy(group); 00079 // change the base so that is prefixed by the set 00080 ConjugatingBaseChange<PERMUTATION,TRANSVERSAL, 00081 RandomBaseTranspose<PERMUTATION,TRANSVERSAL> > baseChange(copy); 00082 baseChange.change(copy, begin, end); 00083 00084 // prepare search without DCM pruning 00085 classic::SetStabilizerSearch<BSGS<PERMUTATION,TRANSVERSAL>, TRANSVERSAL> backtrackSearch(copy, 0); 00086 backtrackSearch.construct(begin, end); 00087 00088 // start the search 00089 boost::shared_ptr<PermutationGroup> stabilizer(new PermutationGroup(copy.n)); 00090 backtrackSearch.search(*stabilizer); 00091 return stabilizer; 00092 } 00093 00094 00095 // --------------------------------------------------------------------- 00096 // set image 00097 // 00098 00099 template<class InputIterator> 00100 boost::shared_ptr<Permutation> setImage(const PermutationGroup& group, InputIterator begin, InputIterator end, InputIterator begin2, InputIterator end2) { 00101 PermutationGroup copy(group); 00102 // change the base so that is prefixed by the set 00103 ConjugatingBaseChange<PERMUTATION,TRANSVERSAL, 00104 RandomBaseTranspose<PERMUTATION,TRANSVERSAL> > baseChange(copy); 00105 baseChange.change(copy, begin, end); 00106 00107 // prepare search without DCM pruning 00108 classic::SetImageSearch<BSGS<PERMUTATION,TRANSVERSAL>, TRANSVERSAL> backtrackSearch(copy, 0); 00109 backtrackSearch.construct(begin, end, begin2, end2); 00110 00111 // start the search 00112 return backtrackSearch.searchCosetRepresentative(); 00113 } 00114 00115 00116 // --------------------------------------------------------------------- 00117 // orbits 00118 // 00119 00120 template<typename PDOMAIN,typename ACTION,typename InputIterator> 00121 std::list<boost::shared_ptr<OrbitSet<PERMUTATION,PDOMAIN> > > orbits(const PermutationGroup& group, InputIterator begin, InputIterator end) { 00122 typedef boost::shared_ptr<OrbitSet<PERMUTATION,PDOMAIN> > ORBIT; 00123 std::list<ORBIT> orbitList; 00124 00125 for (; begin != end; ++begin) { 00126 const PDOMAIN& alpha = *begin; 00127 bool knownElement = false; 00128 BOOST_FOREACH(const ORBIT& orb, orbitList) { 00129 if (orb->contains(alpha)) { 00130 knownElement = true; 00131 break; 00132 } 00133 } 00134 00135 if (knownElement) 00136 continue; 00137 00138 ORBIT orbit(new OrbitSet<PERMUTATION,PDOMAIN>()); 00139 orbit->orbit(alpha, group.S, ACTION()); 00140 orbitList.push_back(orbit); 00141 } 00142 00143 return orbitList; 00144 } 00145 00146 inline std::list<boost::shared_ptr<OrbitAsSet> > orbits(const PermutationGroup& group) { 00147 return orbits<unsigned long, Transversal<PERMUTATION>::TrivialAction>(group, boost::counting_iterator<unsigned long>(0), boost::counting_iterator<unsigned long>(group.n)); 00148 } 00149 00150 // --------------------------------------------------------------------- 00151 // smallest orbit element 00152 // 00153 00154 inline dset smallestSetImage(const PermutationGroup& group, const dset& set) { 00155 OrbitLexMinSearch<PermutationGroup> orbLexMin(group); 00156 return orbLexMin.lexMin(set); 00157 } 00158 00159 00160 } // namespace permlib 00161 00162 00163 #endif // PERMLIB_API_H 00164