source: trunk/Couenne/src/problem/CouenneRecordBestSol.cpp @ 943

Last change on this file since 943 was 943, checked in by pbelotti, 7 years ago

starting to fix #22

File size: 9.8 KB
Line 
1// (C) Copyright Francois Margot and Carnegie Mellon University 2011
2// All Rights Reserved.
3// This code is published under the Eclipse Public License (EPL).
4//
5// Authors :
6// Francois Margot, Tepper School of Business, Carnegie Mellon University,
7//
8// Date : 3/31/2011
9
10#include<cstdio>
11#include<cstdlib>
12#include<cstring>
13#include<cmath>
14
15#include "CoinHelperFunctions.hpp"
16
17#include "CouenneProblem.hpp"
18#include "CouenneRecordBestSol.hpp"
19
20using namespace Couenne;
21
22//#define TRACE
23
24/*************************************************************/
25/** Default constructor. */
26CouenneRecordBestSol::CouenneRecordBestSol() {
27
28  cardInitDom = -1;
29  initIsInt = NULL;
30  initDomLb = NULL;
31  initDomUb = NULL;
32
33  hasSol = false;
34  cardSol = -1;
35  sol = NULL;
36  val = -1;
37  maxViol = -1;
38
39  cardModSol = -1;
40  modSol = NULL;
41  modSolVal = -1;
42  modSolMaxViol = -1;
43}
44
45/*************************************************************/
46// copy constructor
47CouenneRecordBestSol::CouenneRecordBestSol(const CouenneRecordBestSol &other) {
48
49  cardInitDom = other.cardInitDom;
50  if(cardInitDom > -1) {
51    initIsInt = new bool[other.cardInitDom];
52    initDomLb = new CouNumber[other.cardInitDom];
53    initDomUb = new CouNumber[other.cardInitDom];
54
55    CoinCopyN(other.initIsInt, cardInitDom, initIsInt);
56    CoinCopyN(other.initDomLb, cardInitDom, initDomLb);
57    CoinCopyN(other.initDomUb, cardInitDom, initDomUb);
58  }
59  else {
60    initIsInt = NULL;
61    initDomLb = NULL;
62    initDomUb = NULL;
63  }
64
65  for(unsigned int i=0; i<other.listInt.size(); i++) {
66    listInt.push_back(other.listInt[i]);
67  }
68
69  hasSol = other.hasSol;
70  cardSol = other.cardSol;
71  val = other.val;
72  maxViol = other.maxViol;
73
74  if(other.sol != NULL) {
75    sol = new double[other.cardSol];
76    CoinCopyN(other.sol, cardSol, sol);
77  }
78  else {
79    sol = NULL;
80  }
81
82  if (other.modSol != NULL) {
83    modSol = new double[other.cardSol];
84    CoinCopyN(other.modSol, cardSol, modSol);
85  }
86  else {
87    modSol = NULL;
88  }
89  cardModSol = other.cardModSol;
90  modSolVal = other.modSolVal;
91  modSolMaxViol = other.modSolMaxViol;
92} 
93
94/*************************************************************/
95/** Destructor. */
96CouenneRecordBestSol::~CouenneRecordBestSol(){
97
98  if(cardInitDom > -1) {
99    delete[] initIsInt;
100    delete[] initDomLb;
101    delete[] initDomUb;
102  }
103
104  if(sol != NULL) {
105    delete[] sol;
106  }
107
108  if(modSol != NULL) {
109    delete[] modSol;
110  }
111}
112
113/*****************************************************************************/
114void CouenneRecordBestSol::setInitIsInt(const bool *givenIsInt,
115                                        const int givenCard) {
116
117  if(initIsInt == NULL) {
118    if(cardInitDom == -1) {
119      cardInitDom = givenCard;
120    }
121    if(givenCard != cardInitDom) {
122      printf("### ERROR: CouenneRecordBestSol::setInitIsInt(): cardInitDom: %d  givenCard: %d\n", cardInitDom, givenCard);
123      exit(1);
124    }
125    initIsInt = new bool[givenCard];
126  }
127  else {
128    if(givenCard != cardInitDom) {
129      printf("### ERROR: CouenneRecordBestSol::setInitIsInt(): cardInitDom: %d  givenCard: %d\n", cardInitDom, givenCard);
130      exit(1);
131    }
132  }
133  CoinCopyN(givenIsInt, givenCard, initIsInt);
134
135  listInt.empty();
136  for(int i=0; i<givenCard; i++) {
137    if(initIsInt[i]) {
138      listInt.push_back(i);
139    }
140  }
141} /* setInitIsInt */
142
143/*****************************************************************************/
144void CouenneRecordBestSol::setInitDomLb(const CouNumber *givenLb, 
145                                        const int givenCard) {
146  if(initDomLb == NULL) {
147    if(cardInitDom == -1) {
148      cardInitDom = givenCard;
149    }
150    if(givenCard != cardInitDom) {
151      printf("### ERROR: CouenneRecordBestSol::setInitDomLb(): cardInitDom: %d  givenCard: %d\n", cardInitDom, givenCard);
152      exit(1);
153    }
154    initDomLb = new CouNumber[givenCard];
155  }
156  else {
157    if(givenCard != cardInitDom) {
158      printf("### ERROR: CouenneRecordBestSol::setInitDomLb(): cardInitDom: %d  givenCard: %d\n", cardInitDom, givenCard);
159      exit(1);
160    }
161  }
162  CoinCopyN(givenLb, givenCard, initDomLb);
163} /* setInitDomLb */
164
165/*****************************************************************************/
166void CouenneRecordBestSol::setInitDomUb(const CouNumber *givenUb, 
167                                        const int givenCard) {
168  if(initDomUb == NULL) {
169    if(cardInitDom == -1) {
170      cardInitDom = givenCard;
171    }
172    if(givenCard != cardInitDom) {
173      printf("### ERROR: CouenneRecordBestSol::setInitDomUb(): cardInitDom: %d  givenCard: %d\n", cardInitDom, givenCard);
174      exit(1);
175    }
176    initDomUb = new CouNumber[givenCard];
177  }
178  else {
179    if(givenCard != cardInitDom) {
180      printf("### ERROR: CouenneRecordBestSol::setInitDomUb(): cardInitDom: %d  givenCard: %d\n", cardInitDom, givenCard);
181      exit(1);
182    }
183  }
184  CoinCopyN(givenUb, givenCard, initDomUb);
185} /* setInitDomUb */
186
187/*****************************************************************************/
188void CouenneRecordBestSol::setHasSol(const bool givenHasSol) {
189  hasSol = givenHasSol;
190}
191
192/*****************************************************************************/
193void CouenneRecordBestSol::setCardSol(const int givenCard) {
194  cardSol = givenCard;
195}
196
197/*****************************************************************************/
198void CouenneRecordBestSol::setSol(const double *givenSol, const int givenCard,
199                           const double givenMaxViol) {
200  if(sol == NULL) {
201    cardSol = givenCard;
202    sol = new double[givenCard];
203    if(modSol == NULL) {
204      modSol = new double[givenCard];
205    }
206  }
207  else {
208    if(givenCard != cardSol) {
209      //printf("CouenneRecordBestSol::setSol(): ### ERROR: givenCard: %d  cardSol: %d", givenCard, cardSol);
210      //exit(1);
211
212        double *newSol = new double [givenCard];
213        CoinCopyN (givenSol, givenCard, newSol);
214        delete [] modSol;
215        modSol = newSol;
216        cardSol = givenCard;
217    }
218  }
219  CoinCopyN(givenSol, givenCard, sol);
220  maxViol = givenMaxViol;
221
222#ifdef TRACE
223  printf("CouenneRecordBestSol::setSol(): New solution set\n");
224#endif
225
226} /* setSol */
227
228/*****************************************************************************/
229void CouenneRecordBestSol::setVal(const double givenVal) {
230
231#ifdef TRACE
232  printf("CouenneRecordBestSol::setVal(): set to %10.6f\n", givenVal);
233#endif
234
235  val = givenVal;
236  hasSol = true;
237}
238
239/*****************************************************************************/
240void CouenneRecordBestSol::update(const double *givenSol, const int givenCard, 
241                           const double givenVal, const double givenMaxViol) {
242  if (!hasSol || (givenVal < val)) {
243    setSol(givenSol, givenCard, givenMaxViol);
244    setVal(givenVal);
245  }
246} /* update */
247
248/*****************************************************************************/
249void CouenneRecordBestSol::update() {
250  if(modSol == NULL) {
251    printf(" CouenneRecordBestSol::update(): ### ERROR: modSol == NULL\n");
252    exit(1);
253  }
254
255  update(modSol, cardModSol, modSolVal, modSolMaxViol);
256} /* update */
257
258/*****************************************************************************/
259int CouenneRecordBestSol::compareAndSave(const double *solA, const double solAVal, const double solAMaxViol, const bool solAIsFeas,
260                                         const double *solB, const double solBVal, const double solBMaxViol, const bool solBIsFeas,
261                                         const int cardSol,
262                                         const double precision) {
263  int retval = -2;
264  if(solBIsFeas) {
265    if(solAIsFeas) {
266      if(solAVal < solBVal - precision) {
267        retval = 0;
268      }
269      else {
270        retval = 1;
271      }
272    }
273    else {
274      retval = 1;
275    }
276  }
277  else {
278    if(solAIsFeas) {
279      retval = 0;
280    }
281    else { // both solutions are infeasible; select the one with min viol.
282      if(solAVal < 1e49) {
283        if(solBVal < 1e49) {
284          if(solAMaxViol < solBMaxViol) {
285            retval = 0;
286          }
287          else {
288            retval = 1;
289          }
290        }
291        else {
292          retval = 0;
293        }
294      }
295      else {
296        if(solBVal < 1e49) {
297          retval = 1;
298        }
299        else {
300          retval = -1;
301        }
302      }
303    }
304  }
305 
306  switch (retval) {
307    case 0: update(solA, cardSol, solAVal, solAMaxViol); break;
308    case 1: update(solB, cardSol, solBVal, solBMaxViol); break;
309    case -1: break;
310    default: printf("CouenneRecordBestSol::compareAndSave(): ### ERROR: retval: %d\n",
311                    retval); break;
312  }
313
314  return(retval);
315} /* compareAndSave */ 
316
317/*****************************************************************************/
318double * CouenneRecordBestSol::getModSol(const int expectedCard) { 
319  if(modSol == NULL) {
320    cardModSol = expectedCard;
321    modSol = new double[expectedCard];
322  }
323  else {
324    if(expectedCard != cardModSol) {
325      printf("CouenneRecordBestSol::getModSol(): ### ERROR: expectedCard: %d  cardModSol: %d", expectedCard, cardModSol);
326      exit(1);
327    }
328  }
329  return modSol;
330} /* getModSol */
331
332/*****************************************************************************/
333void CouenneRecordBestSol::setModSol(const double *givenModSol, 
334                              const int givenModCard, 
335                              const double givenModVal, 
336                              const double givenModMaxViol) {
337 
338  if(givenModSol != NULL) {
339    if(modSol == NULL) {
340      cardModSol = givenModCard;
341      modSol = new double[givenModCard];
342    }
343    else {
344      if(givenModCard != cardModSol) {
345        // printf("CouenneRecordBestSol::setModSol(): ### ERROR: givenModCard: %d  cardModSol: %d", givenModCard, cardModSol);
346        // exit(1);
347
348        double *newModSol = new double [givenModCard];
349        CoinCopyN (givenModSol, givenModCard, newModSol);
350        delete [] modSol;
351        modSol = newModSol;
352        cardModSol = givenModCard;
353      }
354    }
355    CoinCopyN(givenModSol, givenModCard, modSol);
356  }
357  modSolVal = givenModVal;
358  modSolMaxViol = givenModMaxViol;
359} /* setModSol */
360
361/*****************************************************************************/
362void CouenneRecordBestSol::printSol(FILE *fsol) const {
363
364  if(sol != NULL) {
365    fprintf(fsol, "%d\n", cardSol);
366    for(int i=0; i<cardSol; i++) {
367      fprintf(fsol, " %12.8f", sol[i]);
368      if(i % 10 == 9) {
369        fprintf(fsol, "\n");
370      }
371    }
372    if(cardSol % 10 != 0) {
373      fprintf(fsol, "\n");     
374    }
375    fprintf(fsol, "Value: %16.14g\n", val);
376    fprintf(fsol, "Tolerance: %16.14g\n", maxViol);
377  }
378} /* printSol */ 
Note: See TracBrowser for help on using the repository browser.