[Lemon-commits] [lemon_svn] ladanyi: r1408 - hugo/trunk/src/work/akos
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:45:11 CET 2006
Author: ladanyi
Date: Mon Nov 22 15:39:40 2004
New Revision: 1408
Modified:
hugo/trunk/src/work/akos/simann.h
Log:
Use lemon::Timer for time measuring. Added the threshold() function and initial threshold and temperature calculation.
Modified: hugo/trunk/src/work/akos/simann.h
==============================================================================
--- hugo/trunk/src/work/akos/simann.h (original)
+++ hugo/trunk/src/work/akos/simann.h Mon Nov 22 15:39:40 2004
@@ -3,7 +3,7 @@
#include <cstdlib>
#include <cmath>
-#include <sys/time.h>
+#include <lemon/time_measure.h>
namespace lemon {
@@ -30,12 +30,12 @@
controller = &_controller;
controller->setBase(this);
}
- double getCurrCost() { return curr_cost; }
- double getPrevCost() { return prev_cost; }
- double getBestCost() { return best_cost; }
+ double getCurrCost() const { return curr_cost; }
+ double getPrevCost() const { return prev_cost; }
+ double getBestCost() const { return best_cost; }
void run() {
controller->init();
- while (controller->next()) {
+ do {
mutate();
if (controller->accept()) {
controller->acceptEvent();
@@ -48,7 +48,7 @@
revert();
controller->rejectEvent();
}
- }
+ } while (controller->next());
}
/*! \brief A base class for controllers. */
@@ -72,6 +72,7 @@
};
};
+ /*! \todo atgondolni mi is ez a prev_cost */
template <typename E>
class SimAnn : public SimAnnBase {
private:
@@ -85,10 +86,12 @@
}
E getBestEntity() { return *best_ent; }
void mutate() {
- curr_ent->mutate();
+ prev_cost = curr_cost;
+ curr_cost = curr_ent->mutate();
}
void revert() {
curr_ent->revert();
+ curr_cost = prev_cost;
}
void saveAsBest() {
*best_ent = *curr_ent;
@@ -140,8 +143,13 @@
return !quit;
}
bool accept() {
- return (drand48() <= exp(base->getPrevCost() - base->getCurrCost() /
- temp));
+ double cost_diff = base->getPrevCost() - base->getCurrCost();
+ if (cost_diff < 0.0) {
+ return (drand48() <= exp(cost_diff / temp));
+ }
+ else {
+ return true;
+ }
}
};
@@ -151,51 +159,90 @@
*/
class AdvancedController : public SimAnnBase::Controller {
private:
+ Timer timer;
/*! \param time the elapsed time in seconds */
- double threshold(double time) { return 0.0; }
+ virtual double threshold(double time) {
+ // this is the function 1 / log(x) scaled and offset
+ static double xm = 5.0 / end_time;
+ static double ym = start_threshold / (1 / log(1.2) - 1 / log(5.0 + 1.2));
+ return ym * (1 / log(xm * time + 1.2) - 1 / log(5.0 + 1.2));
+ }
public:
double alpha, beta, gamma;
double end_time, start_time;
+ double start_threshold;
double avg_cost;
double temp, ann_fact;
- /*! \param _end_time running_time
+ bool warmup;
+ long iter;
+ /*! \param _end_time running time in seconds
* \param _alpha parameter used to calculate the running average
* \param _beta parameter used to decrease the annealing factor
* \param _gamma parameter used to increase the temperature
*/
AdvancedController(double _end_time, double _alpha = 0.2,
double _beta = 0.9, double _gamma = 1.2) : alpha(_alpha), beta(_beta),
- gamma(_gamma), end_time(_end_time) {}
+ gamma(_gamma), end_time(_end_time), ann_fact(0.9999), warmup(true),
+ iter(0) {}
void init() {
- timeval tv;
- gettimeofday(&tv, 0);
- start_time = tv.tv_sec + double(tv.tv_usec) / 1e6;
+ avg_cost = base->getCurrCost();
}
void acceptEvent() {
avg_cost = alpha * base->getCurrCost() + (1.0 - alpha) * avg_cost;
+ iter++;
}
void improveEvent() {
}
void rejectEvent() {
+ iter++;
}
bool next() {
- timeval tv;
- gettimeofday(&tv, 0);
- double elapsed_time = tv.tv_sec + double(tv.tv_usec) / 1e6 - start_time;
- if (fabs(avg_cost - base->getBestCost()) > threshold(elapsed_time)) {
- // decrease the annealing factor
- ann_fact *= beta;
+ if (warmup) {
+ static double max_cost_diff = 0.0;
+ double cost_diff = base->getCurrCost() - base->getPrevCost();
+ // jo ez igy egyaltalan? -> prev_cost
+ if ((cost_diff > 0.0) && (cost_diff > max_cost_diff)) {
+ max_cost_diff = cost_diff;
+ }
+ // How to set the starting temperature when all the 100 first
+ // iterations improve the solution?
+ if (iter > 100) {
+ // calculate starting threshold and starting temperature
+ start_threshold = fabs(base->getBestCost() - avg_cost);
+ temp = exp(max_cost_diff) / 0.5;
+ warmup = false;
+ timer.reset();
+ }
+ return true;
}
else {
- // increase the temperature
- temp *= gamma;
+ double elapsed_time = timer.getRealTime();
+ if (fabs(avg_cost - base->getBestCost()) > threshold(elapsed_time)) {
+ // decrease the annealing factor
+ ann_fact *= beta;
+ }
+ else {
+ // increase the temperature
+ temp *= gamma;
+ }
+ temp *= ann_fact;
+ return elapsed_time < end_time;
}
- temp *= ann_fact;
- return elapsed_time < end_time;
}
bool accept() {
- return (drand48() <= exp(base->getPrevCost() - base->getCurrCost() /
- temp));
+ if (warmup) {
+ // we accept eveything during the "warm up" phase
+ return true;
+ }
+ else {
+ double cost_diff = base->getPrevCost() - base->getCurrCost();
+ if (cost_diff < 0.0) {
+ return (drand48() <= exp(cost_diff / temp));
+ }
+ else {
+ return true;
+ }
+ }
}
};
More information about the Lemon-commits
mailing list