/home/coin/SVN-release/OS-2.4.0/Couenne/src/problem/CouenneRecordBestSol.cpp

Go to the documentation of this file.
00001 // (C) Copyright Francois Margot and Carnegie Mellon University 2011
00002 // All Rights Reserved.
00003 // This code is published under the Eclipse Public License (EPL).
00004 //
00005 // Authors :
00006 // Francois Margot, Tepper School of Business, Carnegie Mellon University,
00007 //
00008 // Date : 3/31/2011
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 // copy constructor
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 } /* setInitIsInt */
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 } /* setInitDomLb */
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 } /* setInitDomUb */
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 } /* setSol */
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 } /* update */
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 } /* update */
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 { // both solutions are infeasible; select the one with min viol.
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 } /* compareAndSave */ 
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 } /* getModSol */
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 } /* setModSol */
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 } /* printSol */ 

Generated on Thu Sep 22 03:05:59 2011 by  doxygen 1.4.7