00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012 #include "OsiSolverInterface.hpp"
00013 #include "OsiCuts.hpp"
00014
00015 #include "CouenneDomain.hpp"
00016 #include "CouennePrecisions.hpp"
00017
00018
00019 #define EXTRA_STORAGE 1024
00020
00021 using namespace Couenne;
00022
00024 DomainPoint::DomainPoint (int dim,
00025 CouNumber *x,
00026 CouNumber *lb,
00027 CouNumber *ub,
00028 bool copy):
00029 dimension_ (dim),
00030 x_ (x),
00031 lb_ (lb),
00032 ub_ (ub),
00033 copied_ (copy) {
00034
00035 if ((dimension_ > 0) && copied_) {
00036
00037 int size = dim * sizeof (CouNumber);
00038
00039 x_ = (CouNumber *) malloc (size);
00040 lb_ = (CouNumber *) malloc (size);
00041 ub_ = (CouNumber *) malloc (size);
00042
00043 if (x) CoinCopyN (x, dim, x_); else CoinFillN (x_, dim, 0.);
00044 if (lb) CoinCopyN (lb, dim, lb_); else CoinFillN (lb_, dim, -COUENNE_INFINITY);
00045 if (ub) CoinCopyN (ub, dim, ub_); else CoinFillN (ub_, dim, COUENNE_INFINITY);
00046 }
00047 }
00048
00049
00051 DomainPoint::DomainPoint (int dim,
00052 const CouNumber *x,
00053 const CouNumber *lb,
00054 const CouNumber *ub,
00055 bool copy):
00056 dimension_ (dim),
00057 x_ (const_cast<CouNumber *>(x)),
00058 lb_ (const_cast<CouNumber *>(lb)),
00059 ub_ (const_cast<CouNumber *>(ub)),
00060 copied_ (copy) {
00061
00062 if ((dimension_ > 0) && copied_) {
00063
00064 x_ = (CouNumber *) malloc (dim * sizeof (CouNumber));
00065 lb_ = (CouNumber *) malloc (dim * sizeof (CouNumber));
00066 ub_ = (CouNumber *) malloc (dim * sizeof (CouNumber));
00067
00068 if (x) CoinCopyN (x, dim, x_); else CoinFillN (x_, dim, 0.);
00069 if (lb) CoinCopyN (lb, dim, lb_); else CoinFillN (lb_, dim, -COUENNE_INFINITY);
00070 if (ub) CoinCopyN (ub, dim, ub_); else CoinFillN (ub_, dim, COUENNE_INFINITY);
00071 }
00072 }
00073
00074
00076 DomainPoint::DomainPoint (const DomainPoint &src):
00077 dimension_ (src.dimension_),
00078 x_ (src.x_),
00079 lb_ (src.lb_),
00080 ub_ (src.ub_),
00081 copied_ (src.copied_) {
00082
00083 if ((dimension_ > 0) && copied_) {
00084
00085 x_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
00086 lb_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
00087 ub_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
00088
00089 CoinCopyN (src.x_, dimension_, x_);
00090 CoinCopyN (src.lb_, dimension_, lb_);
00091 CoinCopyN (src.ub_, dimension_, ub_);
00092 }
00093 }
00094
00095
00097 void DomainPoint::resize (int newdim) {
00098
00099 if (newdim == dimension_) return;
00100
00101 assert (copied_);
00102
00103 if (newdim==0) {
00104
00105 free (x_); x_ = NULL;
00106 free (lb_); lb_ = NULL;
00107 free (ub_); ub_ = NULL;
00108
00109 dimension_ = newdim;
00110
00111 } else if (newdim < dimension_) {
00112
00113 x_ = (CouNumber *) realloc (x_, newdim * sizeof (CouNumber));
00114 lb_ = (CouNumber *) realloc (lb_, newdim * sizeof (CouNumber));
00115 ub_ = (CouNumber *) realloc (ub_, newdim * sizeof (CouNumber));
00116
00117 dimension_ = newdim;
00118
00119 } else if (newdim > dimension_) {
00120
00121 newdim += EXTRA_STORAGE;
00122
00123 x_ = (CouNumber *) realloc (x_, newdim * sizeof (CouNumber));
00124 lb_ = (CouNumber *) realloc (lb_, newdim * sizeof (CouNumber));
00125 ub_ = (CouNumber *) realloc (ub_, newdim * sizeof (CouNumber));
00126
00127 dimension_ = newdim;
00128 }
00129 }
00130
00131
00133 DomainPoint &DomainPoint::operator= (const DomainPoint &src) {
00134
00135 copied_ = src.copied_;
00136
00137 if (src.dimension_ != dimension_) {
00138 if (x_) free (x_); x_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
00139 if (lb_) free (lb_); lb_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
00140 if (ub_) free (ub_); ub_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
00141 dimension_ = src.dimension_;
00142 }
00143
00144 CoinCopyN (src.x_, dimension_, x_);
00145 CoinCopyN (src.lb_, dimension_, lb_);
00146 CoinCopyN (src.ub_, dimension_, ub_);
00147
00148 return *this;
00149 }
00150
00151
00153 Domain::~Domain () {
00154
00155 if (point_)
00156 delete point_;
00157
00158 while (!(domStack_.empty ())) {
00159 delete domStack_.top ();
00160 domStack_.pop ();
00161 }
00162 }
00163
00164
00166 void Domain::push (int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy) {
00167
00168 if (!x) x = point_ -> x ();
00169 if (!lb) lb = point_ -> lb ();
00170 if (!ub) ub = point_ -> ub ();
00171
00172 if (point_)
00173 domStack_.push (point_);
00174
00175 point_ = new DomainPoint (dim, x, lb, ub, copy);
00176 }
00177
00178
00180 void Domain::push (int dim,
00181 const CouNumber *x,
00182 const CouNumber *lb,
00183 const CouNumber *ub,
00184 bool copy) {
00185
00186 if (point_)
00187 domStack_.push (point_);
00188
00189 point_ = new DomainPoint (dim, x, lb, ub, copy);
00190 }
00191
00192
00195 void Domain::push (const OsiSolverInterface *si,
00196 OsiCuts *cs,
00197 bool copy) {
00198
00199 int dim = si -> getNumCols ();
00200
00201 if (point_)
00202 domStack_.push (point_);
00203
00204 point_ = new DomainPoint (dim,
00205 si -> getColSolution (),
00206 si -> getColLower (),
00207 si -> getColUpper (), copy);
00208
00209
00210
00211 if (cs)
00212 for (int i = cs -> sizeColCuts (); i--;) {
00213
00214 OsiColCut *cut = cs -> colCutPtr (i);
00215
00216 register const CoinPackedVector
00217 &lbs = cut -> lbs (),
00218 &ubs = cut -> ubs ();
00219
00220 register const int *indices = lbs. getIndices ();
00221 register const double *elements = lbs. getElements ();
00222
00223 register CouNumber
00224 *lb = point_ -> lb_,
00225 *ub = point_ -> ub_;
00226
00227
00228
00229 for (register int j = lbs. getNumElements (); j--; elements++, indices++)
00230 if (*elements > lb [*indices])
00231 lb [*indices] = *elements;
00232
00233
00234
00235 indices = ubs. getIndices ();
00236 elements = ubs. getElements ();
00237
00238 for (register int j = ubs. getNumElements (); j--; elements++, indices++)
00239 if (*elements < ub [*indices])
00240 ub [*indices] = *elements;
00241 }
00242 }
00243
00244
00246 void Domain::push (const DomainPoint &dp, bool copy) {
00247
00248 if (point_)
00249 domStack_.push (point_);
00250 point_ = new DomainPoint (dp);
00251 }
00252
00253
00255 void Domain::pop () {
00256
00257 delete point_;
00258 if (!(domStack_.empty ())) {
00259 point_ = domStack_.top ();
00260 domStack_.pop ();
00261 }
00262 else point_ = NULL;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296