00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef GROUPREFINEMENT_H_
00034 #define GROUPREFINEMENT_H_
00035
00036 #include <permlib/predicate/pointwise_stabilizer_predicate.h>
00037 #include <permlib/search/partition/refinement.h>
00038
00039 namespace permlib {
00040 namespace partition {
00041
00043 template<class PERM,class TRANS>
00044 class GroupRefinement : public Refinement<PERM> {
00045 public:
00047 explicit GroupRefinement(const BSGSCore<PERM,TRANS>& bsgs);
00048
00049 virtual uint apply(Partition& pi) const;
00050 virtual uint apply2(Partition& pi, const PERM& t) const;
00051
00052 virtual bool init(Partition& pi);
00053
00055 const BSGSCore<PERM,TRANS>& bsgs() const;
00056 private:
00057 const BSGSCore<PERM,TRANS>& m_bsgs;
00058
00059 std::vector<ulong> thetaOrbit;
00060 std::vector<int> thetaBorder;
00061
00062 uint apply2(Partition& pi, const PERM* t) const;
00063 };
00064
00065 template<class PERM,class TRANS>
00066 GroupRefinement<PERM,TRANS>::GroupRefinement(const BSGSCore<PERM,TRANS>& bsgs)
00067 : Refinement<PERM>(bsgs.n, Group), m_bsgs(bsgs), thetaOrbit(m_bsgs.n), thetaBorder(m_bsgs.n, -1)
00068 {
00069 }
00070
00071 template<class PERM,class TRANS>
00072 uint GroupRefinement<PERM,TRANS>::apply(Partition& pi) const {
00073 return apply2(pi, 0);
00074 }
00075
00076 template<class PERM,class TRANS>
00077 uint GroupRefinement<PERM,TRANS>::apply2(Partition& pi, const PERM& t) const {
00078 return apply2(pi, &t);
00079 }
00080
00081 template<class PERM,class TRANS>
00082 uint GroupRefinement<PERM,TRANS>::apply2(Partition& pi, const PERM* t) const {
00083 BOOST_ASSERT( this->initialized() );
00084
00085 std::vector<ulong> myTheta(thetaOrbit);
00086
00087 std::vector<ulong>::iterator thetaIt;
00088 std::vector<ulong>::iterator thetaBeginIt, thetaEndIt;
00089 std::list<int>::const_iterator cellPairIt = Refinement<PERM>::m_cellPairs.begin();
00090 uint ret = false;
00091 while (cellPairIt != Refinement<PERM>::m_cellPairs.end()) {
00092 const int thetaC = *cellPairIt;
00093 ++cellPairIt;
00094 if (*cellPairIt < 0) {
00095 ++cellPairIt;
00096 continue;
00097 }
00098
00099 int borderLo = 0;
00100 if (thetaC > 0)
00101 borderLo = thetaBorder[thetaC-1];
00102 thetaBeginIt = myTheta.begin() + borderLo;
00103 thetaEndIt = myTheta.begin() + thetaBorder[thetaC];
00104
00105 if (t) {
00106 for (thetaIt = thetaBeginIt; thetaIt != thetaEndIt; ++thetaIt) {
00107 *thetaIt = *t / *thetaIt;
00108 }
00109 std::sort(thetaBeginIt, thetaEndIt);
00110 }
00111
00112 for (int c = *cellPairIt; c >= 0; c = *(++cellPairIt)) {
00113 if (t) {
00114 DEBUG(std::cout << "apply theta " << thetaC << "," << c << " t = " << *t << " to " << pi << std::endl;)
00115 } else {
00116 DEBUG(std::cout << "apply theta " << thetaC << "," << c << " t = 0 to " << pi << std::endl;)
00117 }
00118
00119 if (pi.intersect(thetaBeginIt, thetaEndIt, c))
00120 ++ret;
00121 }
00122 ++cellPairIt;
00123 }
00124
00125 return ret;
00126 }
00127
00128 template<class PERM,class TRANS>
00129 bool GroupRefinement<PERM,TRANS>::init(Partition& pi) {
00130 uint fixSize = pi.fixPointsSize();
00131 if (fixSize > 0) {
00132 boost::dynamic_bitset<> orbitCharacterstic(m_bsgs.n);
00133
00134 std::vector<ulong>::const_iterator Bit;
00135 std::vector<ulong>::const_iterator fixIt = pi.fixPointsBegin();
00136 std::vector<ulong>::const_iterator fixEndIt = pi.fixPointsEnd();
00137 for (Bit = m_bsgs.B.begin(); Bit != m_bsgs.B.end(); ++Bit) {
00138 while (fixIt != fixEndIt && *fixIt != *Bit) {
00139 DEBUG(std::cout << "skip " << (*fixIt + 1) << " for " << (*Bit + 1) << std::endl;)
00140 ++fixIt;
00141 }
00142 if (fixIt == fixEndIt)
00143 break;
00144 ++fixIt;
00145 }
00146
00147 #ifdef DEBUG_OUTPUT
00148 print_iterable(m_bsgs.B.begin(), m_bsgs.B.end(), 1, " BSGS ");
00149 print_iterable(m_bsgs.B.begin(), Bit, 1, "to fix");
00150 print_iterable(pi.fixPointsBegin(), pi.fixPointsEnd(), 1, " fix");
00151 #endif
00152 PointwiseStabilizerPredicate<PERM> fixStab(m_bsgs.B.begin(), Bit);
00153 std::list<PERM> S_fix;
00154 BOOST_FOREACH(const PERMptr& p, m_bsgs.S) {
00155 if (fixStab(p)) {
00156
00157 S_fix.push_back(*p);
00158 }
00159 }
00160
00161 uint thetaIndex = 0;
00162 std::vector<int>::iterator thetaBorderIt = thetaBorder.begin();
00163 std::vector<ulong>::iterator thetaIt = thetaOrbit.begin();
00164 for (ulong alpha = 0; alpha < m_bsgs.n; ++alpha) {
00165 if (orbitCharacterstic[alpha])
00166 continue;
00167 orbitCharacterstic.flip(alpha);
00168 std::vector<ulong>::iterator thetaOrbitBeginIt = thetaIt;
00169 *thetaIt = alpha;
00170 ++thetaIt;
00171 ++thetaIndex;
00172 std::vector<ulong>::iterator thetaOrbitEndIt = thetaIt;
00173
00174 std::vector<ulong>::iterator it;
00175 for (it = thetaOrbitBeginIt; it != thetaOrbitEndIt; ++it) {
00176 ulong beta = *it;
00177 BOOST_FOREACH(const PERM &p, S_fix) {
00178 ulong beta_p = p / beta;
00179 if (!orbitCharacterstic[beta_p]) {
00180 *thetaIt = beta_p;
00181 ++thetaIt;
00182 ++thetaOrbitEndIt;
00183 ++thetaIndex;
00184 orbitCharacterstic.flip(beta_p);
00185 }
00186 }
00187 }
00188 *thetaBorderIt = thetaIndex;
00189 ++thetaBorderIt;
00190 }
00191
00192 thetaIt = thetaOrbit.begin();
00193 std::vector<ulong>::iterator thetaItEnd;
00194 thetaBorderIt = thetaBorder.begin();
00195 uint thetaC = 0;
00196 int oldBorder = 0;
00197 while (thetaBorderIt != thetaBorder.end() && *thetaBorderIt >= 0) {
00198 thetaItEnd = thetaOrbit.begin() + *thetaBorderIt;
00199 std::sort(thetaIt, thetaItEnd);
00200
00201 if (*thetaBorderIt - oldBorder != 1 || std::find(pi.fixPointsBegin(), pi.fixPointsEnd(), *thetaIt) == pi.fixPointsEnd()) {
00202 bool hasTheta = false;
00203 const uint oldCellNumber = pi.cells();
00204 for (uint c = 0; c < oldCellNumber; ++c) {
00205 if (pi.cellSize(c) == 1)
00206 continue;
00207
00208
00209
00210 if (pi.intersect(thetaIt, thetaItEnd, c)) {
00211 DEBUG(std::cout << "prepare theta " << thetaC << "," << c << std::endl;)
00212
00213 if (!hasTheta) {
00214 Refinement<PERM>::m_cellPairs.push_back(thetaC);
00215 hasTheta = true;
00216 }
00217 Refinement<PERM>::m_cellPairs.push_back(c);
00218
00219 }
00220
00221 }
00222
00223 if (hasTheta)
00224 Refinement<PERM>::m_cellPairs.push_back(-1);
00225 }
00226
00227 oldBorder = *thetaBorderIt;
00228 thetaIt = thetaItEnd;
00229 ++thetaC;
00230 ++thetaBorderIt;
00231 }
00232
00233 if (!Refinement<PERM>::m_cellPairs.empty()) {
00234 typename Refinement<PERM>::RefinementPtr ref(new GroupRefinement<PERM,TRANS>(*this));
00235 Refinement<PERM>::m_backtrackRefinements.push_back(ref);
00236 return true;
00237 }
00238 }
00239
00240 return false;
00241 }
00242
00243 template<class PERM,class TRANS>
00244 const BSGSCore<PERM,TRANS>& GroupRefinement<PERM,TRANS>::bsgs() const {
00245 return m_bsgs;
00246 }
00247
00248 }
00249 }
00250
00251 #endif // -- GROUPREFINEMENT_H_