00001
00020 #include "cmaesb.h"
00021
00022 using namespace realea;
00023 using namespace realea::internal;
00024
00025 CMAESBound::CMAESBound(IEvalReal *eval, DomainRealPtr domain) :
00026 m_eval(eval), m_domain(domain), m_avanzed(true), m_ndim(domain->getDimension()),
00027 m_diagC(m_ndim), m_scale(m_ndim), m_weights(m_ndim), m_dfithist() {
00028 m_validfitval = 0;
00029 m_numapplied = 0;
00030
00031 m_isactive = m_domain->isBound();
00032
00033 if (!m_isactive) {
00034 return;
00035 }
00036
00037 m_weights = 0;
00038 Real meanC = mean(m_diagC);
00039 m_scale = m_diagC/meanC;
00040 }
00041
00042 void CMAESBound::setParam(int lambda, double mueff, ColumnVector &sigma, MyMatrix &C) {
00043 m_lambda = lambda;
00044 m_mueff = mueff;
00045 m_sigma = sigma;
00046 m_dfithist_size = 20+(3*m_ndim)/lambda;
00047 m_dfithist.push(1.0);
00048
00049 DiagonalMatrix DiagC(m_ndim);
00050 DiagC <<C;
00051 copyColumn(DiagC, m_diagC);
00052 }
00053
00054
00055 MyReturnMatrix xintobounds(const ColumnVector &mat, DomainRealPtr domain, vector<int> *corrected) {
00056 Real val;
00057 int posi, i;
00058 int n= mat.Nrows();
00059
00060 ColumnVector mat_corrected(n);
00061
00062 for (i = 0; i < n; i++) {
00063 tReal lower, upper;
00064 domain->getValues(i, &lower, &upper);
00065 val = mat[i];
00066 posi = i;
00067
00068 if (val < lower) {
00069 val = lower;
00070 if (corrected != NULL) {
00071 corrected->push_back(posi);
00072 }
00073 }
00074 else if (val > upper) {
00075 val = upper;
00076
00077 if (corrected != NULL) {
00078 corrected->push_back(posi);
00079 }
00080 }
00081
00082 mat_corrected[i] = val;
00083 }
00084
00085 mat_corrected.Release();
00086 return mat_corrected;
00087 }
00088
00089
00090 void CMAESBound::evalSols(ColumnVector &xmean, MyMatrix &arx, MyMatrix &arxvalid,
00091 RowVector &fitness_raw, RowVector &fitness_sel) {
00092 int lambda = arx.Ncols();
00093 int i;
00094
00095 try {
00096 vector<int> v_ti;
00097 v_ti.reserve(m_ndim);
00098
00099
00100 m_numapplied += 1;
00101
00102
00103
00104 if (!m_isactive) {
00105 arxvalid = arx;
00106 }
00107 else {
00108 for (i = 1; i <= lambda; ++i) {
00109 ColumnVector arx_i = arx.Column(i);
00110 arxvalid.Column(i) = xintobounds(arx_i, m_domain, &v_ti);
00111 }
00112
00113 }
00114
00115 for (i = 1; i <= lambda; ++i) {
00116 ColumnVector arxvalid_i = arxvalid.Column(i);
00117 fitness_raw[i-1] = m_eval->eval(arxvalid_i.Store(), m_ndim);
00118 }
00119
00120
00121 fitness_sel = fitness_raw;
00122
00123
00124 if (!m_isactive || !m_avanzed) {
00125 return;
00126 }
00127
00128
00129 int perc[2] = {25,75};
00130
00131
00132 RowVector r_val = myprctile(fitness_raw, perc, 2);
00133 ColumnVector val(m_ndim);
00134 val = (r_val[1]-r_val[0]) / m_ndim / mean(m_diagC);
00135 ColumnVector pow2_sigma = pow2(m_sigma);
00136 val = DotDivide(val, pow2_sigma);
00137 Real maxval = max(val);
00138
00139 if (maxval == 0) {
00140 val = min_positive(m_dfithist);
00141 }
00142 else if (m_validfitval == 0) {
00143 m_dfithist.pop();
00144 m_validfitval = 1;
00145 }
00146
00147
00148 if (m_dfithist.size() == m_dfithist_size) {
00149 m_dfithist.pop();
00150 }
00151
00152 Real valuemin = min_positive(val);
00153 m_dfithist.push(valuemin);
00154
00155 RowVector dfithist(m_dfithist.size());
00156 copyRow(m_dfithist, dfithist);
00157
00158
00159 m_weights = DotVectors(m_scale, m_weights);
00160
00161 Real mean_d = mean(log(m_diagC));
00162 m_scale << exp(0.1*mean_d)*pow(m_diagC, 0.9);
00163
00164
00165 m_scale = m_scale / exp(mean(log(m_scale)));
00166
00167
00168 m_weights = DivVectors(m_weights, m_scale);
00169
00170
00171
00172 v_ti.clear();
00173 ColumnVector tx = xintobounds(xmean, m_domain, &v_ti);
00174
00175
00176
00177
00178 if (m_iniphase) {
00179
00180
00181
00182
00183 if (v_ti.size() ) {
00184
00185 try {
00186
00187 Real hist_median = median(dfithist);
00188 m_weights = 2.0002* hist_median;
00189
00190 m_weights = DivVectors(m_weights, m_scale);
00191
00192 }
00193 catch (Exception &e) {
00194 cerr <<"Dentro de iniphase : " <<e.what() <<endl;
00195 }
00196 if (m_validfitval && m_numapplied > 2) {
00197 m_iniphase = false;
00198 }
00199 }
00200 }
00201
00202
00203 if (v_ti.size() ) {
00204
00205 tx = xmean - tx;
00206 Real umbral_out = 3*max(1.0,sqrt(m_ndim)/m_mueff);
00207 Real increm = pow(1.1, max(1.0, m_mueff/10.0/m_ndim));
00208 vector<int>::iterator item;
00209 int posi;
00210
00211 for (item = v_ti.begin(); item != v_ti.end(); item++) {
00212 posi = *item;
00213
00214 if (tx[posi] > umbral_out*m_sigma[posi]*sqrt(m_diagC[posi])) {
00215 m_weights *= increm;
00216 }
00217 }
00218 }
00219
00220
00221 Matrix dif = arxvalid - arx;
00222
00223
00224
00225 RowVector arpenalty = m_weights.t() * pow2_m(dif);
00226
00227
00228
00229 fitness_sel = fitness_raw + arpenalty;
00230 }
00231 catch (Exception &e) {
00232 cerr <<"Excepción recuperada" <<endl;
00233 cerr <<e.what() <<endl;
00234 }
00235
00236 }
00237
00241 MyReturnMatrix xintobounds(const ColumnVector &mat, Real *lower, Real *upper, vector<int> *corrected) {
00242 Real val;
00243 int posi, i;
00244 int n= mat.Nrows();
00245
00246 ColumnVector mat_corrected(n);
00247
00248 for (i = 0; i < n; i++) {
00249 val = mat[i];
00250 posi = i;
00251
00252 if (val < lower[i]) {
00253 val = lower[i];
00254 if (corrected != NULL) {
00255 corrected->push_back(posi);
00256 }
00257 }
00258 else if (val > upper[i]) {
00259 val = upper[i];
00260
00261 if (corrected != NULL) {
00262 corrected->push_back(posi);
00263 }
00264 }
00265
00266 mat_corrected[i] = val;
00267 }
00268
00269 mat_corrected.Release();
00270 return mat_corrected;
00271 }
00272
00273
00274