00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <vector>
00012
00013 #include "CoinHelperFunctions.hpp"
00014 #include "CoinTime.hpp"
00015
00016 #include "CouenneTypes.hpp"
00017
00018 #include "expression.hpp"
00019 #include "exprConst.hpp"
00020 #include "exprQuad.hpp"
00021 #include "exprClone.hpp"
00022 #include "exprIVar.hpp"
00023 #include "exprAux.hpp"
00024 #include "exprOpp.hpp"
00025
00026 #include "CouenneProblem.hpp"
00027 #include "CouenneProblemElem.hpp"
00028 #include "depGraph.hpp"
00029 #include "lqelems.hpp"
00030
00031
00033
00034 void CouenneProblem::addObjective (expression *newobj, const std::string &sense = "min") {
00035 objectives_ . push_back
00036 (new CouenneObjective ((sense == "min") ?
00037 newobj : new exprOpp (new exprClone (newobj))));
00038 }
00039
00040
00042
00044 void CouenneProblem::addEQConstraint (expression *body, expression *rhs = NULL) {
00045
00046 if (!rhs) rhs = new exprConst (0.);
00047 constraints_ . push_back (new CouenneConstraint (body, rhs, new exprClone (rhs)));
00048 }
00049
00051 void CouenneProblem::addGEConstraint (expression *body, expression *rhs = NULL) {
00052 if (!rhs) rhs = new exprConst (0.);
00053 constraints_ . push_back (new CouenneConstraint
00054 (body, rhs, new exprConst (COUENNE_INFINITY)));
00055 }
00056
00058 void CouenneProblem::addLEConstraint (expression *body, expression *rhs = NULL) {
00059 if (!rhs) rhs = new exprConst (0.);
00060 constraints_ . push_back (new CouenneConstraint
00061 (body, new exprConst (-COUENNE_INFINITY), rhs));
00062 }
00063
00065 void CouenneProblem::addRNGConstraint (expression *body, expression *lb=NULL, expression *ub=NULL) {
00066 if (!lb) lb = new exprConst (0.);
00067 if (!ub) ub = new exprConst (0.);
00068 constraints_ . push_back (new CouenneConstraint (body, lb, ub));
00069 }
00070
00071
00073
00074 expression *CouenneProblem::addVariable (bool isDiscrete, Domain *d) {
00075
00076 exprVar *var = (isDiscrete) ?
00077 (new exprIVar (variables_ . size (), d)) :
00078 (new exprVar (variables_ . size (), d));
00079
00080 variables_ . push_back (var);
00081
00082 if (isDiscrete)
00083 nIntVars_++;
00084
00085 nOrigVars_++;
00086
00087 return var;
00088 }
00089
00090
00093 exprAux *CouenneProblem::addAuxiliary (expression *symbolic) {
00094
00095
00096 std::set <exprAux *, compExpr>::iterator i;
00097
00098 int var_ind = variables_ . size ();
00099 domain_. current () -> resize (var_ind + 1);
00100
00101 symbolic -> getBounds (domain_. lb (var_ind),
00102 domain_. ub (var_ind));
00103
00104
00105 exprAux *w = new exprAux (symbolic,
00106 var_ind,
00107 1 + symbolic -> rank (),
00108 exprAux::Unset,
00109 &domain_);
00110
00111
00112
00113
00114
00115 if ((i = auxSet_ -> find (w)) == auxSet_ -> end ()) {
00116
00117
00118 variables_ . push_back (w);
00119 auxSet_ -> insert (w);
00120 graph_ -> insert (w);
00121
00122 } else {
00123
00124 w->Image(NULL);
00125 delete w;
00126 w = *i;
00127 (*i) -> increaseMult ();
00128 }
00129
00130 return w;
00131 }
00132
00133
00135 void CouenneProblem::indcoe2vector (int *indexL,
00136 CouNumber *coeff,
00137 std::vector <std::pair <exprVar *, CouNumber> > &lcoeff) {
00138
00139
00140 for (int i=0; indexL [i] >= 0; i++)
00141 lcoeff.push_back (std::pair <exprVar *, CouNumber> (Var (indexL [i]), coeff [i]));
00142 }
00143
00144
00146 void CouenneProblem::indcoe2vector (int *indexI,
00147 int *indexJ,
00148 CouNumber *coeff,
00149 std::vector <quadElem> &qcoeff) {
00150
00151
00152 for (int i=0; indexI [i] >= 0; i++)
00153 qcoeff.push_back (quadElem (Var (indexI [i]), Var (indexJ [i]), coeff [i]));
00154 }
00155
00156
00158 void CouenneProblem::fillIntegerRank () const {
00159
00160 if (integerRank_)
00161 return;
00162
00163 int nvars = nVars ();
00164
00165 integerRank_ = new int [nvars];
00166
00167
00168
00169
00170
00171
00172 for (int ii = 0; ii < nvars; ii++) {
00173
00174 int index = numbering_ [ii];
00175
00176 if (Var (index) -> Multiplicity () <= 0) {
00177 integerRank_ [index] = 0;
00178 continue;
00179 }
00180
00181 bool isInt = Var (index) -> isDefinedInteger ();
00182
00183 integerRank_ [index] = (isInt) ? 1 : 0;
00184
00185 if (Var (index) -> Type () == AUX) {
00186
00187 std::set <int> deplist;
00188
00189 if (Var (index) -> Image () -> DepList (deplist, STOP_AT_AUX) != 0)
00190 for (std::set <int>::iterator i = deplist.begin (); i != deplist.end (); ++i) {
00191
00192 int token = integerRank_ [*i];
00193 if (isInt) token++;
00194
00195 if (token > integerRank_ [index])
00196 integerRank_ [index] = token;
00197 }
00198 }
00199 }
00200
00201 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "Free (original) integers\n");
00202 for (int i=0; i<nOrigVars_; i++)
00203 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, integerRank_ [i]);
00204
00205
00206 for (int i=0; i<nOrigVars_; i++)
00207 if ((variables_ [i] -> isDefinedInteger ()) &&
00208 (variables_ [i] -> Multiplicity () > 0)) {
00209
00210 int rank = integerRank_ [i];
00211
00212 if (numberInRank_.size () <= (unsigned int) rank)
00213 for (int j=numberInRank_.size (); j <= rank; j++)
00214 numberInRank_ .push_back (0);
00215
00216 numberInRank_ [rank] ++;
00217 }
00218
00219 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "numInteger [neglect non-originals]\n");
00220 for (unsigned int i=0; i<numberInRank_.size(); i++)
00221 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, numberInRank_ [i]);
00222 }
00223
00224
00227 bool BranchingFBBT (CouenneProblem *problem,
00228 OsiObject *Object,
00229 OsiSolverInterface *solver) {
00230
00231 bool feasible = true;
00232
00233 if (problem -> doFBBT ()) {
00234
00235 int
00236 indVar = Object -> columnNumber (),
00237 nvars = problem -> nVars ();
00238
00239 t_chg_bounds *chg_bds = new t_chg_bounds [nvars];
00240 chg_bds [indVar].setUpper (t_chg_bounds::CHANGED);
00241 problem -> installCutOff ();
00242
00243 if ((feasible = problem -> btCore (chg_bds))) {
00244
00245 const double
00246 *lb = solver -> getColLower (),
00247 *ub = solver -> getColUpper ();
00248
00249 for (int i=0; i<nvars; i++) {
00250 if (problem -> Lb (i) > lb [i]) solver -> setColLower (i, problem -> Lb (i));
00251 if (problem -> Ub (i) < ub [i]) solver -> setColUpper (i, problem -> Ub (i));
00252 }
00253 }
00254
00255 delete [] chg_bds;
00256 }
00257
00258 return feasible;
00259 }