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