Index: src/work/akos/SimAnn.h
===================================================================
--- src/work/akos/SimAnn.h	(revision 918)
+++ src/work/akos/SimAnn.h	(revision 918)
@@ -0,0 +1,103 @@
+#ifndef SIMANN_H
+#define SIMANN_H
+
+#ifndef INFTY
+#define INFTY 1e24
+#endif
+
+#include <iostream>
+
+class SimAnnBase {
+public:
+  friend class Controller;
+  class Controller {
+  public:
+    SimAnnBase *sab;
+    double T;
+    void init(SimAnnBase *_sab) { sab = _sab; }
+    bool next() {}
+    bool accept(double cost) {}
+  };
+protected:
+  double CurrCost;
+  double PrevCost;
+  double BestCost;
+
+  long Iter;
+  long LastImpr;
+
+  //friend class Controller;
+  Controller *Ctrl;
+public:
+  long getIter() { return Iter; }
+  long getLastImpr() { return LastImpr; }
+  double getBestCost() { return BestCost; }
+  virtual void mutate() = 0;
+  virtual void revert() = 0;
+  virtual void saveAsBest() = 0;
+  virtual void init() = 0;
+
+  void run() {
+    init();
+    while (Ctrl->next()) {
+      Iter++;
+      std::cout << Iter << std::endl;
+      mutate();
+      if (Ctrl->accept(PrevCost - CurrCost) && (CurrCost < BestCost)) {
+	LastImpr = Iter;
+        saveAsBest();
+      }
+      else {
+        revert();
+      }
+    }
+  }
+};
+
+template <typename E>
+class SimAnn : public SimAnnBase {
+private:
+  E *CurrEnt;
+  E *PrevEnt;
+  E *BestEnt;
+public:
+  SimAnn() {
+    CurrCost = PrevCost = BestCost = INFTY;
+    Iter = LastImpr = 0;
+  }
+  void setController(Controller &_Ctrl) { Ctrl = &_Ctrl; }
+  void setEnt(E &Ent) {
+    CurrEnt = new E(Ent);
+    PrevEnt = new E(Ent);
+    BestEnt = new E(Ent);
+  }
+  E getBestEnt() { return *BestEnt; }
+  void mutate() {
+    *PrevEnt = *CurrEnt;
+    PrevCost = CurrCost;
+    CurrCost = CurrEnt->mutate();
+  }
+  void revert() {
+    E *tmp = CurrEnt;
+    CurrEnt = PrevEnt;
+    PrevEnt = tmp;
+    CurrCost = PrevCost;
+  }
+  void saveAsBest() {
+    *BestEnt = *CurrEnt;
+    BestCost = CurrCost;
+  }
+  void init() {
+    Ctrl->init(this);
+    CurrEnt->init();
+  }
+};
+
+class EntitySkeleton {
+public:
+  void init() {}
+  // returns the new cost
+  double mutate() { return 0.0; }
+};
+
+#endif
Index: src/work/akos/simann_test.cc
===================================================================
--- src/work/akos/simann_test.cc	(revision 918)
+++ src/work/akos/simann_test.cc	(revision 918)
@@ -0,0 +1,39 @@
+#include "SimAnn.h"
+#include <cstdlib>
+#include <cmath>
+#include <iostream>
+
+class MyController : public SimAnnBase::Controller {
+public:
+  long MaxIter, MaxNoImpr;
+  double af;
+  MyController() {
+    MaxIter = 500000;
+    MaxNoImpr = 20000;
+    af = 0.9999;
+    T = 1000;
+  }
+  bool next() {
+    T *= af;
+    std::cout << T << std::endl;
+    return !((sab->getIter() > MaxIter) || (sab->getIter() - sab->getLastImpr() > MaxNoImpr));
+  }
+  bool accept(double cost) {
+    return (drand48() <= exp(cost / T));
+  }
+};
+
+class MyEntity {
+public:
+  void init() {}
+  double mutate() { return 10.0; }
+};
+
+int main() {
+  SimAnn<MyEntity> sa;
+  MyController c;
+  sa.setController(c);
+  MyEntity ent;
+  sa.setEnt(ent);
+  sa.run();
+}
