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

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

added option to fill matrices for SDP cuts. removed delete_ field from CouenneScalar?

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  }
220  CoinCopyN(givenSol, givenCard, sol);
221  maxViol = givenMaxViol;
222
223#ifdef TRACE
224  printf("CouenneRecordBestSol::setSol(): New solution set\n");
225#endif
226
227} /* setSol */
228
229/*****************************************************************************/
230void CouenneRecordBestSol::setVal(const double givenVal) {
231
232#ifdef TRACE
233  printf("CouenneRecordBestSol::setVal(): set to %10.6f\n", givenVal);
234#endif
235
236  val = givenVal;
237  hasSol = true;
238}
239
240/*****************************************************************************/
241void CouenneRecordBestSol::update(const double *givenSol, const int givenCard, 
242                           const double givenVal, const double givenMaxViol) {
243  if (!hasSol || (givenVal < val)) {
244    setSol(givenSol, givenCard, givenMaxViol);
245    setVal(givenVal);
246  }
247} /* update */
248
249/*****************************************************************************/
250void CouenneRecordBestSol::update() {
251  if(modSol == NULL) {
252    printf(" CouenneRecordBestSol::update(): ### ERROR: modSol == NULL\n");
253    exit(1);
254  }
255
256  update(modSol, cardModSol, modSolVal, modSolMaxViol);
257} /* update */
258
259/*****************************************************************************/
260int CouenneRecordBestSol::compareAndSave(const double *solA, const double solAVal,
261                                  const double solAMaxViol, 
262                                  const bool solAIsFeas,
263                                  const double *solB, const double solBVal,
264                                  const double solBMaxViol, 
265                                  const bool solBIsFeas,
266                                  const int cardSol,
267                                  const double precision) {
268  int retval = -2;
269  if(solBIsFeas) {
270    if(solAIsFeas) {
271      if(solAVal < solBVal - precision) {
272        retval = 0;
273      }
274      else {
275        retval = 1;
276      }
277    }
278    else {
279      retval = 1;
280    }
281  }
282  else {
283    if(solAIsFeas) {
284      retval = 0;
285    }
286    else { // both solutions are infeasible; select the one with min viol.
287      if(solAVal < 1e49) {
288        if(solBVal < 1e49) {
289          if(solAMaxViol < solBMaxViol) {
290            retval = 0;
291          }
292          else {
293            retval = 1;
294          }
295        }
296        else {
297          retval = 0;
298        }
299      }
300      else {
301        if(solBVal < 1e49) {
302          retval = 1;
303        }
304        else {
305          retval = -1;
306        }
307      }
308    }
309  }
310 
311  switch (retval) {
312    case 0: update(solA, cardSol, solAVal, solAMaxViol); break;
313    case 1: update(solB, cardSol, solBVal, solBMaxViol); break;
314    case -1: break;
315    default: printf("CouenneRecordBestSol::compareAndSave(): ### ERROR: retval: %d\n",
316                    retval); break;
317  }
318
319  return(retval);
320} /* compareAndSave */ 
321
322/*****************************************************************************/
323double * CouenneRecordBestSol::getModSol(const int expectedCard) { 
324  if(modSol == NULL) {
325    cardModSol = expectedCard;
326    modSol = new double[expectedCard];
327  }
328  else {
329    if(expectedCard != cardModSol) {
330      printf("CouenneRecordBestSol::getModSol(): ### ERROR: expectedCard: %d  cardModSol: %d", expectedCard, cardModSol);
331      exit(1);
332    }
333  }
334  return modSol;
335} /* getModSol */
336
337/*****************************************************************************/
338void CouenneRecordBestSol::setModSol(const double *givenModSol, 
339                              const int givenModCard, 
340                              const double givenModVal, 
341                              const double givenModMaxViol) {
342 
343  if(givenModSol != NULL) {
344    if(modSol == NULL) {
345      cardModSol = givenModCard;
346      modSol = new double[givenModCard];
347    }
348    else {
349      if(givenModCard != cardModSol) {
350        // printf("CouenneRecordBestSol::setModSol(): ### ERROR: givenModCard: %d  cardModSol: %d", givenModCard, cardModSol);
351        // exit(1);
352
353        double *newModSol = new double [givenModCard];
354        CoinCopyN (givenModSol, givenModCard, newModSol);
355        delete [] modSol;
356        modSol = newModSol;
357        cardModSol = givenModCard;
358      }
359    }
360    CoinCopyN(givenModSol, givenModCard, modSol);
361  }
362  modSolVal = givenModVal;
363  modSolMaxViol = givenModMaxViol;
364} /* setModSol */
365
366/*****************************************************************************/
367void CouenneRecordBestSol::printSol(FILE *fsol) const {
368
369  if(sol != NULL) {
370    fprintf(fsol, "%d\n", cardSol);
371    for(int i=0; i<cardSol; i++) {
372      fprintf(fsol, " %12.8f", sol[i]);
373      if(i % 10 == 9) {
374        fprintf(fsol, "\n");
375      }
376    }
377    if(cardSol % 10 != 0) {
378      fprintf(fsol, "\n");     
379    }
380    fprintf(fsol, "Value: %16.14g\n", val);
381    fprintf(fsol, "Tolerance: %16.14g\n", maxViol);
382  }
383} /* printSol */ 
Note: See TracBrowser for help on using the repository browser.