78d16c82f78911c7b42e4790b193dde72d2ab818
[satune.git] / src / Tuner / autotuner.cc
1 #include "autotuner.h"
2 #include "csolver.h"
3 #include "searchtuner.h"
4 #include <math.h>
5 #include <stdlib.h>
6 #include <float.h>
7
8 AutoTuner::AutoTuner(uint _budget) :
9         budget(_budget) {
10 }
11
12 void AutoTuner::addProblem(CSolver *solver) {
13         solvers.push(solver);
14 }
15
16 long long AutoTuner::evaluate(CSolver * problem, SearchTuner *tuner) {
17         CSolver * copy=problem->clone();
18         copy->setTuner(tuner);
19         int result = copy->startEncoding();
20         long long elapsedTime=copy->getElapsedTime();
21         long long encodeTime=copy->getEncodeTime();
22         long long solveTime=copy->getSolveTime();
23         long long metric=elapsedTime;
24         delete copy;
25         return metric;
26 }
27
28 double AutoTuner::evaluateAll(SearchTuner *tuner) {
29         double product=1;
30         for(uint i=0;i<solvers.getSize();i++) {
31                 CSolver * problem=solvers.get(i);
32                 double score=evaluate(problem, tuner);
33                 product*=score;
34         }
35         return pow(product, 1/((double)solvers.getSize()));
36 }
37
38 SearchTuner * AutoTuner::mutateTuner(SearchTuner * oldTuner, uint k) {
39         SearchTuner *newTuner=oldTuner->copyUsed();
40         uint numSettings=oldTuner->getSize();
41         double factor=0.3;//Adjust this factor...
42         uint settingsToMutate=(uint)(factor*(((double)numSettings) * k)/(budget));
43         if (settingsToMutate < 1)
44                 settingsToMutate=1;
45         model_print("Mutating %u settings\n", settingsToMutate);
46         while(settingsToMutate-- != 0) {
47                 newTuner->randomMutate();
48         }
49         return newTuner;
50 }
51
52
53 void AutoTuner::tune() {
54         SearchTuner * bestTuner = NULL;
55         double bestScore=DBL_MAX;
56
57         SearchTuner * oldTuner=new SearchTuner();
58         double base_temperature=evaluateAll(oldTuner);
59         double oldScore=base_temperature;
60
61         for (uint i=0;i<budget;i++) {
62                 SearchTuner *newTuner=mutateTuner(oldTuner, i);
63                 double newScore=evaluateAll(newTuner);
64                 double scoreDiff=newScore - oldScore; //smaller is better
65                 if (newScore < bestScore) {
66                         bestScore = newScore;
67                         bestTuner = newTuner->copyUsed();
68                 }
69
70                 double acceptanceP;
71                 if (scoreDiff < 0) {
72                         acceptanceP = 1;
73                 } else {
74                         double currTemp=base_temperature * (((double)budget - i) / budget);
75                         acceptanceP = exp(-scoreDiff / currTemp);
76                 }
77                 double ran = ((double)random()) / RAND_MAX;
78                 if (ran <= acceptanceP) {
79                         oldScore = newScore;
80                         oldTuner = newTuner;
81                 } else {
82                         delete newTuner;
83                 }
84         }
85 }