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