Bug Fix
[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->solve();
20         model_print("SAT %d\n", result);
21         long long elapsedTime = copy->getElapsedTime();
22         long long encodeTime = copy->getEncodeTime();
23         long long solveTime = copy->getSolveTime();
24         long long metric = elapsedTime;
25         model_print("Elapsed Time: %llu\n", elapsedTime);
26         model_print("Encode Time: %llu\n", encodeTime);
27         model_print("Solve Time: %llu\n", solveTime);
28         delete copy;
29         return metric;
30 }
31
32 double AutoTuner::evaluateAll(SearchTuner *tuner) {
33         double product = 1;
34         for (uint i = 0; i < solvers.getSize(); i++) {
35                 CSolver *problem = solvers.get(i);
36                 double score = evaluate(problem, tuner);
37                 product *= score;
38         }
39         return pow(product, 1 / ((double)solvers.getSize()));
40 }
41
42 SearchTuner *AutoTuner::mutateTuner(SearchTuner *oldTuner, uint k) {
43         SearchTuner *newTuner = oldTuner->copyUsed();
44         uint numSettings = oldTuner->getSize();
45         double factor = 0.3;//Adjust this factor...
46         uint settingsToMutate = (uint)(factor * (((double)numSettings) * (budget - k)) / (budget));
47         if (settingsToMutate < 1)
48                 settingsToMutate = 1;
49         model_print("Mutating %u settings\n", settingsToMutate);
50         while (settingsToMutate-- != 0) {
51                 newTuner->randomMutate();
52         }
53         return newTuner;
54 }
55
56
57 void AutoTuner::tune() {
58         SearchTuner *bestTuner = NULL;
59         double bestScore = DBL_MAX;
60
61         SearchTuner *oldTuner = new SearchTuner();
62         double base_temperature = evaluateAll(oldTuner);
63         double oldScore = base_temperature;
64
65         for (uint i = 0; i < budget; i++) {
66                 SearchTuner *newTuner = mutateTuner(oldTuner, i);
67                 double newScore = evaluateAll(newTuner);
68                 newTuner->printUsed();
69                 model_print("Received score %f\n", newScore);
70                 double scoreDiff = newScore - oldScore; //smaller is better
71                 if (newScore < bestScore) {
72                         if (bestTuner != NULL)
73                                 delete bestTuner;
74                         bestScore = newScore;
75                         bestTuner = newTuner->copyUsed();
76                 }
77
78                 double acceptanceP;
79                 if (scoreDiff < 0) {
80                         acceptanceP = 1;
81                 } else {
82                         double currTemp = base_temperature * (((double)budget - i) / budget);
83                         acceptanceP = exp(-scoreDiff / currTemp);
84                 }
85                 double ran = ((double)random()) / RAND_MAX;
86                 if (ran <= acceptanceP) {
87                         delete oldTuner;
88                         oldScore = newScore;
89                         oldTuner = newTuner;
90                 } else {
91                         delete newTuner;
92                 }
93         }
94         model_print("Best tuner:\n");
95         bestTuner->print();
96         model_print("Received score %f\n", bestScore);
97         if (bestTuner != NULL)
98                 delete bestTuner;
99         delete oldTuner;
100 }