crown
1.0.0
|
00001 /* 00002 Copyright 2015 Nicolas Melot 00003 00004 This file is part of Crown. 00005 00006 Crown is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 Crown is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with Crown. If not, see <http://www.gnu.org/licenses/>. 00018 00019 */ 00020 00021 00022 #include <fstream> 00023 00024 #include <pelib/argument_parsing.hpp> 00025 #include <pelib/dl.h> 00026 #include <pelib/Scalar.hpp> 00027 00028 #include <crown/CrownModular.hpp> 00029 #include <crown/CrownCompositeAnnealing.hpp> 00030 00031 #ifdef debug 00032 #undef debug 00033 #endif 00034 00035 #define debug(var) cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << endl; 00036 00037 using namespace std; 00038 using namespace pelib; 00039 using namespace crown; 00040 00041 #ifdef __cplusplus 00042 extern "C" { 00043 #endif 00044 00045 struct args 00046 { 00047 double alpha, eta, zeta, kappa; 00048 pelib_argument_stream mapping, scaling; 00049 vector<pelib_argument_stream> composite; 00050 bool showError, showOutput; 00051 float init_temp, cooling, temp_final, max_trans, max_new, distance; 00052 }; 00053 typedef struct args args_t; 00054 00055 static args_t 00056 parse(char **args) 00057 { 00058 args_t out; 00059 out.showError = false; 00060 out.showOutput = false; 00061 out.alpha = 3; 00062 out.zeta = 0.649; 00063 out.eta = 0.018611; 00064 out.kappa = 52.639161335; 00065 00066 out.init_temp = 8; 00067 out.cooling = 0.6; 00068 out.temp_final = 0.9; 00069 out.max_trans = 2; 00070 out.max_new = 2; 00071 out.distance = 0.5; 00072 00073 pelib_argument_stream_init(&out.mapping); 00074 pelib_argument_stream_init(&out.scaling); 00075 00076 for(; args[0] != NULL; args++) 00077 { 00078 if(strcmp(args[0], "--show-stdout") == 0) 00079 { 00080 out.showOutput = true; 00081 continue; 00082 } 00083 if(strcmp(args[0], "--show-stderr") == 0) 00084 { 00085 out.showError = true; 00086 continue; 00087 } 00088 if(strcmp(args[0], "--alpha") == 0) 00089 { 00090 args++; 00091 stringstream str(args[0]); 00092 str >> out.alpha; 00093 continue; 00094 } 00095 if(strcmp(args[0], "--eta") == 0) 00096 { 00097 args++; 00098 stringstream str(args[0]); 00099 str >> out.eta; 00100 continue; 00101 } 00102 if(strcmp(args[0], "--zeta") == 0) 00103 { 00104 args++; 00105 stringstream str(args[0]); 00106 str >> out.zeta; 00107 continue; 00108 } 00109 if(strcmp(args[0], "--kappa") == 0) 00110 { 00111 args++; 00112 stringstream str(args[0]); 00113 str >> out.kappa; 00114 continue; 00115 } 00116 if(strcmp(args[0], "--init-temperature") == 0) 00117 { 00118 args++; 00119 stringstream str(args[0]); 00120 str >> out.init_temp; 00121 continue; 00122 } 00123 if(strcmp(args[0], "--cooling-factor") == 0) 00124 { 00125 args++; 00126 stringstream str(args[0]); 00127 str >> out.cooling; 00128 continue; 00129 } 00130 if(strcmp(args[0], "--final-temperature") == 0) 00131 { 00132 args++; 00133 stringstream str(args[0]); 00134 str >> out.temp_final; 00135 continue; 00136 } 00137 if(strcmp(args[0], "--max-transformations") == 0) 00138 { 00139 args++; 00140 stringstream str(args[0]); 00141 str >> out.max_trans; 00142 continue; 00143 } 00144 if(strcmp(args[0], "--max-new-state") == 0) 00145 { 00146 args++; 00147 stringstream str(args[0]); 00148 str >> out.max_new; 00149 continue; 00150 } 00151 if(strcmp(args[0], "--distance") == 0) 00152 { 00153 args++; 00154 stringstream str(args[0]); 00155 str >> out.distance; 00156 continue; 00157 } 00158 if(strcmp(args[0], "--mapping") == 0) 00159 { 00160 args++; 00161 args += pelib_argument_stream_parse(args, &out.mapping) - 1; 00162 continue; 00163 } 00164 if(strcmp(args[0], "--scaling") == 0) 00165 { 00166 args++; 00167 args += pelib_argument_stream_parse(args, &out.scaling) - 1; 00168 continue; 00169 } 00170 if(strcmp(args[0], "--composite") == 0) 00171 { 00172 args++; 00173 pelib_argument_stream compo; 00174 pelib_argument_stream_init(&compo); 00175 args += pelib_argument_stream_parse(args, &compo) - 1; 00176 out.composite.push_back(compo); 00177 continue; 00178 } 00179 } 00180 00181 return out; 00182 } 00183 00184 const CrownScheduler* 00185 crown_scheduler(size_t argc, char **argv, const CrownScheduler *composite) 00186 { 00187 args_t args = parse(argv); 00188 Algebra param; 00189 param.insert(new Scalar<float>("alpha", args.alpha)); 00190 param.insert(new Scalar<float>("eta", args.eta)); 00191 param.insert(new Scalar<float>("zeta", args.zeta)); 00192 param.insert(new Scalar<float>("kappa", args.kappa)); 00193 00194 void *libMapping = load_lib(args.mapping.library); 00195 void *libScaling = load_lib(args.scaling.library); 00196 CrownMapping* (*map)(size_t argc, char **argv); 00197 CrownScaling* (*scal)(size_t argc, char **argv); 00198 CrownMapping* mapping = NULL; 00199 CrownScaling* scaling = NULL; 00200 00201 // Load crown mapping 00202 if(args.mapping.library != NULL) 00203 { 00204 void *libConfig = load_lib(args.mapping.library); 00205 map = (CrownMapping* (*)(size_t argc, char **argv))load_function(libConfig, "crown_mapping"); 00206 mapping = map(args.mapping.argc, args.mapping.argv); 00207 } 00208 00209 // Load crown scaling 00210 if(args.scaling.library != NULL) 00211 { 00212 void *libConfig = load_lib(args.scaling.library); 00213 scal = (CrownScaling* (*)(size_t argc, char **argv))load_function(libConfig, "crown_scaling"); 00214 scaling = scal(args.scaling.argc, args.scaling.argv); 00215 } 00216 00217 const CrownScheduler *scheduler = composite; 00218 for(vector<pelib_argument_stream>::iterator i = args.composite.begin(); i != args.composite.end(); i++) 00219 { 00220 pelib_argument_stream compo = *i; 00221 void *libCompo = load_lib(compo.library); 00222 const CrownScheduler* (*sched)(size_t argc, char **argv, const CrownScheduler*) = (const CrownScheduler* (*)(size_t argc, char **argv, const CrownScheduler*))load_function(libCompo, "crown_scheduler"); 00223 const CrownScheduler *new_scheduler = sched(compo.argc, compo.argv, scheduler); 00224 if(scheduler != NULL) 00225 { 00226 delete scheduler; 00227 } 00228 scheduler = new_scheduler->clone(); 00229 void (*del)(const CrownScheduler*) = (void (*)(const CrownScheduler*))load_function(libCompo, "crown_delete_scheduler"); 00230 del(new_scheduler); 00231 destroy_lib(libCompo); 00232 } 00233 00234 // Final scheduler 00235 CrownScheduler *final = new CrownCompositeAnnealing(param, args.init_temp, args.cooling, args.temp_final, args.max_trans, args.max_new, args.distance, scheduler, mapping, scaling, args.showOutput, args.showError); 00236 00237 // Destroy object instances by libraries 00238 if(args.mapping.library != NULL) 00239 { 00240 void (*del)(CrownMapping *) = (void (*)(CrownMapping*))load_function(libMapping, "crown_delete_algebra"); 00241 del(mapping); 00242 destroy_lib(libMapping); 00243 } 00244 00245 // Destroy object instances by libraries 00246 if(args.scaling.library != NULL) 00247 { 00248 void (*del)(CrownScaling *) = (void (*)(CrownScaling*))load_function(libScaling, "crown_delete_algebra"); 00249 del(scaling); 00250 destroy_lib(libScaling); 00251 } 00252 00253 return final; 00254 } 00255 00256 #ifdef __cplusplus 00257 } 00258 #endif 00259