10 const double INFTY = 1e24;
16 Controller *controller;
22 virtual void mutate() = 0;
23 virtual void revert() = 0;
24 virtual void saveAsBest() = 0;
27 curr_cost = prev_cost = best_cost = INFTY;
29 void setController(Controller &_controller) {
30 controller = &_controller;
31 controller->setBase(this);
33 double getCurrCost() { return curr_cost; }
34 double getPrevCost() { return prev_cost; }
35 double getBestCost() { return best_cost; }
38 while (controller->next()) {
40 if (controller->accept()) {
41 controller->acceptEvent();
42 if (curr_cost < best_cost) {
44 controller->improveEvent();
49 controller->rejectEvent();
57 virtual void init() {}
58 virtual void acceptEvent() {}
59 virtual void improveEvent() {}
60 virtual void rejectEvent() {}
61 virtual void setBase(SimAnnBase *_base) { base = _base; }
62 virtual bool next() = 0;
63 virtual bool accept() = 0;
68 class SimAnn : public SimAnnBase {
73 SimAnn() : SimAnnBase() {}
74 void setEntity(E &ent) {
75 curr_ent = new E(ent);
76 best_ent = new E(ent);
78 E getBestEntity() { return *best_ent; }
86 *best_ent = *curr_ent;
87 best_cost = curr_cost;
91 class EntitySkeleton {
93 /*! \brief Makes a minor change to the entity.
94 * \return the new cost
96 double mutate() { return 0.0; }
97 /*! \brief Restores the entity to its previous state i.e. reverts the
98 * effects of the last mutate.
103 /*! \brief A simple controller for the simulated annealing class.
104 * \todo Find a way to set the various parameters.
106 class SimpleController : public SimAnnBase::Controller {
108 long iter, last_impr, max_iter, max_no_impr;
109 double temp, annealing_factor;
111 iter = last_impr = 0;
114 annealing_factor = 0.9999;
120 void improveEvent() {
127 temp *= annealing_factor;
128 bool quit = (iter > max_iter) || (iter - last_impr > max_no_impr);
132 return (drand48() <= exp(base->getPrevCost() - base->getCurrCost() /
137 /*! \brief A controller with preset running time for the simulated annealing
139 * \todo Find a better name.
141 class AdvancedController : public SimAnnBase::Controller {
143 double threshold() { return 0.0; }
148 double start_time, end_time;
151 gettimeofday(&tv, 0);
152 start_time = tv.tv_sec + double(tv.tv_usec) / 1e6;
155 avg_cost = alpha * base->getCurrCost() + (1.0 - alpha) * avg_cost;
157 void improveEvent() {
162 // abs(avg_cost - base->getBestCost())
163 // ha nagy: cooling factor novelese
164 // ha kicsi: homerseklet novelese
167 gettimeofday(&tv, 0);
168 double elapsed_time = tv.tv_sec + double(tv.tv_usec) / 1e6 - start_time;
169 return elapsed_time < end_time;
172 return (drand48() <= exp(base->getPrevCost() - base->getCurrCost() /