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 MATRIXREFINEMENT2_H_
00034 #define MATRIXREFINEMENT2_H_
00035
00036 #include "predicate/pointwise_stabilizer_predicate.h"
00037 #include "search/partition/refinement.h"
00038
00039 #include <map>
00040
00041 namespace permlib {
00042 namespace partition {
00043
00045
00048 template<class PERM,class MATRIX>
00049 class MatrixRefinement2 : public Refinement<PERM> {
00050 public:
00052 explicit MatrixRefinement2(ulong n, const MATRIX& matrix);
00053
00054 virtual uint apply(Partition& pi) const;
00055
00056 virtual bool init(Partition& pi);
00057
00058 private:
00059 const MATRIX& m_matrix;
00060
00062 class Fingerprint {
00063 public:
00064 Fingerprint(ulong k) : m_fingerprint(k) {}
00065
00067 bool operator<(const Fingerprint& f) const {
00068 BOOST_ASSERT(f.m_fingerprint.size() == m_fingerprint.size());
00069 for (uint i=0; i<m_fingerprint.size(); ++i) {
00070 if (m_fingerprint[i] < f.m_fingerprint[i])
00071 return true;
00072 if (m_fingerprint[i] > f.m_fingerprint[i])
00073 return false;
00074 }
00075 return false;
00076 }
00077 bool operator==(const Fingerprint& f) const {
00078 BOOST_ASSERT(f.m_fingerprint.size() == m_fingerprint.size());
00079 for (uint i=0; i<m_fingerprint.size(); ++i) {
00080 if (m_fingerprint[i] != f.m_fingerprint[i])
00081 return false;
00082 }
00083 return true;
00084 }
00085 ulong& operator[](ulong i) {
00086 BOOST_ASSERT(i < m_fingerprint.size());
00087 return m_fingerprint[i];
00088 }
00089 const ulong& operator[](ulong i) const {
00090 BOOST_ASSERT(i < m_fingerprint.size());
00091 return m_fingerprint[i];
00092 }
00093 private:
00094 std::vector<ulong> m_fingerprint;
00095 };
00096
00097 uint splitCell(Partition& pi, ulong i) const;
00098 void computeFingerprint(const Partition& pi, ulong i, ulong j, std::map<Fingerprint,std::list<ulong> >& map) const;
00099 };
00100
00101 template<class PERM,class MATRIX>
00102 MatrixRefinement2<PERM,MATRIX>::MatrixRefinement2(ulong n, const MATRIX& matrix)
00103 : Refinement<PERM>(n, Default), m_matrix(matrix)
00104 {
00105 }
00106
00107 template<class PERM,class MATRIX>
00108 uint MatrixRefinement2<PERM,MATRIX>::apply(Partition& pi) const {
00109 BOOST_ASSERT( this->initialized() );
00110
00111 uint ret = 0;
00112 std::list<int>::const_iterator cellPairIt = Refinement<PERM>::m_cellPairs.begin();
00113 while (cellPairIt != Refinement<PERM>::m_cellPairs.end()) {
00114 ulong i = *cellPairIt++;
00115 ret += splitCell(pi, static_cast<ulong>(i));
00116 }
00117 return ret;
00118 }
00119
00120
00121 template<class PERM,class MATRIX>
00122 bool MatrixRefinement2<PERM,MATRIX>::init(Partition& pi) {
00123 for (ulong i = 0; i < pi.cells(); ++i) {
00124 if (splitCell(pi, i))
00125 Refinement<PERM>::m_cellPairs.push_back(i);
00126 }
00127
00128 if (!Refinement<PERM>::m_cellPairs.empty()) {
00129 typename Refinement<PERM>::RefinementPtr ref(new MatrixRefinement2<PERM,MATRIX>(*this));
00130 Refinement<PERM>::m_backtrackRefinements.push_back(ref);
00131 return true;
00132 }
00133 return false;
00134 }
00135
00136 template<class PERM,class MATRIX>
00137 uint MatrixRefinement2<PERM,MATRIX>::splitCell(Partition& pi, ulong i) const {
00138 ulong ret = 0;
00139 if (pi.cellSize(i) < 2)
00140 return ret;
00141 for (ulong j = 0; j < pi.cells(); ++j) {
00142 std::map<Fingerprint,std::list<ulong> > map;
00143 computeFingerprint(pi, i, j, map);
00144 if (map.size() > 1) {
00145 DEBUG(std::cout << "split " << i << " because of " << j << " in " << pi << std::endl;)
00146 typename std::map<Fingerprint,std::list<ulong> >::const_iterator fit;
00147 for (fit = map.begin(); fit != map.end(); ++fit) {
00148 std::pair<Fingerprint, std::list<ulong> > splitCell = *fit;
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 if (pi.intersect(splitCell.second.begin(), splitCell.second.end(), i)) {
00160 ++ret;
00161 }
00162 }
00163 break;
00164 }
00165 }
00166 return ret;
00167 }
00168
00169 template<class PERM,class MATRIX>
00170 void MatrixRefinement2<PERM,MATRIX>::computeFingerprint(const Partition& pi, ulong i, ulong j, std::map<Fingerprint,std::list<ulong> >& map) const {
00171 for (Partition::CellIt cellI = pi.cellBegin(i); cellI != pi.cellEnd(i); ++cellI) {
00172 Fingerprint f(m_matrix.k());
00173 for (Partition::CellIt cellJ = pi.cellBegin(j); cellJ != pi.cellEnd(j); ++cellJ) {
00174 ++f[m_matrix.at(*cellI, *cellJ)];
00175 }
00176 std::pair<typename std::map<Fingerprint,std::list<ulong> >::iterator, bool> p =
00177 map.insert(std::pair<Fingerprint, std::list<ulong> >(f, std::list<ulong>()));
00178 std::list<ulong>& l = p.first->second;
00179 l.push_back(*cellI);
00180 }
00181 }
00182
00183 }
00184 }
00185
00186 #endif // -- MATRIXREFINEMENT2_H_