00001 #ifndef EtII_NSSEQSwapRotateCenter_HPP_
00002 #define EtII_NSSEQSwapRotateCenter_HPP_
00003
00004
00005 #include "../../../OptFrame/NSSeq.hpp"
00006 #include "../../RandGen.hpp"
00007
00008
00009 #include "ProblemInstance.hpp"
00010 #include "Memory.h"
00011 #include "Solution.h"
00012
00013 using namespace std;
00014
00015 class MoveSwapRotateCenter: public Move<RepEtII, MemEtII>
00016 {
00017 private:
00018 int x1, y1, x2, y2;
00019 int r1, r2;
00020
00021 public:
00022
00023 using Move<RepEtII, MemEtII>::apply;
00024 using Move<RepEtII, MemEtII>::canBeApplied;
00025
00026 MoveSwapRotateCenter(int _x1, int _y1, int _x2, int _y2) :
00027 x1(_x1), y1(_y1), x2(_x2), y2(_y2)
00028 {
00029 r1 = -1;
00030 r2 = -1;
00031 }
00032
00033 MoveSwapRotateCenter(int _x1, int _y1, int _r1, int _x2, int _y2, int _r2) :
00034 x1(_x1), y1(_y1), r1(_r1), x2(_x2), y2(_y2), r2(_r2)
00035 {
00036 }
00037
00038 virtual ~MoveSwapRotateCenter()
00039 {
00040 }
00041
00042 bool canBeApplied(const RepEtII& rep)
00043 {
00044 return !((x1 == x2) && (y1 == y2));
00045 }
00046
00047 Move<RepEtII, MemEtII>& apply(RepEtII& rep)
00048 {
00049 Piece p = rep(x1, y1);
00050 rep(x1, y1) = rep(x2, y2);
00051 rep(x2, y2) = p;
00052
00053 int rot1, rot2;
00054
00055 if (r1 < 0)
00056 {
00057 int best_r = -1;
00058 int best_f = -1;
00059
00060 for (int i = 0; i < 4; i++)
00061 {
00062 int f = 0;
00063 if (rep(x1, y1).left == rep(x1, y1 - 1).right)
00064 f++;
00065 if (rep(x1, y1).up == rep(x1 - 1, y1).down)
00066 f++;
00067 if (rep(x1, y1).right == rep(x1, y1 + 1).left)
00068 f++;
00069 if (rep(x1, y1).down == rep(x1 + 1, y1).up)
00070 f++;
00071
00072 if (f > best_f)
00073 {
00074 best_f = f;
00075 best_r = i;
00076 }
00077
00078 rep(x1, y1).rotate();
00079 }
00080
00081 for (int r = 0; r < best_r; r++)
00082 rep(x1, y1).rotate();
00083
00084 rot1 = 4 - best_r;
00085 if (rot1 == 4)
00086 rot1 = 0;
00087
00088
00089
00090 best_r = -1;
00091 best_f = -1;
00092
00093 for (int i = 0; i < 4; i++)
00094 {
00095 int f = 0;
00096 if (rep(x2, y2).left == rep(x2, y2 - 1).right)
00097 f++;
00098 if (rep(x2, y2).up == rep(x2 - 1, y2).down)
00099 f++;
00100 if (rep(x2, y2).right == rep(x2, y2 + 1).left)
00101 f++;
00102 if (rep(x2, y2).down == rep(x2 + 1, y2).up)
00103 f++;
00104
00105 if (f > best_f)
00106 {
00107 best_f = f;
00108 best_r = i;
00109 }
00110
00111 rep(x2, y2).rotate();
00112 }
00113
00114 for (int r = 0; r < best_r; r++)
00115 rep(x2, y2).rotate();
00116
00117 rot2 = 4 - best_r;
00118 if (rot2 == 4)
00119 rot2 = 0;
00120 }
00121 else
00122 {
00123 for (int i = 0; i < r1; i++)
00124 rep(x1, y1).rotate();
00125
00126 for (int i = 0; i < r2; i++)
00127 rep(x2, y2).rotate();
00128
00129 rot1 = -1;
00130 rot2 = -1;
00131 }
00132
00133 return *new MoveSwapRotateCenter(x1, y1, rot2, x2, y2, rot1);
00134 }
00135
00136 Move<RepEtII, MemEtII>& apply(MemEtII& mem, RepEtII& rep)
00137 {
00138 int f = 0;
00139 if (rep(x1, y1).left == rep(x1, y1 - 1).right)
00140 f++;
00141 if (rep(x1, y1).up == rep(x1 - 1, y1).down)
00142 f++;
00143 if (rep(x1, y1).right == rep(x1, y1 + 1).left)
00144 f++;
00145 if (rep(x1, y1).down == rep(x1 + 1, y1).up)
00146 f++;
00147
00148 int g = 0;
00149 if ((rep(x2, y2).left == rep(x2, y2 - 1).right) && !((x2 == x1) && ((y2 - 1) == y1)))
00150 g++;
00151 if ((rep(x2, y2).up == rep(x2 - 1, y2).down) && !(((x2 - 1) == x1) && (y2 == y1)))
00152 g++;
00153 if ((rep(x2, y2).right == rep(x2, y2 + 1).left) && !((x2 == x1) && ((y2 + 1) == y1)))
00154 g++;
00155 if ((rep(x2, y2).down == rep(x2 + 1, y2).up) && !(((x2 + 1) == x1) && (y2 == y1)))
00156 g++;
00157
00158 Move<RepEtII, MemEtII>& rev = apply(rep);
00159
00160 int f2 = 0;
00161 if (rep(x1, y1).left == rep(x1, y1 - 1).right)
00162 f2++;
00163 if (rep(x1, y1).up == rep(x1 - 1, y1).down)
00164 f2++;
00165 if (rep(x1, y1).right == rep(x1, y1 + 1).left)
00166 f2++;
00167 if (rep(x1, y1).down == rep(x1 + 1, y1).up)
00168 f2++;
00169
00170 int g2 = 0;
00171 if ((rep(x2, y2).left == rep(x2, y2 - 1).right) && !((x2 == x1) && ((y2 - 1) == y1)))
00172 g2++;
00173 if ((rep(x2, y2).up == rep(x2 - 1, y2).down) && !(((x2 - 1) == x1) && (y2 == y1)))
00174 g2++;
00175 if ((rep(x2, y2).right == rep(x2, y2 + 1).left) && !((x2 == x1) && ((y2 + 1) == y1)))
00176 g2++;
00177 if ((rep(x2, y2).down == rep(x2 + 1, y2).up) && !(((x2 + 1) == x1) && (y2 == y1)))
00178 g2++;
00179
00180 mem += (f2 - f);
00181 mem += (g2 - g);
00182
00183 return rev;
00184 }
00185
00186 virtual bool operator==(const Move<RepEtII, MemEtII>& _m) const
00187 {
00188 const MoveSwapRotateCenter& m = (const MoveSwapRotateCenter&) _m;
00189 return (m.x1 == x1) && (m.y1 == y1) && (m.x2 == x2) && (m.y2 == y2) && (m.r1 == r1) && (m.r2 == r2);
00190 }
00191
00192 void print()
00193 {
00194 cout << "MoveSwapRotateCenter: (" << x1 << "," << y1 << ") r=" << r1 << " <=> (" << x2 << "," << y2 << ") r=" << r2 << endl;
00195 }
00196 };
00197
00198 class NSIteratorSwapRotateCenter: public NSIterator<RepEtII, MemEtII>
00199 {
00200 private:
00201 int nIntraRows, nIntraCols;
00202 int x1, y1, x2, y2;
00203
00204 public:
00205 NSIteratorSwapRotateCenter(int _nIntraRows, int _nIntraCols) :
00206 nIntraRows(_nIntraRows), nIntraCols(_nIntraCols)
00207 {
00208 }
00209
00210 virtual ~NSIteratorSwapRotateCenter()
00211 {
00212 }
00213
00214 virtual void first()
00215 {
00216 x1 = 0;
00217 y1 = 0;
00218
00219 x2 = 0;
00220 y2 = 1;
00221 }
00222
00223 virtual void next()
00224 {
00225 y2++;
00226 if (y2 >= nIntraCols)
00227 {
00228 y2 = 0;
00229 x2++;
00230 if (x2 >= nIntraRows)
00231 {
00232 y1++;
00233 if (y1 >= nIntraCols)
00234 {
00235 y1 = 0;
00236 x1++;
00237
00238 x2 = x1;
00239 y2 = y1 + 1;
00240 if (y2 >= nIntraCols)
00241 {
00242 y2 = 0;
00243 x2++;
00244 }
00245 }
00246 else
00247 {
00248 x2 = x1;
00249 y2 = y1 + 1;
00250 if (y2 >= nIntraCols)
00251 {
00252 y2 = 0;
00253 x2++;
00254 }
00255 }
00256 }
00257 }
00258 }
00259
00260 virtual bool isDone()
00261 {
00262 return (x1 >= nIntraRows) || (y1 >= nIntraCols) || (x2 >= nIntraRows) || (y2 >= nIntraCols);
00263 }
00264
00265 virtual Move<RepEtII, MemEtII>& current()
00266 {
00267 return *new MoveSwapRotateCenter(x1 + 1, y1 + 1, x2 + 1, y2 + 1);
00268 }
00269 };
00270
00271 class NSSeqSwapRotateCenter: public NSSeq<RepEtII, MemEtII>
00272 {
00273 private:
00274 RandGen& rg;
00275 public:
00276
00277 using NSSeq<RepEtII, MemEtII>::move;
00278 using NSSeq<RepEtII, MemEtII>::getIterator;
00279
00280 NSSeqSwapRotateCenter(RandGen& _rg) :
00281 rg(_rg)
00282 {
00283 }
00284
00285 virtual ~NSSeqSwapRotateCenter()
00286 {
00287 }
00288
00289 virtual Move<RepEtII, MemEtII>& move(const RepEtII& rep)
00290 {
00291 if ((rep.getRows() == 3) && (rep.getCols() == 3))
00292 return *new MoveSwapRotateCenter(1, 1, 1, 1);
00293
00294
00295 int x1 = rg.rand((rep.getRows() - 2)) + 1;
00296 int y1 = rg.rand((rep.getCols() - 2)) + 1;
00297
00298 int x2 = x1;
00299 int y2 = y1;
00300 while ((x2 == x1) && (y2 == y1))
00301 {
00302 x2 = rg.rand((rep.getRows() - 2)) + 1;
00303 y2 = rg.rand((rep.getCols() - 2)) + 1;
00304 }
00305
00306 return *new MoveSwapRotateCenter(x1, y1, x2, y2);
00307 }
00308
00309 virtual NSIterator<RepEtII, MemEtII>& getIterator(const RepEtII& rep)
00310 {
00311
00312 return *new NSIteratorSwapRotateCenter(rep.getRows() - 2, rep.getCols() - 2);
00313 }
00314
00315 virtual void print()
00316 {
00317 cout << "NSSeqSwapRotateCenter" << endl;
00318 }
00319 };
00320
00321 #endif