00001 #ifndef LEMON_SIMANN_H
00002 #define LEMON_SIMANN_H
00003
00011
00012 #include <cstdlib>
00013 #include <cmath>
00014 #include <lemon/time_measure.h>
00015
00016 namespace lemon {
00017
00020
00022 class ControllerBase {
00023 friend class SimAnnBase;
00024 public:
00026 SimAnnBase *simann;
00028 virtual void init() {}
00030 virtual void acceptEvent() {}
00034 virtual void improveEvent() {}
00036 virtual void rejectEvent() {}
00038 virtual bool next() = 0;
00040 virtual bool accept() = 0;
00041 };
00042
00044 class EntityBase {
00045 public:
00049 virtual double mutate() = 0;
00053 virtual void revert() = 0;
00055 virtual EntityBase* clone() = 0;
00057 virtual void randomize() = 0;
00058 };
00059
00061 class SimAnnBase {
00062 private:
00064 ControllerBase *controller;
00066 double curr_cost;
00068 double best_cost;
00070 double prev_cost;
00072 double prev_prev_cost;
00074 long iter;
00077 long last_impr;
00078 protected:
00080 virtual double mutate() = 0;
00082 virtual void revert() = 0;
00084 virtual void saveAsBest() = 0;
00086 virtual void init() {
00087 controller->init();
00088 curr_cost = prev_cost = prev_prev_cost = best_cost =
00089 std::numeric_limits<double>::infinity();
00090 iter = last_impr = 0;
00091 }
00092 public:
00094 void setController(ControllerBase &_controller) {
00095 controller = &_controller;
00096 controller->simann = this;
00097 }
00099 double getCurrCost() const { return curr_cost; }
00101 double getPrevCost() const { return prev_cost; }
00103 double getBestCost() const { return best_cost; }
00105 long getIter() const { return iter; }
00109 long getLastImpr() const { return last_impr; }
00111 bool step() {
00112 iter++;
00113 prev_prev_cost = prev_cost;
00114 prev_cost = curr_cost;
00115 curr_cost = mutate();
00116 if (controller->accept()) {
00117 controller->acceptEvent();
00118 last_impr = iter;
00119 if (curr_cost < best_cost) {
00120 best_cost = curr_cost;
00121 saveAsBest();
00122 controller->improveEvent();
00123 }
00124 }
00125 else {
00126 revert();
00127 curr_cost = prev_cost;
00128 prev_cost = prev_prev_cost;
00129 controller->rejectEvent();
00130 }
00131 return controller->next();
00132 }
00136 bool step(int n) {
00137 for(; n > 0 && step(); --n) ;
00138 return !n;
00139 }
00141 void run() {
00142 init();
00143 do { } while (step());
00144 }
00145 };
00146
00148 class SimAnn : public SimAnnBase {
00149 private:
00151 EntityBase *curr_ent;
00153 EntityBase *best_ent;
00155 void init() {
00156 SimAnnBase::init();
00157 if (best_ent) delete best_ent;
00158 best_ent = NULL;
00159 curr_ent->randomize();
00160 }
00161 public:
00163 SimAnn() : curr_ent(NULL), best_ent(NULL) {}
00165 virtual ~SimAnn() {
00166 if (best_ent) delete best_ent;
00167 }
00169 double mutate() {
00170 return curr_ent->mutate();
00171 }
00173 void revert() {
00174 curr_ent->revert();
00175 }
00177 void saveAsBest() {
00178 if (best_ent) delete best_ent;
00179 best_ent = curr_ent->clone();
00180 }
00182 void setEntity(EntityBase &_ent) {
00183 curr_ent = &_ent;
00184 }
00186 EntityBase* getBestEntity() { return best_ent->clone(); }
00187 };
00188
00190 class SimpleController : public ControllerBase {
00191 public:
00193 long max_iter;
00196 long max_no_impr;
00198 double temp;
00200 double ann_fact;
00208 SimpleController(long _max_iter = 500000, long _max_no_impr = 20000,
00209 double _temp = 1000.0, double _ann_fact = 0.9999) : max_iter(_max_iter),
00210 max_no_impr(_max_no_impr), temp(_temp), ann_fact(_ann_fact)
00211 {
00212 srand48(time(0));
00213 }
00215 void acceptEvent() {}
00219 void improveEvent() {}
00221 void rejectEvent() {}
00224 bool next() {
00225 temp *= ann_fact;
00226 bool quit = (simann->getIter() > max_iter) ||
00227 (simann->getIter() - simann->getLastImpr() > max_no_impr);
00228 return !quit;
00229 }
00231 bool accept() {
00232 double cost_diff = simann->getPrevCost() - simann->getCurrCost();
00233 return (drand48() <= exp(cost_diff / temp));
00234 }
00235 };
00236
00250 class AdvancedController : public ControllerBase {
00251 private:
00252 Timer timer;
00254 virtual double threshold(double time) {
00255 return (-1.0) * start_threshold / end_time * time + start_threshold;
00256 }
00257 public:
00258 double alpha;
00259 double beta;
00260 double gamma;
00262 double end_time;
00264 double start_time;
00266 double start_threshold;
00268 double avg_cost;
00270 double temp;
00272 double ann_fact;
00274 double init_ann_fact;
00275 bool warmup;
00283 AdvancedController(double _end_time, double _alpha = 0.2,
00284 double _beta = 0.9, double _gamma = 1.6, double _ann_fact = 0.9999) :
00285 alpha(_alpha), beta(_beta), gamma(_gamma), end_time(_end_time),
00286 ann_fact(_ann_fact), init_ann_fact(_ann_fact), warmup(true)
00287 {
00288 srand48(time(0));
00289 }
00290 void init() {
00291 avg_cost = simann->getCurrCost();
00292 }
00294 void acceptEvent() {
00295 avg_cost = alpha * simann->getCurrCost() + (1.0 - alpha) * avg_cost;
00296 if (warmup) {
00297 static int cnt = 0;
00298 cnt++;
00299 if (cnt >= 100) {
00300
00301 start_threshold = 5.0 * fabs(simann->getBestCost() - avg_cost);
00302 temp = 10000.0;
00303 warmup = false;
00304 timer.reset();
00305 }
00306 }
00307 }
00309 bool next() {
00310 if (warmup) {
00311 return true;
00312 }
00313 else {
00314 double elapsed_time = timer.getRealTime();
00315 if (fabs(avg_cost - simann->getBestCost()) > threshold(elapsed_time)) {
00316
00317 ann_fact *= beta;
00318 }
00319 else {
00320
00321 temp *= gamma;
00322
00323 ann_fact = init_ann_fact;
00324 }
00325 temp *= ann_fact;
00326 return elapsed_time < end_time;
00327 }
00328 }
00330 bool accept() {
00331 if (warmup) {
00332
00333 return true;
00334 }
00335 else {
00336 double cost_diff = simann->getPrevCost() - simann->getCurrCost();
00337 if (cost_diff < 0.0) {
00338 return (drand48() <= exp(cost_diff / temp));
00339 }
00340 else {
00341 return true;
00342 }
00343 }
00344 }
00345 };
00346
00348
00349 }
00350
00351 #endif