1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/work/akos/simann.h Mon Oct 11 18:02:48 2004 +0000
1.3 @@ -0,0 +1,126 @@
1.4 +#ifndef LEMON_SIMANN_H
1.5 +#define LEMON_SIMANN_H
1.6 +
1.7 +namespace lemon {
1.8 +
1.9 + const double INFTY = 1e24;
1.10 +
1.11 + class SimAnnBase {
1.12 + public:
1.13 + class Controller;
1.14 + private:
1.15 + Controller *controller;
1.16 + protected:
1.17 + double curr_cost;
1.18 + double prev_cost;
1.19 + double best_cost;
1.20 +
1.21 + virtual void mutate() = 0;
1.22 + virtual void revert() = 0;
1.23 + virtual void saveAsBest() = 0;
1.24 + public:
1.25 + SimAnnBase() {
1.26 + curr_cost = prev_cost = best_cost = INFTY;
1.27 + }
1.28 + void setController(Controller &_controller) { controller = &_controller; }
1.29 + double getBestCost() { return best_cost; }
1.30 + void run() {
1.31 + while (controller->next()) {
1.32 + mutate();
1.33 + if (controller->accept(prev_cost - curr_cost)) {
1.34 + controller->acceptEvent();
1.35 + if (curr_cost < best_cost) {
1.36 + saveAsBest();
1.37 + controller->improveEvent();
1.38 + }
1.39 + }
1.40 + else {
1.41 + revert();
1.42 + controller->rejectEvent();
1.43 + }
1.44 + }
1.45 + }
1.46 +
1.47 + class Controller {
1.48 + public:
1.49 + virtual void acceptEvent() {}
1.50 + virtual void improveEvent() {}
1.51 + virtual void rejectEvent() {}
1.52 + virtual bool next() = 0;
1.53 + virtual bool accept(double cost_diff) = 0;
1.54 + };
1.55 + };
1.56 +
1.57 + template <typename E>
1.58 + class SimAnn : public SimAnnBase {
1.59 + private:
1.60 + E *curr_ent;
1.61 + E *prev_ent;
1.62 + E *best_ent;
1.63 + public:
1.64 + SimAnn() : SimAnnBase() {}
1.65 + void setEntity(E &Ent) {
1.66 + curr_ent = new E(Ent);
1.67 + prev_ent = new E(Ent);
1.68 + best_ent = new E(Ent);
1.69 + }
1.70 + E getBestEntity() { return *best_ent; }
1.71 + void mutate() {
1.72 + *prev_ent = *curr_ent;
1.73 + prev_cost = curr_cost;
1.74 + curr_cost = curr_ent->mutate();
1.75 + }
1.76 + void revert() {
1.77 + E *tmp = curr_ent;
1.78 + curr_ent = prev_ent;
1.79 + prev_ent = tmp;
1.80 + curr_cost = prev_cost;
1.81 + }
1.82 + void saveAsBest() {
1.83 + *best_ent = *curr_ent;
1.84 + best_cost = curr_cost;
1.85 + }
1.86 + };
1.87 +
1.88 + class EntitySkeleton {
1.89 + public:
1.90 + // returns the new cost
1.91 + double mutate() { return 0.0; }
1.92 + };
1.93 +
1.94 + template <typename E>
1.95 + class SimAnn2 : public SimAnnBase {
1.96 + private:
1.97 + E *curr_ent;
1.98 + E *best_ent;
1.99 + public:
1.100 + SimAnn2() : SimAnnBase() {}
1.101 + void setEntity(E &Ent) {
1.102 + curr_ent = new E(Ent);
1.103 + best_ent = new E(Ent);
1.104 + }
1.105 + E getBestEntity() { return *best_ent; }
1.106 + void mutate() {
1.107 + curr_ent->mutate();
1.108 + }
1.109 + void revert() {
1.110 + curr_ent->revert();
1.111 + }
1.112 + void saveAsBest() {
1.113 + *best_ent = *curr_ent;
1.114 + best_cost = curr_cost;
1.115 + }
1.116 + };
1.117 +
1.118 + class EntitySkeleton2 {
1.119 + public:
1.120 + // returns the new cost
1.121 + double mutate() { return 0.0; }
1.122 + // restores the entity to its previous state i.e. reverts the effects of
1.123 + // the last mutate()
1.124 + void revert() {}
1.125 + };
1.126 +
1.127 +}
1.128 +
1.129 +#endif