src/work/akos/simann.h
author alpar
Mon, 01 Nov 2004 07:04:52 +0000
changeset 952 fa65d57f1930
parent 918 bb77eaa8fa0e
child 956 0ff924405d21
permissions -rw-r--r--
Traits + Named Parameters version
ladanyi@942
     1
#ifndef LEMON_SIMANN_H
ladanyi@942
     2
#define LEMON_SIMANN_H
ladanyi@918
     3
ladanyi@942
     4
namespace lemon {
ladanyi@918
     5
ladanyi@942
     6
  const double INFTY = 1e24;
ladanyi@918
     7
ladanyi@942
     8
  class SimAnnBase {
ladanyi@918
     9
  public:
ladanyi@942
    10
    class Controller;
ladanyi@942
    11
  private:
ladanyi@942
    12
    Controller *controller;
ladanyi@942
    13
  protected:
ladanyi@942
    14
    double curr_cost;
ladanyi@942
    15
    double prev_cost;
ladanyi@942
    16
    double best_cost;
ladanyi@918
    17
ladanyi@942
    18
    virtual void mutate() = 0;
ladanyi@942
    19
    virtual void revert() = 0;
ladanyi@942
    20
    virtual void saveAsBest() = 0;
ladanyi@942
    21
  public:
ladanyi@942
    22
    SimAnnBase() {
ladanyi@942
    23
      curr_cost = prev_cost = best_cost = INFTY;
ladanyi@942
    24
    }
ladanyi@942
    25
    void setController(Controller &_controller) { controller = &_controller; }
ladanyi@942
    26
    double getBestCost() { return best_cost; }
ladanyi@942
    27
    void run() {
ladanyi@942
    28
      while (controller->next()) {
ladanyi@942
    29
        mutate();
ladanyi@942
    30
        if (controller->accept(prev_cost - curr_cost)) {
ladanyi@942
    31
          controller->acceptEvent();
ladanyi@942
    32
          if (curr_cost < best_cost) {
ladanyi@942
    33
            saveAsBest();
ladanyi@942
    34
            controller->improveEvent();
ladanyi@942
    35
          }
ladanyi@942
    36
        }
ladanyi@942
    37
        else {
ladanyi@942
    38
          revert();
ladanyi@942
    39
          controller->rejectEvent();
ladanyi@942
    40
        }
ladanyi@918
    41
      }
ladanyi@918
    42
    }
ladanyi@918
    43
ladanyi@942
    44
    class Controller {
ladanyi@942
    45
    public:
ladanyi@942
    46
      virtual void acceptEvent() {}
ladanyi@942
    47
      virtual void improveEvent() {}
ladanyi@942
    48
      virtual void rejectEvent() {}
ladanyi@942
    49
      virtual bool next() = 0;
ladanyi@942
    50
      virtual bool accept(double cost_diff) = 0;
ladanyi@942
    51
    };
ladanyi@942
    52
  };
ladanyi@918
    53
ladanyi@942
    54
  template <typename E>
ladanyi@942
    55
  class SimAnn : public SimAnnBase {
ladanyi@942
    56
  private:
ladanyi@942
    57
    E *curr_ent;
ladanyi@942
    58
    E *prev_ent;
ladanyi@942
    59
    E *best_ent;
ladanyi@942
    60
  public:
ladanyi@942
    61
    SimAnn() : SimAnnBase() {}
ladanyi@942
    62
    void setEntity(E &Ent) {
ladanyi@942
    63
      curr_ent = new E(Ent);
ladanyi@942
    64
      prev_ent = new E(Ent);
ladanyi@942
    65
      best_ent = new E(Ent);
ladanyi@942
    66
    }
ladanyi@942
    67
    E getBestEntity() { return *best_ent; }
ladanyi@942
    68
    void mutate() {
ladanyi@942
    69
      *prev_ent = *curr_ent;
ladanyi@942
    70
      prev_cost = curr_cost;
ladanyi@942
    71
      curr_cost = curr_ent->mutate();
ladanyi@942
    72
    }
ladanyi@942
    73
    void revert() {
ladanyi@942
    74
      E *tmp = curr_ent;
ladanyi@942
    75
      curr_ent = prev_ent;
ladanyi@942
    76
      prev_ent = tmp;
ladanyi@942
    77
      curr_cost = prev_cost;
ladanyi@942
    78
    }
ladanyi@942
    79
    void saveAsBest() {
ladanyi@942
    80
      *best_ent = *curr_ent;
ladanyi@942
    81
      best_cost = curr_cost;
ladanyi@942
    82
    }
ladanyi@942
    83
  };
ladanyi@942
    84
ladanyi@942
    85
  class EntitySkeleton {
ladanyi@942
    86
  public:
ladanyi@942
    87
    // returns the new cost
ladanyi@942
    88
    double mutate() { return 0.0; }
ladanyi@942
    89
  };
ladanyi@942
    90
ladanyi@942
    91
  template <typename E>
ladanyi@942
    92
  class SimAnn2 : public SimAnnBase {
ladanyi@942
    93
  private:
ladanyi@942
    94
    E *curr_ent;
ladanyi@942
    95
    E *best_ent;
ladanyi@942
    96
  public:
ladanyi@942
    97
    SimAnn2() : SimAnnBase() {}
ladanyi@942
    98
    void setEntity(E &Ent) {
ladanyi@942
    99
      curr_ent = new E(Ent);
ladanyi@942
   100
      best_ent = new E(Ent);
ladanyi@942
   101
    }
ladanyi@942
   102
    E getBestEntity() { return *best_ent; }
ladanyi@942
   103
    void mutate() {
ladanyi@942
   104
      curr_ent->mutate();
ladanyi@942
   105
    }
ladanyi@942
   106
    void revert() {
ladanyi@942
   107
      curr_ent->revert();
ladanyi@942
   108
    }
ladanyi@942
   109
    void saveAsBest() {
ladanyi@942
   110
      *best_ent = *curr_ent;
ladanyi@942
   111
      best_cost = curr_cost;
ladanyi@942
   112
    }
ladanyi@942
   113
  };
ladanyi@942
   114
ladanyi@942
   115
  class EntitySkeleton2 {
ladanyi@942
   116
  public:
ladanyi@942
   117
    // returns the new cost
ladanyi@942
   118
    double mutate() { return 0.0; }
ladanyi@942
   119
    // restores the entity to its previous state i.e. reverts the effects of
ladanyi@942
   120
    // the last mutate()
ladanyi@942
   121
    void revert() {}
ladanyi@942
   122
  };
ladanyi@942
   123
ladanyi@942
   124
}
ladanyi@918
   125
ladanyi@918
   126
#endif