00001 #ifndef EtII_NSSEQRotate_HPP_
00002 #define EtII_NSSEQRotate_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 MoveRotate: public Move<RepEtII, MemEtII>
00016 {
00017 private:
00018 int nRot, x, y;
00019
00020 public:
00021
00022 using Move<RepEtII, MemEtII>::apply;
00023 using Move<RepEtII, MemEtII>::canBeApplied;
00024
00025 MoveRotate(int _nRot, int _x, int _y) :
00026 nRot(_nRot), x(_x), y(_y)
00027 {
00028 }
00029
00030 virtual ~MoveRotate()
00031 {
00032 }
00033
00034 bool canBeApplied(const RepEtII& rep)
00035 {
00036 return true;
00037 }
00038
00039 Move<RepEtII, MemEtII>& apply(RepEtII& rep)
00040 {
00041 for (int i = 0; i < nRot; i++)
00042 rep(x, y).rotate();
00043
00044 return *new MoveRotate(4 - nRot, x, y);
00045 }
00046
00047 Move<RepEtII, MemEtII>& apply(MemEtII& mem, RepEtII& rep)
00048 {
00049 int f = 0;
00050 if (rep(x, y).left == rep(x, y - 1).right)
00051 f++;
00052 if (rep(x, y).up == rep(x - 1, y).down)
00053 f++;
00054 if (rep(x, y).right == rep(x, y + 1).left)
00055 f++;
00056 if (rep(x, y).down == rep(x + 1, y).up)
00057 f++;
00058
00059 Move<RepEtII, MemEtII>& rev = apply(rep);
00060
00061 int f2 = 0;
00062 if (rep(x, y).left == rep(x, y - 1).right)
00063 f2++;
00064 if (rep(x, y).up == rep(x - 1, y).down)
00065 f2++;
00066 if (rep(x, y).right == rep(x, y + 1).left)
00067 f2++;
00068 if (rep(x, y).down == rep(x + 1, y).up)
00069 f2++;
00070
00071 mem += (f2 - f);
00072
00073 return rev;
00074 }
00075
00076 virtual bool operator==(const Move<RepEtII, MemEtII>& _m) const
00077 {
00078 const MoveRotate& m = (const MoveRotate&) _m;
00079 return (m.nRot == nRot) && (m.x == x) && (m.y == y);
00080 }
00081
00082 void print()
00083 {
00084 cout << "MoveRotate: " << nRot << " rotations on (" << x << "," << y << ")" << endl;
00085 }
00086 };
00087
00088 class NSIteratorRotate: public NSIterator<RepEtII, MemEtII>
00089 {
00090 private:
00091 int nIntraRows, nIntraCols;
00092 int nRot, x, y;
00093
00094 public:
00095
00096 NSIteratorRotate(int _nIntraRows, int _nIntraCols) :
00097 nIntraRows(_nIntraRows), nIntraCols(_nIntraCols)
00098 {
00099 x = 0;
00100 y = 0;
00101 nRot = 1;
00102 }
00103
00104 virtual ~NSIteratorRotate()
00105 {
00106 }
00107
00108 virtual void first()
00109 {
00110 x = 0;
00111 y = 0;
00112 nRot = 1;
00113 }
00114
00115 virtual void next()
00116 {
00117 nRot++;
00118 if (nRot > 3)
00119 {
00120 nRot = 1;
00121 y++;
00122 if (y >= nIntraCols)
00123 {
00124 y = 0;
00125 x++;
00126 }
00127 }
00128 }
00129
00130 virtual bool isDone()
00131 {
00132 return x >= nIntraRows;
00133 }
00134
00135 virtual Move<RepEtII, MemEtII>& current()
00136 {
00137 return *new MoveRotate(nRot, x + 1, y + 1);
00138 }
00139 };
00140
00141 class NSSeqRotate: public NSSeq<RepEtII, MemEtII>
00142 {
00143 private:
00144 RandGen& rg;
00145 public:
00146
00147 using NSSeq<RepEtII, MemEtII>::move;
00148
00149 NSSeqRotate(RandGen& _rg) :
00150 rg(_rg)
00151 {
00152 }
00153
00154 virtual ~NSSeqRotate()
00155 {
00156 }
00157
00158 virtual Move<RepEtII, MemEtII>& move(const RepEtII& rep)
00159 {
00160
00161 int x = rg.rand((rep.getRows() - 2)) + 1;
00162 int y = rg.rand((rep.getCols() - 2)) + 1;
00163 int nRot = rg.rand(3) + 1;
00164
00165 return *new MoveRotate(nRot, x, y);
00166 }
00167
00168 virtual NSIterator<RepEtII, MemEtII>& getIterator(const RepEtII& rep)
00169 {
00170
00171 return *new NSIteratorRotate(rep.getRows() - 2, rep.getCols() - 2);
00172 }
00173
00174 virtual void print()
00175 {
00176 cout << "NSSeqRotate" << endl;
00177 }
00178 };
00179
00180 #endif
00181