00001 #ifndef TSP_NSENUMSwap_HPP_
00002 #define TSP_NSENUMSwap_HPP_
00003
00004
00005 #include "../../../OptFrame/Move.hpp"
00006 #include "../../../OptFrame/NSEnum.hpp"
00007
00008
00009 #include "ProblemInstance.hpp"
00010 #include "Memory.h"
00011 #include "Solution.h"
00012 #include "../../RandGen.hpp"
00013
00014
00015
00016 using namespace std;
00017
00018
00019
00020
00021
00022 class MoveSwap: public Move<RepTSP, MemTSP>
00023 {
00024 private:
00025 int c1, c2;
00026 TSPProblemInstance& tsp;
00027
00028 public:
00029
00030 MoveSwap(int c1, int c2, TSPProblemInstance& _tsp) :
00031 tsp(_tsp)
00032 {
00033 this->c1 = c1;
00034 this->c2 = c2;
00035
00036
00037 }
00038
00039 bool canBeApplied(const RepTSP& rep)
00040 {
00041
00042
00043 return true;
00044 }
00045
00046 Move<RepTSP, MemTSP>& apply(RepTSP& rep)
00047 {
00048
00049
00050 int aux = rep.at(c1);
00051 rep[c1] = rep[c2];
00052 rep[c2] = aux;
00053
00054
00055 return *new MoveSwap(c2, c1, tsp);
00056 }
00057
00058 Move<RepTSP, MemTSP>& apply(MemTSP& mem, RepTSP& rep)
00059 {
00060 int k1, k2;
00061
00062 if (c1 < c2)
00063 {
00064 k1 = c1;
00065 k2 = c2;
00066 }
00067 else
00068 {
00069 k1 = c2;
00070 k2 = c1;
00071 }
00072
00073
00074 int bk1 = k1 - 1;
00075 int bk2 = k2 - 1;
00076
00077 int ak1 = k1 + 1;
00078 int ak2 = k2 + 1;
00079
00080 if (k1 == 0)
00081 bk1 = rep.size() - 1;
00082 if (k2 == rep.size() - 1)
00083 ak2 = 0;
00084
00085 int f = 0;
00086
00087 if (k2 - k1 == 1)
00088 {
00089 f -= (*tsp.dist)(rep[bk1], rep[k1]);
00090 f -= (*tsp.dist)(rep[k1], rep[k2]);
00091 f -= (*tsp.dist)(rep[k2], rep[ak2]);
00092 }
00093 else
00094 {
00095 f -= (*tsp.dist)(rep[bk1], rep[k1]);
00096 f -= (*tsp.dist)(rep[k1], rep[ak1]);
00097 f -= (*tsp.dist)(rep[bk2], rep[k2]);
00098 f -= (*tsp.dist)(rep[k2], rep[ak2]);
00099 }
00100
00101 Move<RepTSP, MemTSP>& rev = apply(rep);
00102
00103 if (k2 - k1 == 1)
00104 {
00105 f += (*tsp.dist)(rep[bk1], rep[k1]);
00106 f += (*tsp.dist)(rep[k1], rep[k2]);
00107 f += (*tsp.dist)(rep[k2], rep[ak2]);
00108 }
00109 else
00110 {
00111 f += (*tsp.dist)(rep[bk1], rep[k1]);
00112 f += (*tsp.dist)(rep[k1], rep[ak1]);
00113 f += (*tsp.dist)(rep[bk2], rep[k2]);
00114 f += (*tsp.dist)(rep[k2], rep[ak2]);
00115 }
00116
00117 mem += f;
00118
00119 return rev;
00120 }
00121
00122 void print()
00123 {
00124 cout << "MoveSwap between " << c1 << " and " << c2 << endl;
00125 }
00126
00127 virtual bool operator==(const Move<RepTSP, MemTSP>& _m) const
00128 {
00129 const MoveSwap& m = (const MoveSwap&) _m;
00130
00131 if ((c1 == m.c1 && c2 == m.c2) || (c1 == m.c2 && c2 == m.c1))
00132 return true;
00133 else
00134 return false;
00135 }
00136
00137 };
00138
00139
00140
00141
00142
00143
00144 class NSEnumSwap: public NSEnum<RepTSP, MemTSP>
00145 {
00146 private:
00147 TSPProblemInstance* pI;
00148 int n;
00149
00150
00151
00152 public:
00153
00154 using NSEnum<RepTSP, MemTSP>::move;
00155
00156 NSEnumSwap(TSPProblemInstance* pI, RandGen& _rg) :
00157 NSEnum<RepTSP, MemTSP> (_rg)
00158 {
00159 this->pI = pI;
00160 this->n = pI->n;
00161 }
00162
00163 virtual Move<RepTSP, MemTSP>& move(unsigned int k)
00164 {
00165 return busca(k, 1, 2 * n);
00166 }
00167
00168 unsigned int size()
00169 {
00170 return n * (n - 1) / 2;
00171 }
00172
00173 virtual void print()
00174 {
00175 cout << "\nNSEnum Swap (" << size() << ")\n";
00176 }
00177
00178
00179
00180
00181 int corresp(int d)
00182 {
00183 return d - ((d - (n - 1)) - 1) * 2;
00184 }
00185
00186 int numElem(int d)
00187 {
00188 if (d <= n)
00189 return (d / 2);
00190 else
00191 return numElem(corresp(d));
00192 }
00193
00194 int comeca(int d)
00195 {
00196
00197 if (d <= n)
00198 {
00199 int z = (d / 2);
00200
00201 int ant = z * (z - 1);
00202
00203
00204 if (d % 2 == 1)
00205 ant += z;
00206
00207 return ant;
00208 }
00209 else
00210 {
00211 return 2 * (comeca(n)) - comeca(corresp(d) + 1) + numElem(n);
00212 }
00213
00214 }
00215
00216 int termina(int d)
00217 {
00218 return comeca(d) + numElem(d) - 1;
00219 }
00220
00221 Move<RepTSP, MemTSP>& busca(int k, int a, int b)
00222 {
00223 int d = (a + b) / 2;
00224
00225
00226
00227 int c = comeca(d);
00228 int t = termina(d);
00229
00230
00231
00232
00233
00234
00235 if (k < c)
00236 {
00237
00238 return busca(k, a, d);
00239 }
00240
00241 if (k > t)
00242 {
00243
00244
00245 if (a == d)
00246 d++;
00247
00248 return busca(k, d, b);
00249 }
00250
00251 if (d <= n)
00252 {
00253
00254 for (int i = 0; i < numElem(d); i++)
00255 if (k == c + i)
00256 return *new MoveSwap(i, d - i - 1, *pI);
00257 }
00258 else
00259 {
00260
00261 for (int i = 0; i < numElem(d); i++)
00262 if (k == c + i)
00263 {
00264 int j = d - n;
00265 return *new MoveSwap(i + j, d - i - 1 - j, *pI);
00266 }
00267
00268 }
00269
00270 cout << "Error!" << endl;
00271 return *new MoveSwap(0, 0, *pI);
00272 }
00273
00274 };
00275
00276 #endif
00277