00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include<cstdio>
00011 #include<cstdlib>
00012 #include<cstring>
00013 #include<cmath>
00014
00015 #include "CoinHelperFunctions.hpp"
00016
00017 #include "CouenneProblem.hpp"
00018 #include "CouenneRecordBestSol.hpp"
00019
00020 using namespace Couenne;
00021
00022
00023
00024
00026 CouenneRecordBestSol::CouenneRecordBestSol() {
00027
00028 cardInitDom = -1;
00029 initIsInt = NULL;
00030 initDomLb = NULL;
00031 initDomUb = NULL;
00032
00033 hasSol = false;
00034 cardSol = -1;
00035 sol = NULL;
00036 val = -1;
00037 maxViol = -1;
00038
00039 cardModSol = -1;
00040 modSol = NULL;
00041 modSolVal = -1;
00042 modSolMaxViol = -1;
00043 }
00044
00045
00046
00047 CouenneRecordBestSol::CouenneRecordBestSol(const CouenneRecordBestSol &other) {
00048
00049 cardInitDom = other.cardInitDom;
00050 if(cardInitDom > -1) {
00051 initIsInt = new bool[other.cardInitDom];
00052 initDomLb = new CouNumber[other.cardInitDom];
00053 initDomUb = new CouNumber[other.cardInitDom];
00054
00055 CoinCopyN(other.initIsInt, cardInitDom, initIsInt);
00056 CoinCopyN(other.initDomLb, cardInitDom, initDomLb);
00057 CoinCopyN(other.initDomUb, cardInitDom, initDomUb);
00058 }
00059 else {
00060 initIsInt = NULL;
00061 initDomLb = NULL;
00062 initDomUb = NULL;
00063 }
00064
00065 for(unsigned int i=0; i<other.listInt.size(); i++) {
00066 listInt.push_back(other.listInt[i]);
00067 }
00068
00069 hasSol = other.hasSol;
00070 cardSol = other.cardSol;
00071 val = other.val;
00072 maxViol = other.maxViol;
00073
00074 if(other.sol != NULL) {
00075 sol = new double[other.cardSol];
00076 CoinCopyN(other.sol, cardSol, sol);
00077 }
00078 else {
00079 sol = NULL;
00080 }
00081
00082 if (other.modSol != NULL) {
00083 modSol = new double[other.cardSol];
00084 CoinCopyN(other.modSol, cardSol, modSol);
00085 }
00086 else {
00087 modSol = NULL;
00088 }
00089 cardModSol = other.cardModSol;
00090 modSolVal = other.modSolVal;
00091 modSolMaxViol = other.modSolMaxViol;
00092 }
00093
00094
00096 CouenneRecordBestSol::~CouenneRecordBestSol(){
00097
00098 if(cardInitDom > -1) {
00099 delete[] initIsInt;
00100 delete[] initDomLb;
00101 delete[] initDomUb;
00102 }
00103
00104 if(sol != NULL) {
00105 delete[] sol;
00106 }
00107
00108 if(modSol != NULL) {
00109 delete[] modSol;
00110 }
00111 }
00112
00113
00114 void CouenneRecordBestSol::setInitIsInt(const bool *givenIsInt,
00115 const int givenCard) {
00116
00117 if(initIsInt == NULL) {
00118 if(cardInitDom == -1) {
00119 cardInitDom = givenCard;
00120 }
00121 if(givenCard != cardInitDom) {
00122 printf("### ERROR: CouenneRecordBestSol::setInitIsInt(): cardInitDom: %d givenCard: %d\n", cardInitDom, givenCard);
00123 exit(1);
00124 }
00125 initIsInt = new bool[givenCard];
00126 }
00127 else {
00128 if(givenCard != cardInitDom) {
00129 printf("### ERROR: CouenneRecordBestSol::setInitIsInt(): cardInitDom: %d givenCard: %d\n", cardInitDom, givenCard);
00130 exit(1);
00131 }
00132 }
00133 CoinCopyN(givenIsInt, givenCard, initIsInt);
00134
00135 listInt.empty();
00136 for(int i=0; i<givenCard; i++) {
00137 if(initIsInt[i]) {
00138 listInt.push_back(i);
00139 }
00140 }
00141 }
00142
00143
00144 void CouenneRecordBestSol::setInitDomLb(const CouNumber *givenLb,
00145 const int givenCard) {
00146 if(initDomLb == NULL) {
00147 if(cardInitDom == -1) {
00148 cardInitDom = givenCard;
00149 }
00150 if(givenCard != cardInitDom) {
00151 printf("### ERROR: CouenneRecordBestSol::setInitDomLb(): cardInitDom: %d givenCard: %d\n", cardInitDom, givenCard);
00152 exit(1);
00153 }
00154 initDomLb = new CouNumber[givenCard];
00155 }
00156 else {
00157 if(givenCard != cardInitDom) {
00158 printf("### ERROR: CouenneRecordBestSol::setInitDomLb(): cardInitDom: %d givenCard: %d\n", cardInitDom, givenCard);
00159 exit(1);
00160 }
00161 }
00162 CoinCopyN(givenLb, givenCard, initDomLb);
00163 }
00164
00165
00166 void CouenneRecordBestSol::setInitDomUb(const CouNumber *givenUb,
00167 const int givenCard) {
00168 if(initDomUb == NULL) {
00169 if(cardInitDom == -1) {
00170 cardInitDom = givenCard;
00171 }
00172 if(givenCard != cardInitDom) {
00173 printf("### ERROR: CouenneRecordBestSol::setInitDomUb(): cardInitDom: %d givenCard: %d\n", cardInitDom, givenCard);
00174 exit(1);
00175 }
00176 initDomUb = new CouNumber[givenCard];
00177 }
00178 else {
00179 if(givenCard != cardInitDom) {
00180 printf("### ERROR: CouenneRecordBestSol::setInitDomUb(): cardInitDom: %d givenCard: %d\n", cardInitDom, givenCard);
00181 exit(1);
00182 }
00183 }
00184 CoinCopyN(givenUb, givenCard, initDomUb);
00185 }
00186
00187
00188 void CouenneRecordBestSol::setHasSol(const bool givenHasSol) {
00189 hasSol = givenHasSol;
00190 }
00191
00192
00193 void CouenneRecordBestSol::setCardSol(const int givenCard) {
00194 cardSol = givenCard;
00195 }
00196
00197
00198 void CouenneRecordBestSol::setSol(const double *givenSol, const int givenCard,
00199 const double givenMaxViol) {
00200 if(sol == NULL) {
00201 cardSol = givenCard;
00202 sol = new double[givenCard];
00203 if(modSol == NULL) {
00204 modSol = new double[givenCard];
00205 }
00206 }
00207 else {
00208 if(givenCard != cardSol) {
00209
00210
00211
00212 double *newSol = new double [givenCard];
00213 CoinCopyN (givenSol, givenCard, newSol);
00214 delete [] modSol;
00215 modSol = newSol;
00216 cardSol = givenCard;
00217 }
00218 }
00219 CoinCopyN(givenSol, givenCard, sol);
00220 maxViol = givenMaxViol;
00221
00222 #ifdef TRACE
00223 printf("CouenneRecordBestSol::setSol(): New solution set\n");
00224 #endif
00225
00226 }
00227
00228
00229 void CouenneRecordBestSol::setVal(const double givenVal) {
00230
00231 #ifdef TRACE
00232 printf("CouenneRecordBestSol::setVal(): set to %10.6f\n", givenVal);
00233 #endif
00234
00235 val = givenVal;
00236 hasSol = true;
00237 }
00238
00239
00240 void CouenneRecordBestSol::update(const double *givenSol, const int givenCard,
00241 const double givenVal, const double givenMaxViol) {
00242 if (!hasSol || (givenVal < val)) {
00243 setSol(givenSol, givenCard, givenMaxViol);
00244 setVal(givenVal);
00245 }
00246 }
00247
00248
00249 void CouenneRecordBestSol::update() {
00250 if(modSol == NULL) {
00251 printf(" CouenneRecordBestSol::update(): ### ERROR: modSol == NULL\n");
00252 exit(1);
00253 }
00254
00255 update(modSol, cardModSol, modSolVal, modSolMaxViol);
00256 }
00257
00258
00259 int CouenneRecordBestSol::compareAndSave(const double *solA, const double solAVal, const double solAMaxViol, const bool solAIsFeas,
00260 const double *solB, const double solBVal, const double solBMaxViol, const bool solBIsFeas,
00261 const int cardSol,
00262 const double precision) {
00263 int retval = -2;
00264 if(solBIsFeas) {
00265 if(solAIsFeas) {
00266 if(solAVal < solBVal - precision) {
00267 retval = 0;
00268 }
00269 else {
00270 retval = 1;
00271 }
00272 }
00273 else {
00274 retval = 1;
00275 }
00276 }
00277 else {
00278 if(solAIsFeas) {
00279 retval = 0;
00280 }
00281 else {
00282 if(solAVal < 1e49) {
00283 if(solBVal < 1e49) {
00284 if(solAMaxViol < solBMaxViol) {
00285 retval = 0;
00286 }
00287 else {
00288 retval = 1;
00289 }
00290 }
00291 else {
00292 retval = 0;
00293 }
00294 }
00295 else {
00296 if(solBVal < 1e49) {
00297 retval = 1;
00298 }
00299 else {
00300 retval = -1;
00301 }
00302 }
00303 }
00304 }
00305
00306 switch (retval) {
00307 case 0: update(solA, cardSol, solAVal, solAMaxViol); break;
00308 case 1: update(solB, cardSol, solBVal, solBMaxViol); break;
00309 case -1: break;
00310 default: printf("CouenneRecordBestSol::compareAndSave(): ### ERROR: retval: %d\n",
00311 retval); break;
00312 }
00313
00314 return(retval);
00315 }
00316
00317
00318 double * CouenneRecordBestSol::getModSol(const int expectedCard) {
00319 if(modSol == NULL) {
00320 cardModSol = expectedCard;
00321 modSol = new double[expectedCard];
00322 }
00323 else {
00324 if(expectedCard != cardModSol) {
00325 printf("CouenneRecordBestSol::getModSol(): ### ERROR: expectedCard: %d cardModSol: %d", expectedCard, cardModSol);
00326 exit(1);
00327 }
00328 }
00329 return modSol;
00330 }
00331
00332
00333 void CouenneRecordBestSol::setModSol(const double *givenModSol,
00334 const int givenModCard,
00335 const double givenModVal,
00336 const double givenModMaxViol) {
00337
00338 if(givenModSol != NULL) {
00339 if(modSol == NULL) {
00340 cardModSol = givenModCard;
00341 modSol = new double[givenModCard];
00342 }
00343 else {
00344 if(givenModCard != cardModSol) {
00345
00346
00347
00348 double *newModSol = new double [givenModCard];
00349 CoinCopyN (givenModSol, givenModCard, newModSol);
00350 delete [] modSol;
00351 modSol = newModSol;
00352 cardModSol = givenModCard;
00353 }
00354 }
00355 CoinCopyN(givenModSol, givenModCard, modSol);
00356 }
00357 modSolVal = givenModVal;
00358 modSolMaxViol = givenModMaxViol;
00359 }
00360
00361
00362 void CouenneRecordBestSol::printSol(FILE *fsol) const {
00363
00364 if(sol != NULL) {
00365 fprintf(fsol, "%d\n", cardSol);
00366 for(int i=0; i<cardSol; i++) {
00367 fprintf(fsol, " %12.8f", sol[i]);
00368 if(i % 10 == 9) {
00369 fprintf(fsol, "\n");
00370 }
00371 }
00372 if(cardSol % 10 != 0) {
00373 fprintf(fsol, "\n");
00374 }
00375 fprintf(fsol, "Value: %16.14g\n", val);
00376 fprintf(fsol, "Tolerance: %16.14g\n", maxViol);
00377 }
00378 }