00001 #ifndef EtII_NSSEQSwapCenter_HPP_
00002 #define EtII_NSSEQSwapCenter_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 MoveSwapCenter: 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 MoveSwapCenter(int _x1, int _y1, int _x2, int _y2) :
00026 x1(_x1), y1(_y1), x2(_x2), y2(_y2)
00027 {
00028 }
00029
00030 virtual ~MoveSwapCenter()
00031 {
00032 }
00033
00034 bool canBeApplied(const RepEtII& rep)
00035 {
00036 return true;
00037 }
00038
00039 Move<RepEtII, MemEtII>& apply(RepEtII& rep)
00040 {
00041 Piece p = rep(x1, y1);
00042 rep(x1, y1) = rep(x2, y2);
00043 rep(x2, y2) = p;
00044
00045 return *new MoveSwapCenter(x2, y2, x1, y1);
00046 }
00047
00048 Move<RepEtII, MemEtII>& apply(MemEtII& mem, RepEtII& rep)
00049 {
00050 int f = 0;
00051 if (rep(x1, y1).left == rep(x1, y1 - 1).right)
00052 f++;
00053 if (rep(x1, y1).up == rep(x1 - 1, y1).down)
00054 f++;
00055 if (rep(x1, y1).right == rep(x1, y1 + 1).left)
00056 f++;
00057 if (rep(x1, y1).down == rep(x1 + 1, y1).up)
00058 f++;
00059
00060 int g = 0;
00061 if ((rep(x2, y2).left == rep(x2, y2 - 1).right) && !((x2 == x1) && ((y2 - 1) == y1)))
00062 g++;
00063 if ((rep(x2, y2).up == rep(x2 - 1, y2).down) && !(((x2 - 1) == x1) && (y2 == y1)))
00064 g++;
00065 if ((rep(x2, y2).right == rep(x2, y2 + 1).left) && !((x2 == x1) && ((y2 + 1) == y1)))
00066 g++;
00067 if ((rep(x2, y2).down == rep(x2 + 1, y2).up) && !(((x2 + 1) == x1) && (y2 == y1)))
00068 g++;
00069
00070 Move<RepEtII, MemEtII>& rev = apply(rep);
00071
00072 int f2 = 0;
00073 if (rep(x1, y1).left == rep(x1, y1 - 1).right)
00074 f2++;
00075 if (rep(x1, y1).up == rep(x1 - 1, y1).down)
00076 f2++;
00077 if (rep(x1, y1).right == rep(x1, y1 + 1).left)
00078 f2++;
00079 if (rep(x1, y1).down == rep(x1 + 1, y1).up)
00080 f2++;
00081
00082 int g2 = 0;
00083 if ((rep(x2, y2).left == rep(x2, y2 - 1).right) && !((x2 == x1) && ((y2 - 1) == y1)))
00084 g2++;
00085 if ((rep(x2, y2).up == rep(x2 - 1, y2).down) && !(((x2 - 1) == x1) && (y2 == y1)))
00086 g2++;
00087 if ((rep(x2, y2).right == rep(x2, y2 + 1).left) && !((x2 == x1) && ((y2 + 1) == y1)))
00088 g2++;
00089 if ((rep(x2, y2).down == rep(x2 + 1, y2).up) && !(((x2 + 1) == x1) && (y2 == y1)))
00090 g2++;
00091
00092 mem += (f2 - f);
00093 mem += (g2 - g);
00094
00095 return rev;
00096 }
00097
00098 virtual bool operator==(const Move<RepEtII, MemEtII>& _m) const
00099 {
00100 const MoveSwapCenter& m = (const MoveSwapCenter&) _m;
00101 return (m.x1 == x1) && (m.y1 == y1) && (m.x2 == x2) && (m.y2 == y2);
00102 }
00103
00104 void print()
00105 {
00106 cout << "MoveSwapCenter: (" << x1 << "," << y1 << ") <=> (" << x2 << "," << y2 << ")" << endl;
00107 }
00108 };
00109
00110 class NSIteratorSwapCenter: public NSIterator<RepEtII, MemEtII>
00111 {
00112 private:
00113 int nIntraRows, nIntraCols;
00114 int x1, y1, x2, y2;
00115
00116 public:
00117 NSIteratorSwapCenter(int _nIntraRows, int _nIntraCols) :
00118 nIntraRows(_nIntraRows), nIntraCols(_nIntraCols)
00119 {
00120 }
00121
00122 virtual ~NSIteratorSwapCenter()
00123 {
00124 }
00125
00126 virtual void first()
00127 {
00128 x1 = 0;
00129 y1 = 0;
00130
00131 x2 = 0;
00132 y2 = 1;
00133 }
00134
00135 virtual void next()
00136 {
00137 y2++;
00138 if (y2 >= nIntraCols)
00139 {
00140 y2 = 0;
00141 x2++;
00142 if (x2 >= nIntraRows)
00143 {
00144
00145 y1++;
00146 if (y1 >= nIntraCols)
00147 {
00148 y1 = 0;
00149 x1++;
00150
00151 x2 = x1;
00152 y2 = y1 + 1;
00153 if (y2 >= nIntraCols)
00154 {
00155 y2 = 0;
00156 x2++;
00157 }
00158 }
00159 else
00160 {
00161 x2 = x1;
00162 y2 = y1 + 1;
00163 if (y2 >= nIntraCols)
00164 {
00165 y2 = 0;
00166 x2++;
00167 }
00168 }
00169 }
00170 }
00171 }
00172
00173 virtual bool isDone()
00174 {
00175 return (x1 >= nIntraRows) || (y1 >= nIntraCols) || (x2 >= nIntraRows) || (y2 >= nIntraCols);
00176 }
00177
00178 virtual Move<RepEtII, MemEtII>& current()
00179 {
00180 return *new MoveSwapCenter(x1 + 1, y1 + 1, x2 + 1, y2 + 1);
00181 }
00182 };
00183
00184 class NSSeqSwapCenter: public NSSeq<RepEtII, MemEtII>
00185 {
00186 private:
00187 RandGen& rg;
00188 public:
00189
00190 using NSSeq<RepEtII, MemEtII>::move;
00191 using NSSeq<RepEtII, MemEtII>::getIterator;
00192
00193 NSSeqSwapCenter(RandGen& _rg) :
00194 rg(_rg)
00195 {
00196 }
00197
00198 virtual ~NSSeqSwapCenter()
00199 {
00200 }
00201
00202 virtual Move<RepEtII, MemEtII>& move(const RepEtII& rep)
00203 {
00204 if ((rep.getRows() == 3) && (rep.getCols() == 3))
00205 return *new MoveSwapCenter(1, 1, 1, 1);
00206
00207
00208 int x1 = rg.rand((rep.getRows() - 2)) + 1;
00209 int y1 = rg.rand((rep.getCols() - 2)) + 1;
00210
00211 int x2 = x1;
00212 int y2 = y1;
00213 while ((x2 == x1) && (y2 == y1))
00214 {
00215 x2 = rg.rand((rep.getRows() - 2)) + 1;
00216 y2 = rg.rand((rep.getCols() - 2)) + 1;
00217 }
00218
00219 return *new MoveSwapCenter(x1, y1, x2, y2);
00220 }
00221
00222 virtual NSIterator<RepEtII, MemEtII>& getIterator(const RepEtII& rep)
00223 {
00224
00225 return *new NSIteratorSwapCenter(rep.getRows() - 2, rep.getCols() - 2);
00226 }
00227
00228 virtual void print()
00229 {
00230 cout << "NSSeqSwapCenter" << endl;
00231 }
00232 };
00233
00234 #endif
00235