CouenneRecordBestSol.cpp
Go to the documentation of this file.
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 
20 using namespace Couenne;
21 
22 //#define TRACE
23 
24 /*************************************************************/
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
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;
92 }
93 
94 /*************************************************************/
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 /*****************************************************************************/
114 void 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 /*****************************************************************************/
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 /*****************************************************************************/
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 /*****************************************************************************/
188 void CouenneRecordBestSol::setHasSol(const bool givenHasSol) {
189  hasSol = givenHasSol;
190 }
191 
192 /*****************************************************************************/
193 void CouenneRecordBestSol::setCardSol(const int givenCard) {
194  cardSol = givenCard;
195 }
196 
197 /*****************************************************************************/
198 void 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 /*****************************************************************************/
229 void 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 /*****************************************************************************/
240 void 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 /*****************************************************************************/
250  if(modSol == NULL) {
251  printf(" CouenneRecordBestSol::update(): ### ERROR: modSol == NULL\n");
252  exit(1);
253  }
254 
256 } /* update */
257 
258 /*****************************************************************************/
259 int 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 /*****************************************************************************/
318 double * 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 /*****************************************************************************/
333 void 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 /*****************************************************************************/
362 void 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 */
void setVal(const double givenVal)
void setSol(const double *givenSol, const int givenCard, const double givenMaxViol)
void setInitIsInt(const bool *givenIsInt, const int givenCard)
void setInitDomUb(const CouNumber *givenUb, const int givenCard)
int compareAndSave(const double *solA, const double solAVal, const double solAMaxViol, const bool solAIsFeas, const double *solB, const double solBVal, const double solBMaxViol, const bool solBIsFeas, const int cardSol, const double precision)
double CouNumber
main number type in Couenne
void setCardSol(const int givenCard)
void setModSol(const double *givenModSol, const int givenModCard, const double givenModVal, const double givenModMaxViol)
double * getModSol(const int expectedCard)
void setHasSol(const bool givenHasSol)
void setInitDomLb(const CouNumber *givenLb, const int givenCard)