00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #ifndef _ANNEAL_H
00028 #define _ANNEAL_H
00029
00030 #include <stdlib.h>
00031 #include <iostream>
00032 #include <vector>
00033
00034 using namespace std;
00035
00037 typedef double MyNT;
00038
00039
00040 const MyNT DEFAULT_START_TEMPERATURE = 100;
00041 const MyNT DEFAULT_END_TEMPERATURE = 1E-5;
00042 const unsigned int DEFAULT_NUM_ITERATIONS = 10000;
00043
00044 const MyNT DEFAULT_DROP_TEMPERATURE = pow(DEFAULT_START_TEMPERATURE/DEFAULT_END_TEMPERATURE, 1.0/DEFAULT_NUM_ITERATIONS);
00045
00046
00069 class MyAbstractAnnealState
00070 {
00071 private:
00072 MyNT _score;
00073
00074 public:
00076 MyAbstractAnnealState()
00077 : _score(0)
00078 {}
00079
00080 virtual ~MyAbstractAnnealState()
00081 {}
00082
00085 MyAbstractAnnealState &operator=(const MyAbstractAnnealState &rhs);
00086
00091 virtual void computeRandomNeighbour(MyAbstractAnnealState &neighbour) = 0;
00092
00093
00095 virtual MyNT computeScore() const = 0;
00096
00098 virtual void print(ostream &ostr) const = 0;
00099
00101 virtual void undo() = 0;
00102
00103 };
00104
00105
00106
00113 template <typename AnnealState >
00114 class MySimulatedAnnealer {
00115 protected:
00116
00117
00118 MyNT _startTemperature;
00119 MyNT _endTemperature;
00120
00121 MyNT _dropTemperature;
00122 unsigned int _numMaxIterations;
00123 unsigned int _numMaxIterationsWithoutImprovement;
00124
00125 MyNT _bestScore;
00126 MyNT _currentTemperature;
00127 unsigned int _numTotalIterations;
00128 unsigned int _numIterationsWithScoreDecrease;
00129 unsigned int _numIterationsWithoutImprovement;
00130
00131 AnnealState _startState;
00132 AnnealState _currentState;
00133
00134
00135
00136
00137
00138
00139
00140 public:
00141 MySimulatedAnnealer()
00142 :
00143 _startTemperature(DEFAULT_START_TEMPERATURE),
00144 _endTemperature(DEFAULT_END_TEMPERATURE),
00145 _dropTemperature(DEFAULT_DROP_TEMPERATURE),
00146 _numMaxIterations(DEFAULT_NUM_ITERATIONS),
00147 _numMaxIterationsWithoutImprovement(100),
00148 _bestScore(0), _currentTemperature(_startTemperature),
00149 _numTotalIterations(0), _numIterationsWithScoreDecrease(0),
00150 _numIterationsWithoutImprovement(0),
00151 _startState(), _currentState()
00152
00153
00154 {
00155 }
00156
00157 MySimulatedAnnealer(const AnnealState &s)
00158 : _startTemperature(DEFAULT_START_TEMPERATURE),
00159 _endTemperature(DEFAULT_END_TEMPERATURE),
00160 _dropTemperature(DEFAULT_DROP_TEMPERATURE),
00161 _numMaxIterations(DEFAULT_NUM_ITERATIONS),
00162 _numMaxIterationsWithoutImprovement(100),
00163 _bestScore(0), _currentTemperature(_startTemperature),
00164 _numTotalIterations(0), _numIterationsWithScoreDecrease(0),
00165 _numIterationsWithoutImprovement(0),
00166 _startState(s), _currentState()
00167
00168
00169 {
00170 }
00171
00172 virtual ~MySimulatedAnnealer()
00173 {
00174 }
00175
00176 bool acceptNeighbour(MyNT score)
00177 {
00178 if (score > _bestScore)
00179 return(true);
00180
00181 MyNT prob = (score - _bestScore)/_currentTemperature;
00182 prob = exp(prob);
00183 MyNT sample = random()*1.0/RAND_MAX;
00184 if (sample <= prob)
00185 return(true);
00186 return(false);
00187 }
00188
00189 MyNT computeBestScore(const vector< AnnealState > &neighbours,
00190 AnnealState &bestNeighbour)
00191 {
00192 typename vector< AnnealState >::const_iterator aitr = neighbours.begin();
00193 MyNT score = aitr->computeScore();
00194 bestNeighbour = *aitr;
00195 MyNT currentScore;
00196
00197 for (; aitr != neighbours.end(); aitr++)
00198 {
00199 currentScore = aitr->computeScore();
00200 if (currentScore > score)
00201 {
00202 score = currentScore;
00203 bestNeighbour = *aitr;
00204 }
00205 }
00206 return(score);
00207 }
00208
00209 void decreaseTemperature()
00210 {
00211 _currentTemperature /= _dropTemperature;
00212 }
00213
00214 void getFinalState(AnnealState &finalState) const
00215 {
00216 finalState = _currentState;
00217 }
00218
00219 void initialise()
00220 {
00221 _bestScore = 0;
00222 _currentTemperature = DEFAULT_START_TEMPERATURE;
00223 _numTotalIterations = 0;
00224 _numIterationsWithoutImprovement = 0;
00225 _currentState = _startState;
00226
00227 }
00228
00230 bool isDone()
00231 {
00232 if (_numMaxIterations == _numTotalIterations)
00233
00234 return(true);
00235 return(false);
00236 }
00237
00239 void setNumTotalIterations(unsigned int num)
00240 {
00241 _numMaxIterations = num;
00242
00243 _dropTemperature = pow(_startTemperature/_endTemperature, 1.0/_numMaxIterations);
00244 }
00245
00247 void run()
00248 {
00249 MyNT score;
00250 initialise();
00251 AnnealState neighbour;
00252
00253
00254 score = _startState.computeScore();
00255
00256 while (true)
00257 {
00258
00259
00260
00261
00262
00263
00264
00265
00266 _currentState.computeRandomNeighbour(neighbour);
00267
00268 score = neighbour.computeScore();
00269
00270 if (acceptNeighbour(score))
00271 {
00272 _currentState = neighbour;
00273
00274 if (_bestScore > score)
00275
00276 _numIterationsWithScoreDecrease++;
00277 _bestScore = score;
00278 _numIterationsWithoutImprovement = 0;
00279 }
00280 else
00281 {
00282
00291 neighbour.undo();
00292 _numIterationsWithoutImprovement++;
00293 }
00294
00295
00296
00297 decreaseTemperature();
00298 _numTotalIterations++;
00299
00300 if (0 == (_numTotalIterations%10000))
00301 {
00302 cout << "\t" << _numTotalIterations
00303 << "\t" << _numIterationsWithScoreDecrease
00304 << "\t" << _numIterationsWithScoreDecrease*1.0/_numTotalIterations;
00305 _currentState.print(cout);
00306 }
00307
00308
00309 if (isDone())
00310 {
00311 #ifdef DEBUG
00312 _currentState.print(cout);
00313
00314 #endif // DEBUG
00315 break;
00316 }
00317 }
00318 }
00319
00321 void setInitialState(AnnealState &s)
00322 {
00323 _startState = s;
00324 }
00325
00326 };
00327
00328
00329 #endif // _ANNEAL_H