source: trunk/Bonmin/experimental/NotConvex/BonCouenneInterface.cpp @ 508

Last change on this file since 508 was 508, checked in by pbonami, 13 years ago

Make bcp-bonmin work with new setup

File size: 7.4 KB
Line 
1// (C) Copyright International Business Machines Corporation (IBM) 2006, 2007
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Pietro Belloti, Carnegie Mellon University
7// Pierre Bonami, International Business Machines Corporation
8//
9// Date : 12/19/2006
10
11
12#include "BonCouenneInterface.hpp"
13#include "CoinHelperFunctions.hpp"
14#include <CouenneProblem.h>
15
16namespace Bonmin {
17
18/** Default constructor. */
19CouenneInterface::CouenneInterface():
20  AmplInterface()
21{}
22
23/** Copy constructor. */
24CouenneInterface::CouenneInterface(const CouenneInterface &other):
25  AmplInterface(other)
26  {
27  }
28
29/** virutal copy constructor. */
30CouenneInterface * CouenneInterface::clone(bool CopyData){
31  return new CouenneInterface(*this);
32}
33
34/** Destructor. */
35CouenneInterface::~CouenneInterface(){
36}
37
38
39
40void 
41CouenneInterface::readAmplNlFile(char **& argv, Ipopt::SmartPtr<Ipopt::RegisteredOptions> roptions,
42                                 Ipopt::SmartPtr<Ipopt::OptionsList> options,
43                                 Ipopt::SmartPtr<Ipopt::Journalist> journalist){
44  AmplInterface::readAmplNlFile(argv, roptions, options, journalist);
45}
46
47/** \name Overloaded methods to build outer approximations */
48  //@{
49  /** \brief Extract a linear relaxation of the MINLP.
50   *
51   * Solve the continuous relaxation and takes first-order
52   * outer-approximation constraints at the optimum.  Then put
53   * everything in an OsiSolverInterface.
54   *
55   * The OsiSolverInterface si is empty and has to be populated with
56   * the initial linear relaxation.
57   */
58
59void 
60CouenneInterface::extractLinearRelaxation (OsiSolverInterface &si, CouenneCutGenerator & couenneCg, bool getObj, bool solveNlp) {
61
62  if (solveNlp)
63    initialSolve ();
64
65   int numcols     = getNumCols ();             // number of original variables
66   int numcolsconv = couenneCg.getnvars (); // number of original+auxiliary variables
67
68   const double *lb = getColLower ();
69   const double *ub = getColUpper ();
70
71   // add original variables to the new problem
72   for (register int i=0; i<numcols; i++)
73     si.addCol (0, NULL, NULL, lb [i], ub [i], 0);
74
75   // get initial relaxation
76   OsiCuts cs;
77   couenneCg.generateCuts (si, cs);
78
79   // store all (original + auxiliary) bounds in the relaxation
80   CouNumber * colLower = new CouNumber [numcolsconv];
81   CouNumber * colUpper = new CouNumber [numcolsconv];
82
83   CouNumber *ll = couenneCg.Problem () -> Lb ();
84   CouNumber *uu = couenneCg.Problem () -> Ub ();
85
86   // overwrite original bounds, could be improved within generateCuts
87   for (register int i=numcolsconv; i--;) {
88     colLower [i] = ll [i];
89     colUpper [i] = uu [i];
90   }
91
92   int numrowsconv = cs.sizeRowCuts ();
93
94   // create matrix and other stuff
95   CoinBigIndex * start = new CoinBigIndex [numrowsconv + 1];
96
97   int    * length   = new int    [numrowsconv];
98   double * rowLower = new double [numrowsconv];
99   double * rowUpper = new double [numrowsconv];
100
101   start[0] = 0;
102   int nnz = 0;
103   /* fill the four arrays. */
104   for(int i = 0 ; i < numrowsconv ; i++)
105   {
106     OsiRowCut * cut = cs.rowCutPtr (i);
107
108     const CoinPackedVector &v = cut->row();
109     start[i+1] = start[i] + v.getNumElements();
110     nnz += v.getNumElements();
111     length[i] = v.getNumElements();
112
113     rowLower[i] = cut->lb();
114     rowUpper[i] = cut->ub();
115   }
116   assert(nnz == start[numrowsconv]);
117   /* Now fill the elements arrays. */
118   int * ind = new int[start[numrowsconv]];
119   double * elem = new double[start[numrowsconv]];
120   for(int i = 0 ; i < numrowsconv ; i++) {
121
122     OsiRowCut * cut = cs.rowCutPtr (i);
123
124     const CoinPackedVector &v = cut->row();
125
126     if(v.getNumElements() != length[i])
127       std::cout<<"Empty row"<<std::endl;
128     cut->print();
129     CoinCopyN(v.getIndices(), length[i], ind + start[i]);
130     CoinCopyN(v.getElements(), length[i], elem + start[i]);
131   }
132
133   // Ok everything done now create interface
134   CoinPackedMatrix A;
135   A.assignMatrix(false, numcolsconv, numrowsconv,
136                  start[numrowsconv], elem, ind,
137                  start, length);
138   if(A.getNumCols() != numcolsconv || A.getNumRows() != numrowsconv){
139     std::cout<<"Error in row number"<<std::endl;
140   }
141   assert(A.getNumElements() == nnz);
142   // Objective function
143   double * obj = new double[numcolsconv];
144   CoinFillN(obj,numcolsconv,0.);
145
146   // some instances have no (or null) objective function, check it here
147   if (couenneCg.Problem () -> nObjs () > 0)
148     obj [couenneCg.Problem () -> Obj (0) -> Body () -> Index ()] = 1;
149
150   // Finally, load interface si with the initial LP relaxation
151   si.loadProblem (A, colLower, colUpper, obj, rowLower, rowUpper);
152 
153   delete [] rowLower; 
154   delete [] rowUpper;
155   delete [] colLower;
156   delete [] colUpper;
157   delete [] obj;
158   //   delete [] x0;
159
160   for(int i = 0 ; i < numcols ; i++)
161   {
162     if(isInteger(i)){
163       si.setInteger(i);
164     }
165   }
166 
167   //si.writeMpsNative("toto",NULL,NULL,1);
168   si.writeLp("toto");
169  app_->enableWarmStart();
170  setColSolution(problem()->x_sol());
171  setRowPrice(problem()->duals_sol());
172}
173
174/** Get the outer approximation constraints at the currently stored optimal point.
175   (Only get outer-approximations of nonlinear constraints of the problem.)*/
176/*
177void
178CouenneInterface::getOuterApproximation(OsiCuts &cs, bool getObj,
179                                        const double * x2, bool global){
180
181 
182   int numcols = getNumCols();
183   int numcolsconv = couenneCg_->getnvars();
184
185   CouNumber * x0 = new CouNumber[numcolsconv];
186   CouNumber * colLower = new CouNumber[numcolsconv];
187   CouNumber * colUpper = new CouNumber[numcolsconv];
188   assert(numcolsconv >= numcols);
189   
190   CoinCopyN(couenneCg_->X(), numcolsconv, x0);
191   CoinCopyN(couenneCg_->Lb(), numcolsconv, colLower);
192   CoinCopyN(couenneCg_->Ub(), numcolsconv, colUpper);
193
194   // Feed in the initial relaxation point
195   CoinCopyN(getColSolution(), numcols, x0);
196   couenneCg_ -> updateAuxs (x0,colLower, colUpper);
197   getOuterApproximation(cs, x0, getObj, x2, global);
198
199   delete [] colLower;
200   delete [] colUpper;
201   delete [] x0;
202
203}
204*/
205/*
206void
207CouenneInterface::getOuterApproximation(OsiCuts &cs, const double * x, bool getObj, const double * x2, bool global){
208   // Check that couenneCg_ has been built.
209
210   if(couenneCg_ == NULL){
211     throw CoinError("No couenne generator has been built,"
212                     " probably ampl .nl file was not properly"
213                     " read",
214                     "extractLinearRelaxation",
215                     "Bonmin::CouenneInterface");
216   }
217   int numcols = getNumCols();
218   int numcolsconv = couenneCg_->getnvars();
219 
220   CouNumber * x0 = new CouNumber[numcolsconv];
221   CouNumber * colLower = new CouNumber[numcolsconv];
222   CouNumber * colUpper = new CouNumber[numcolsconv];
223   assert(numcolsconv >= numcols);
224   
225   // Feed in the current state
226   CoinCopyN(x, numcolsconv, x0);
227   CoinCopyN(getColLower(), numcolsconv, colLower);
228   CoinCopyN(getColUpper(), numcolsconv, colUpper);
229
230   couenneCg_->updateConv(x0, colLower, colUpper);
231
232
233   int ncuts = couenneCg_->getncuts();
234   for(int i = 0 ; i < ncuts ; i++)
235   {
236     cs.insert(*couenneCg_->getCut(i));
237   }
238   
239   delete [] colLower;
240   delete [] colUpper;
241   delete [] x0;
242}
243*/
244
245
246/** To set some application specific defaults. */
247void CouenneInterface::setAppDefaultOptions(Ipopt::SmartPtr<Ipopt::OptionsList> Options){
248  Options->SetStringValue("bonmin.algorithm", "B-Couenne", true, true);
249  Options->SetIntegerValue("bonmin.filmint_ecp_cuts", 1, true, true);
250}
251} /** End Bonmin namespace. */
Note: See TracBrowser for help on using the repository browser.