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 "CbcBranchActual.hpp"
00017
00018 #include "CouenneTypes.hpp"
00019
00020 #include "CouenneExpression.hpp"
00021 #include "CouenneExprConst.hpp"
00022 #include "CouenneExprQuad.hpp"
00023 #include "CouenneExprClone.hpp"
00024 #include "CouenneExprIVar.hpp"
00025 #include "CouenneExprAux.hpp"
00026 #include "CouenneExprOpp.hpp"
00027
00028 #include "CouenneProblem.hpp"
00029 #include "CouenneGlobalCutOff.hpp"
00030 #include "CouenneProblemElem.hpp"
00031 #include "CouenneDepGraph.hpp"
00032 #include "CouenneLQelems.hpp"
00033
00034 #include "CouenneJournalist.hpp"
00035 #include "CouenneObject.hpp"
00036
00037 using namespace Couenne;
00038
00040
00041 void CouenneProblem::addObjective (expression *newobj, const std::string &sense) {
00042 objectives_ . push_back
00043 (new CouenneObjective ((sense == "min") ?
00044 newobj : new exprOpp (new exprClone (newobj))));
00045 }
00046
00047
00049
00051 void CouenneProblem::addEQConstraint (expression *body, expression *rhs) {
00052
00053 if (!rhs) rhs = new exprConst (0.);
00054 constraints_ . push_back (new CouenneConstraint (body, rhs, new exprClone (rhs)));
00055 }
00056
00058 void CouenneProblem::addGEConstraint (expression *body, expression *rhs) {
00059 if (!rhs) rhs = new exprConst (0.);
00060 constraints_ . push_back (new CouenneConstraint
00061 (body, rhs, new exprConst (COUENNE_INFINITY)));
00062 }
00063
00065 void CouenneProblem::addLEConstraint (expression *body, expression *rhs) {
00066 if (!rhs) rhs = new exprConst (0.);
00067 constraints_ . push_back (new CouenneConstraint
00068 (body, new exprConst (-COUENNE_INFINITY), rhs));
00069 }
00070
00072 void CouenneProblem::setObjective (int indObj, expression * newObj, const std::string &sense) {
00073 objectives_ [indObj] = (new CouenneObjective ((sense == "min") ?
00074 newObj : new exprOpp (new exprClone (newObj))));
00075 }
00076
00077
00079 void CouenneProblem::addRNGConstraint (expression *body, expression *lb, expression *ub) {
00080 if (!lb) lb = new exprConst (0.);
00081 if (!ub) ub = new exprConst (0.);
00082 constraints_ . push_back (new CouenneConstraint (body, lb, ub));
00083 }
00084
00085
00086
00088
00089 expression *CouenneProblem::addVariable (bool isDiscrete, Domain *d) {
00090
00091 exprVar *var = (isDiscrete) ?
00092 (new exprIVar (variables_ . size (), d)) :
00093 (new exprVar (variables_ . size (), d));
00094
00095 variables_ . push_back (var);
00096
00097 if (isDiscrete)
00098 nIntVars_++;
00099
00100 nOrigVars_++;
00101
00102 return var;
00103 }
00104
00105
00108 exprAux *CouenneProblem::addAuxiliary (expression *symbolic) {
00109
00110
00111 std::set <exprAux *, compExpr>::iterator i;
00112
00113 int var_ind = variables_ . size ();
00114 domain_. current () -> resize (var_ind + 1);
00115
00116 symbolic -> getBounds (domain_. lb (var_ind),
00117 domain_. ub (var_ind));
00118
00119
00120 exprAux *w = new exprAux (symbolic,
00121 var_ind,
00122 1 + symbolic -> rank (),
00123 exprAux::Unset,
00124 &domain_);
00125
00126
00127
00128
00129
00130 if ((i = auxSet_ -> find (w)) == auxSet_ -> end ()) {
00131
00132
00133 variables_ . push_back (w);
00134 auxSet_ -> insert (w);
00135 graph_ -> insert (w);
00136
00137 } else {
00138
00139 w -> Image(NULL);
00140 delete w;
00141 w = *i;
00142 (*i) -> increaseMult ();
00143 }
00144
00145 return w;
00146 }
00147
00148
00150 void CouenneProblem::indcoe2vector (int *indexL,
00151 CouNumber *coeff,
00152 std::vector <std::pair <exprVar *, CouNumber> > &lcoeff) {
00153
00154
00155 for (int i=0; indexL [i] >= 0; i++)
00156 lcoeff.push_back (std::pair <exprVar *, CouNumber> (Var (indexL [i]), coeff [i]));
00157 }
00158
00159
00161 void CouenneProblem::indcoe2vector (int *indexI,
00162 int *indexJ,
00163 CouNumber *coeff,
00164 std::vector <quadElem> &qcoeff) {
00165
00166
00167 for (int i=0; indexI [i] >= 0; i++)
00168 qcoeff.push_back (quadElem (Var (indexI [i]), Var (indexJ [i]), coeff [i]));
00169 }
00170
00171
00173 void CouenneProblem::fillIntegerRank () const {
00174
00175 if (integerRank_)
00176 return;
00177
00178 int nvars = nVars ();
00179
00180 integerRank_ = new int [nvars];
00181
00182
00183
00184
00185
00186
00187 for (int ii = 0; ii < nvars; ii++) {
00188
00189 int index = numbering_ [ii];
00190
00191 if (Var (index) -> Multiplicity () <= 0) {
00192 integerRank_ [index] = 0;
00193 continue;
00194 }
00195
00196 bool isInt = Var (index) -> isDefinedInteger ();
00197
00198
00199 integerRank_ [index] = (isInt) ? 1 : 0;
00200
00201 if (Var (index) -> Type () == AUX) {
00202
00203 std::set <int> deplist;
00204
00205 if (Var (index) -> Image () -> DepList (deplist, STOP_AT_AUX) != 0)
00206 for (std::set <int>::iterator i = deplist.begin (); i != deplist.end (); ++i) {
00207
00208 int token = integerRank_ [*i];
00209 if (isInt) token++;
00210
00211 if (token > integerRank_ [index])
00212 integerRank_ [index] = token;
00213 }
00214 }
00215 }
00216
00217 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "Free (original) integers\n");
00218 for (int i=0; i<nOrigVars_; i++)
00219 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, integerRank_ [i]);
00220
00221
00222 for (int i=0; i<nOrigVars_ - ndefined_; i++)
00223 if ((variables_ [i] -> isDefinedInteger ()) &&
00224 (variables_ [i] -> Multiplicity () > 0)) {
00225
00226 int rank = integerRank_ [i];
00227
00228 if (numberInRank_.size () <= (unsigned int) rank)
00229 for (int j=numberInRank_.size (); j <= rank; j++)
00230 numberInRank_ .push_back (0);
00231
00232 numberInRank_ [rank] ++;
00233 }
00234
00235 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "numInteger [neglect non-originals]\n");
00236 for (unsigned int i=0; i<numberInRank_.size(); i++)
00237 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, numberInRank_ [i]);
00238 }
00239
00240
00242 CouNumber CouenneProblem::getCutOff () const
00243 {return pcutoff_ -> getCutOff ();}
00244
00246 CouNumber *CouenneProblem::getCutOffSol () const
00247 {return pcutoff_ -> getCutOffSol ();}
00248
00250 ConstJnlstPtr CouenneProblem::Jnlst () const
00251 {return ConstPtr (jnlst_);}
00252
00253
00254 void CouenneProblem::setLastPrioSort(int givenLastPS) {
00255 lastPrioSort_ = givenLastPS;
00256 }