ladanyi@942: #ifndef LEMON_SIMANN_H ladanyi@942: #define LEMON_SIMANN_H ladanyi@918: ladanyi@942: namespace lemon { ladanyi@918: ladanyi@942: const double INFTY = 1e24; ladanyi@918: ladanyi@942: class SimAnnBase { ladanyi@918: public: ladanyi@942: class Controller; ladanyi@942: private: ladanyi@942: Controller *controller; ladanyi@942: protected: ladanyi@942: double curr_cost; ladanyi@942: double prev_cost; ladanyi@942: double best_cost; ladanyi@918: ladanyi@942: virtual void mutate() = 0; ladanyi@942: virtual void revert() = 0; ladanyi@942: virtual void saveAsBest() = 0; ladanyi@942: public: ladanyi@942: SimAnnBase() { ladanyi@942: curr_cost = prev_cost = best_cost = INFTY; ladanyi@942: } ladanyi@942: void setController(Controller &_controller) { controller = &_controller; } ladanyi@942: double getBestCost() { return best_cost; } ladanyi@942: void run() { ladanyi@942: while (controller->next()) { ladanyi@942: mutate(); ladanyi@942: if (controller->accept(prev_cost - curr_cost)) { ladanyi@942: controller->acceptEvent(); ladanyi@942: if (curr_cost < best_cost) { ladanyi@942: saveAsBest(); ladanyi@942: controller->improveEvent(); ladanyi@942: } ladanyi@942: } ladanyi@942: else { ladanyi@942: revert(); ladanyi@942: controller->rejectEvent(); ladanyi@942: } ladanyi@918: } ladanyi@918: } ladanyi@918: ladanyi@942: class Controller { ladanyi@942: public: ladanyi@942: virtual void acceptEvent() {} ladanyi@942: virtual void improveEvent() {} ladanyi@942: virtual void rejectEvent() {} ladanyi@942: virtual bool next() = 0; ladanyi@942: virtual bool accept(double cost_diff) = 0; ladanyi@942: }; ladanyi@942: }; ladanyi@918: ladanyi@942: template ladanyi@942: class SimAnn : public SimAnnBase { ladanyi@942: private: ladanyi@942: E *curr_ent; ladanyi@942: E *prev_ent; ladanyi@942: E *best_ent; ladanyi@942: public: ladanyi@942: SimAnn() : SimAnnBase() {} ladanyi@942: void setEntity(E &Ent) { ladanyi@942: curr_ent = new E(Ent); ladanyi@942: prev_ent = new E(Ent); ladanyi@942: best_ent = new E(Ent); ladanyi@942: } ladanyi@942: E getBestEntity() { return *best_ent; } ladanyi@942: void mutate() { ladanyi@942: *prev_ent = *curr_ent; ladanyi@942: prev_cost = curr_cost; ladanyi@942: curr_cost = curr_ent->mutate(); ladanyi@942: } ladanyi@942: void revert() { ladanyi@942: E *tmp = curr_ent; ladanyi@942: curr_ent = prev_ent; ladanyi@942: prev_ent = tmp; ladanyi@942: curr_cost = prev_cost; ladanyi@942: } ladanyi@942: void saveAsBest() { ladanyi@942: *best_ent = *curr_ent; ladanyi@942: best_cost = curr_cost; ladanyi@942: } ladanyi@942: }; ladanyi@942: ladanyi@942: class EntitySkeleton { ladanyi@942: public: ladanyi@942: // returns the new cost ladanyi@942: double mutate() { return 0.0; } ladanyi@942: }; ladanyi@942: ladanyi@942: template ladanyi@942: class SimAnn2 : public SimAnnBase { ladanyi@942: private: ladanyi@942: E *curr_ent; ladanyi@942: E *best_ent; ladanyi@942: public: ladanyi@942: SimAnn2() : SimAnnBase() {} ladanyi@942: void setEntity(E &Ent) { ladanyi@942: curr_ent = new E(Ent); ladanyi@942: best_ent = new E(Ent); ladanyi@942: } ladanyi@942: E getBestEntity() { return *best_ent; } ladanyi@942: void mutate() { ladanyi@942: curr_ent->mutate(); ladanyi@942: } ladanyi@942: void revert() { ladanyi@942: curr_ent->revert(); ladanyi@942: } ladanyi@942: void saveAsBest() { ladanyi@942: *best_ent = *curr_ent; ladanyi@942: best_cost = curr_cost; ladanyi@942: } ladanyi@942: }; ladanyi@942: ladanyi@942: class EntitySkeleton2 { ladanyi@942: public: ladanyi@942: // returns the new cost ladanyi@942: double mutate() { return 0.0; } ladanyi@942: // restores the entity to its previous state i.e. reverts the effects of ladanyi@942: // the last mutate() ladanyi@942: void revert() {} ladanyi@942: }; ladanyi@942: ladanyi@942: } ladanyi@918: ladanyi@918: #endif