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