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