source: stable/0.1/Couenne/src/problem/CouenneSolverInterface.cpp @ 111

Last change on this file since 111 was 111, checked in by stefan, 13 years ago

fix compiler warnings

File size: 9.9 KB
Line 
1/*
2 * Name:    CouenneSolverInterface.cpp
3 * Authors: Pietro Belotti, Carnegie Mellon University
4 *          Andreas Waechter, IBM Corp.
5 * Purpose: Implementation of the OsiSolverInterface::resolve () method
6 *
7 * (C) Carnegie-Mellon University, 2006-09.
8 * This file is licensed under the Common Public License (CPL)
9 */
10
11#include "OsiClpSolverInterface.hpp"
12#include "CouenneProblem.hpp"
13#include "CouenneSolverInterface.hpp"
14#include "CglTreeInfo.hpp"
15
16/// constructor
17CouenneSolverInterface::CouenneSolverInterface (CouenneCutGenerator *cg /*= NULL*/):
18
19  OsiClpSolverInterface(),
20  cutgen_ (cg),
21  knowInfeasible_(false),
22  knowOptimal_(false) {
23
24  // prevents from running OsiClpSolverInterface::tightenBounds()
25  specialOptions_ = specialOptions_ | 262144; 
26}
27
28/// copy constructor
29CouenneSolverInterface::CouenneSolverInterface (const CouenneSolverInterface &src):
30
31  OsiSolverInterface (src),
32  OsiClpSolverInterface (src),
33  cutgen_ (src.cutgen_),
34  knowInfeasible_ (src.knowInfeasible_),
35  knowOptimal_ (src.knowOptimal_) {}
36
37/// Destructor
38CouenneSolverInterface::~CouenneSolverInterface () {
39  //  if (cutgen_)
40  //    delete cutgen_;
41}
42
43
44/// Solve initial LP relaxation
45void CouenneSolverInterface::initialSolve () {
46  /*printf ("------------------------------------- INITIAL SOLVE\n");
47  for (int i=0; i<getNumCols(); i++)
48    printf ("%4d. %20.5g [%20.5g %20.5g]\n",
49            i, getColSolution () [i],
50            getColLower () [i],
51            getColUpper () [i]);
52
53            cutgen_ -> Problem () -> print ();*/
54
55  knowInfeasible_ = 
56  knowOptimal_    = false;
57
58  OsiClpSolverInterface::initialSolve ();
59  //writeLp ("initialLP");
60
61  // some originals may be unused due to their zero multiplicity (that
62  // happens when they are duplicates), restore their value
63  CouNumber *x = new CouNumber [getNumCols ()];
64  CoinCopyN (getColSolution (), getNumCols (), x);
65  cutgen_ -> Problem () -> restoreUnusedOriginals (x);
66  setColSolution (x);
67  delete [] x;
68
69  /*
70    printf ("------------------------------------- INITSOLV\n");
71  for (int i=0; i<cutgen_ -> Problem () -> nOrigVars (); i++)
72    //if (cutgen_ -> Problem () -> Var (i) -> Multiplicity () <= 0)
73      {
74      printf ("%4d. %20.5g [%20.5g %20.5g]   ",
75              i, getColSolution () [i],
76              getColLower () [i],
77              getColUpper () [i]);
78      cutgen_ -> Problem () -> Var (i) -> print ();
79      printf ("\n");
80    }
81  */
82}
83
84bool CouenneSolverInterface::isProvenPrimalInfeasible() const {
85  return knowInfeasible_ || OsiClpSolverInterface::isProvenPrimalInfeasible();
86}
87
88bool CouenneSolverInterface::isProvenOptimal() const {
89  return knowOptimal_ || OsiClpSolverInterface::isProvenOptimal();
90}
91
92
93/// Defined in Couenne/src/convex/generateCuts.cpp
94void sparse2dense (int, t_chg_bounds *, int *&, int &);
95
96
97/// Resolve an LP relaxation after problem modification
98void CouenneSolverInterface::resolve () {
99  /*printf ("------------------------------------- RESOLVE\n");
100  for (int i=0; i<getNumCols(); i++)
101    printf ("%4d. %20.5g [%20.5g %20.5g]\n",
102            i, getColSolution () [i],
103            getColLower () [i],
104            getColUpper () [i]);*/
105
106  // CUT THIS! Some about-to-be-resolved problems have variables with
107  // lower +inf. That is, between CbcModel::initialSolve() and
108  // CbcModel::resolve(). I couldn't spot where in Couenne this
109  // happens.
110
111  ////////////////////////////////////// Cut {
112  /*const double
113    *lb = getColLower (),
114    *ub = getColUpper ();
115
116  for (int i=getNumCols(); i--;) {
117    if (lb [i] >  COUENNE_INFINITY)
118      setColLower (i, cutgen_ -> Problem () -> Lb (i));
119    //setColLower (i, -COIN_DBL_MAX);//cutgen_ -> Problem () -> Lb (i));
120    if (ub [i] < -COUENNE_INFINITY)
121      setColUpper (i, cutgen_ -> Problem () -> Ub (i));
122    //setColUpper (i,  COIN_DBL_MAX);//cutgen_ -> Problem () -> Ub (i));
123    }*/
124  ////////////////////////////////////// Cut }
125
126  static int count = -1;
127  char filename [30];
128
129  // save problem to be loaded later
130  if (cutgen_ && (cutgen_ -> check_lp ())) {
131    count++;
132    sprintf (filename, "resolve_%d", count);
133    writeMps (filename);
134  }
135
136  knowInfeasible_ = false;
137  knowOptimal_    = false;
138
139  const CoinWarmStart *ws = NULL;
140
141  if (cutgen_ && (cutgen_ -> check_lp ()))
142    ws = getWarmStart ();
143
144  //deleteScaleFactors ();
145
146  // re-solve problem
147  OsiClpSolverInterface::resolve ();
148
149  // some originals may be unused due to their zero multiplicity (that
150  // happens when they are duplicates), restore their value
151  CouNumber *x = new CouNumber [getNumCols ()];
152  CoinCopyN (getColSolution (), getNumCols (), x);
153  cutgen_ -> Problem () -> restoreUnusedOriginals (x);
154  setColSolution (x);
155  delete [] x;
156
157  //cutgen_ -> Problem () -> restoreUnusedOriginals (this);
158
159  // check LP independently
160  if (cutgen_ && (cutgen_ -> check_lp ())) {
161
162    OsiSolverInterface
163      *nsi = new OsiClpSolverInterface,
164      *csi = clone ();
165
166    sprintf (filename, "resolve_%d.mps", count);
167    nsi -> readMps (filename);
168
169    nsi -> messageHandler () -> setLogLevel (0);
170    nsi -> setWarmStart (ws);
171
172    nsi -> initialSolve ();
173
174    if ((nsi -> isProvenOptimal () && isProvenOptimal ()) ||
175        (!(nsi -> isProvenOptimal ()) && !isProvenOptimal ())) {
176
177      if (nsi -> isProvenOptimal () &&
178          (fabs (nsi -> getObjValue () - getObjValue ()) / 
179           (1. + fabs (nsi -> getObjValue ()) + fabs (getObjValue ())) > 1e-2))
180
181        printf ("Warning: discrepancy between saved %g and current %g [%g], file %s\n", 
182                nsi -> getObjValue (),  getObjValue (),
183                nsi -> getObjValue () - getObjValue (),
184                filename);
185    }
186
187    csi -> messageHandler () -> setLogLevel (0);
188    csi -> setWarmStart (ws);
189
190    csi -> initialSolve ();
191
192    if (((csi -> isProvenOptimal () && isProvenOptimal ())) ||
193        (!(csi -> isProvenOptimal ()) && !isProvenOptimal ())) {
194
195      if (csi -> isProvenOptimal () &&
196          (fabs (csi -> getObjValue () - getObjValue ()) / 
197           (1. + fabs (csi -> getObjValue ()) + fabs (getObjValue ())) > 1e-2))
198
199        printf ("Warning: discrepancy between cloned %g and current %g [%g]\n", 
200                csi -> getObjValue (),  getObjValue (),
201                csi -> getObjValue () - getObjValue ());
202    }
203
204    delete nsi;
205    delete csi;
206   
207    delete ws;
208
209    //else printf ("Warning: discrepancy between statuses %s -- %s feasible\n",
210    //filename, isProvenOptimal () ? "current" : "saved");
211  }
212}
213
214
215/// Create a hot start snapshot of the optimization process.
216void CouenneSolverInterface::markHotStart () {
217  //printf(">>>> markHotStart\n");
218  // Using OsiClpSolverInterface doesn't work yet...
219  OsiSolverInterface::markHotStart ();
220}
221
222
223/// Delete the hot start snapshot.
224void CouenneSolverInterface::unmarkHotStart() {
225  //printf("<<<< unmarkHotStart\n");
226  OsiSolverInterface::unmarkHotStart();
227}
228
229
230
231/// Optimize starting from the hot start snapshot.
232void CouenneSolverInterface::solveFromHotStart() {
233
234  //OsiClpSolverInterface::solveFromHotStart ();
235
236  //#if 0
237  knowInfeasible_ = false;
238  knowOptimal_ = false;
239
240  /*
241  const int ncols = cutgen_ -> Problem () -> nVars ();
242
243  cutgen_ -> Problem () -> domain () -> push
244    (cutgen_ -> Problem () -> nVars (),
245     getColSolution (),
246     getColLower    (),
247     getColUpper    ());
248
249  // This vector contains variables whose bounds have changed due to
250  // branching, reduced cost fixing, or bound tightening below. To be
251  // used with malloc/realloc/free
252
253  t_chg_bounds *chg_bds = new t_chg_bounds [ncols];
254
255  OsiCuts cs;
256
257  Bonmin::BabInfo *babInfo = dynamic_cast <Bonmin::BabInfo *> (getAuxiliaryInfo ());
258
259  if (cutgen_ -> Problem () -> doFBBT () &&
260      (!(cutgen_ -> Problem () -> boundTightening (chg_bds, babInfo)))) {
261
262#ifdef DEBUG
263    printf ("#### BT says infeasible before re-solve\n");
264#endif
265    knowInfeasible_ = true;
266    cutgen_ -> Problem () -> domain () -> pop ();
267    return;
268  }
269
270  int *changed = NULL, nchanged;
271  sparse2dense (ncols, chg_bds, changed, nchanged);
272
273  // change tightened bounds through OsiCuts
274  if (nchanged)
275    cutgen_ -> genColCuts (*this, cs, nchanged, changed);
276
277  const int nRowsBeforeRowCuts = getNumRows();
278  //printf("NumRows before getRowCuts = %d\n", getNumRows());
279  cutgen_ -> genRowCuts (*this, cs, nchanged, changed, //CglTreeInfo(),
280                         chg_bds, false);
281
282  // Now go through the list of cuts and apply the column cuts
283  // directly as changes on bounds
284  while(cs.sizeColCuts()) {
285    const OsiColCut& ccut = cs.colCut(0);
286    const CoinPackedVector& lbs = ccut.lbs();
287    int nele = lbs.getNumElements();
288    const int* idxs = lbs.getIndices();
289    const double* eles = lbs.getElements();
290    const double* bnds = getColLower();
291    for (int i=0; i<nele; i++) {
292      if (bnds[*idxs] < *eles) {
293        //printf ("setcolLower %d %g\n", *idxs, *eles);
294        setColLower(*idxs,*eles);
295      }
296      idxs++;
297      eles++;
298    }
299    const CoinPackedVector& ubs = ccut.ubs();
300    nele = ubs.getNumElements();
301    idxs = ubs.getIndices();
302    eles = ubs.getElements();
303    bnds = getColUpper();
304    for (int i=0; i<nele; i++) {
305      if (bnds[*idxs] > *eles) {
306        //printf ("setcolUpper %d %g\n", *idxs, *eles);
307        setColUpper(*idxs,*eles);
308      }
309      idxs++;
310      eles++;
311    }
312    cs.eraseColCut(0);
313  }
314
315  applyCuts (cs);
316
317  const int nRowsAfterRowCuts = getNumRows();
318  //printf("NumRows after applyCuts = %d\n", getNumRows());
319  */
320
321  resolve();
322
323  // some originals may be unused due to their zero multiplicity (that
324  // happens when they are duplicates), restore their value
325  CouNumber *x = new CouNumber [getNumCols ()];
326  CoinCopyN (getColSolution (), getNumCols (), x);
327  cutgen_ -> Problem () -> restoreUnusedOriginals (x);
328  setColSolution (x);
329  delete [] x;
330
331  if (isProvenPrimalInfeasible ()) knowInfeasible_ = true;
332  if (isProvenOptimal ())          knowOptimal_    = true;
333
334  //printf("obj value = %e\n",getObjValue());
335
336  // now undo the row cuts
337  /*
338  int nrowsdel = nRowsAfterRowCuts-nRowsBeforeRowCuts;
339  int* rowsdel = new int[nrowsdel];
340  for(int i=0; i<nrowsdel; i++) {
341    rowsdel[i] = nRowsBeforeRowCuts+i;
342  }
343  deleteRows(nrowsdel, rowsdel);
344  delete [] rowsdel;
345  //printf("NumRows after deleting = %d\n", getNumRows());
346
347  cutgen_ -> Problem () -> domain () -> pop ();
348  */
349  //#endif
350}
Note: See TracBrowser for help on using the repository browser.