00001 #ifndef TESTMODULE_HPP_
00002 #define TESTMODULE_HPP_
00003
00004 #include "../OptFrameModule.hpp"
00005 #include <math.h>
00006
00007 template<class R, class M>
00008 class TestModule: public OptFrameModule<R, M>
00009 {
00010 public:
00011 string id()
00012 {
00013 return "test";
00014 }
00015 string usage()
00016 {
00017 string u = "test N T TF BF ISG EVAL METHOD OUTPUTFILE [solution_name]\n WHERE:\n";
00018 u += "N is the number of tests to be executed;\n";
00019 u += "T is the timelimit, in seconds, for each test; (0 for no timelimit)\n";
00020 u += "TF is the target evaluation function value;\n";
00021 u += "BF is the best known evaluation function value;\n";
00022 u += "ISG is the initial solution generator; (e.g. initsol 0)\n";
00023 u += "EVAL is the main evaluator; (e.g. ev 0)\n";
00024 u += "METHOD is the method to be tested with its own parameters;\n";
00025 u += "OUTPUTFILE is the output file;\n";
00026 u += "[solution_name] is a name given to the best found solution (optional).";
00027
00028 return u;
00029 }
00030
00031 void run(vector<OptFrameModule<R, M>*> all_modules, HeuristicFactory<R, M>* factory, map<string, string>* dictionary, string input)
00032 {
00033 Scanner scanner(input);
00034
00035 if (!scanner.hasNext())
00036 {
00037 cout << "Usage: " << usage() << endl;
00038 return;
00039 }
00040
00041 int n = scanner.nextInt();
00042 int t = scanner.nextDouble();
00043 double tf = scanner.nextDouble();
00044 double bf = scanner.nextDouble();
00045 InitialSolution<R>* initsol = factory->read_initsol(&scanner);
00046 Evaluator<R, M>* eval = factory->read_ev(&scanner);
00047 pair<Heuristic<R, M>*, string> method = factory->createHeuristic(scanner.rest());
00048
00049 Heuristic<R, M>* h = method.first;
00050
00051 string rest = method.second;
00052
00053 Scanner scan_rest(rest);
00054
00055 string filename = scan_rest.next();
00056
00057 if (t == 0)
00058 t = 1000000000;
00059
00060 long timelimit = t;
00061
00062 if (bf == 0)
00063 bf = 0.00001;
00064
00065 FILE* file = fopen(filename.c_str(), "a");
00066 if (!file)
00067 {
00068 cout << "Error creating file '" << filename << "'" << endl;
00069 return;
00070 }
00071
00072 fprintf(file, "PARAMETERS:%s\n", input.c_str());
00073
00074 bool minimization = eval->betterThan(1, 2);
00075 Solution<R>* s_star = NULL;
00076
00077 double s_fo_ini = 0;
00078 double s_t_ini = 0;
00079 double s_fo_end = 0;
00080 double s_t_end = 0;
00081 double min_fo = 1000000000;
00082 double min_t = 1000000000;
00083 double max_fo = -1000000000;
00084 double max_t = -1000000000;
00085
00086 double t_now = 0;
00087 double fo_now = 0;
00088 double variance = 0;
00089
00090 vector<long double> s_fo_tests(n);
00091
00092 for (int i = 0; i < n; i++)
00093 {
00094 long seed = time(NULL) + i;
00095 fprintf(file, "%ld\t", seed);
00096
00097 cout << "Test " << i << " {seed=" << seed << "}... Running";
00098 Timer t(false);
00099
00100 Solution<R>* s = &initsol->generateSolution();
00101 t_now = t.now();
00102 fo_now = eval->evaluate(*s).evaluation();
00103 fprintf(file, "%.3f\t%.3f\t", fo_now, t_now);
00104 s_fo_ini += fo_now;
00105 s_t_ini += t_now;
00106
00107 Solution<R>* s2 = &h->search(*s, timelimit, tf);
00108 t_now = t.now();
00109 fo_now = eval->evaluate(*s2).evaluation();
00110 s_fo_tests.at(i) = fo_now;
00111 fprintf(file, "%.3f\t%.3f\t", fo_now, t_now);
00112 s_fo_end += fo_now;
00113 s_t_end += t_now;
00114
00115 if (fo_now < min_fo)
00116 min_fo = fo_now;
00117 if (t_now < min_t)
00118 min_t = t_now;
00119 if (fo_now > max_fo)
00120 max_fo = fo_now;
00121 if (t_now > max_t)
00122 max_t = t_now;
00123
00124 cout << "... Finished! (" << t.now() << "secs.)" << endl;
00125
00126 if (!s_star)
00127 s_star = &s2->clone();
00128 else if (eval->betterThan(*s2, *s_star))
00129 {
00130 delete s_star;
00131 s_star = &s2->clone();
00132 }
00133
00134 delete s;
00135 delete s2;
00136
00137 fprintf(file, "\n");
00138 }
00139
00140 s_fo_ini /= n;
00141 s_t_ini /= n;
00142 s_fo_end /= n;
00143 s_t_end /= n;
00144
00145
00146 for (int i = 0; i < n; i++)
00147 {
00148 variance += pow((s_fo_end - s_fo_tests[i]), 2);
00149 }
00150 variance /= (n * 1.0);
00151
00152 fprintf(file, "AVERAGE:\t%f\t%f\t%f\t%f\n", s_fo_ini, s_t_ini, s_fo_end, s_t_end);
00153 fprintf(file, "MIN:\t-\t-\t%f\t%f\n", min_fo, min_t);
00154 fprintf(file, "MAX:\t-\t-\t%f\t%f\n", max_fo, max_t);
00155 if (min_fo == 0)
00156 min_fo = 0.00001;
00157 fprintf(file, "VARIABILITY:\t-\t-\t%f\t-\n", (s_fo_end - min_fo) / min_fo);
00158 fprintf(file, "VARIANCE: \t-\t-\t%f\t-\n", variance);
00159 fprintf(file, "STANDARD DEVIATION : \t-\t-\t%f\t-\n", sqrt(variance));
00160 fprintf(file, "GAP_FROM_BEST:\t%f\t-\t%f\t-\n", (s_fo_ini - bf) / bf, (s_fo_end - bf) / bf);
00161 fprintf(file, "GAP_FROM_AVG:\t%f\t-\t%f\t-\n", (s_fo_ini - bf) / s_fo_ini, (s_fo_end - bf) / s_fo_end);
00162 fprintf(file, "IMPROVEMENT:\t-\t-\t%f\t-\n", (bf - min_fo) / bf);
00163 fprintf(file, "BEST(LIT):\t%f\n", bf);
00164
00165 fclose(file);
00166
00167 int new_id = factory->add_loadsol(s_star);
00168
00169 stringstream str;
00170 str << "loadsol " << new_id;
00171 string s_new_id = str.str();
00172
00173 cout << "'" << s_new_id << "' added." << endl;
00174
00175 if (scan_rest.hasNext())
00176 {
00177 string new_name = scan_rest.next();
00178 run_module("define", all_modules, factory, dictionary, new_name + " " + s_new_id);
00179 }
00180 }
00181
00182 };
00183
00184 #endif