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 delete w;
00125 w = *i;
00126 (*i) -> increaseMult ();
00127 }
00128
00129 return w;
00130 }
00131
00132
00134 void CouenneProblem::indcoe2vector (int *indexL,
00135 CouNumber *coeff,
00136 std::vector <std::pair <exprVar *, CouNumber> > &lcoeff) {
00137
00138
00139 for (int i=0; indexL [i] >= 0; i++)
00140 lcoeff.push_back (std::pair <exprVar *, CouNumber> (Var (indexL [i]), coeff [i]));
00141 }
00142
00143
00145 void CouenneProblem::indcoe2vector (int *indexI,
00146 int *indexJ,
00147 CouNumber *coeff,
00148 std::vector <quadElem> &qcoeff) {
00149
00150
00151 for (int i=0; indexI [i] >= 0; i++)
00152 qcoeff.push_back (quadElem (Var (indexI [i]), Var (indexJ [i]), coeff [i]));
00153 }
00154
00155
00157 void CouenneProblem::fillIntegerRank () const {
00158
00159 if (integerRank_)
00160 return;
00161
00162 int nvars = nVars ();
00163
00164 integerRank_ = new int [nvars];
00165
00166
00167
00168
00169
00170
00171 for (int ii = 0; ii < nvars; ii++) {
00172
00173 int index = numbering_ [ii];
00174
00175 if (Var (index) -> Multiplicity () <= 0) {
00176 integerRank_ [index] = 0;
00177 continue;
00178 }
00179
00180 bool isInt = Var (index) -> isDefinedInteger ();
00181
00182 integerRank_ [index] = (isInt) ? 1 : 0;
00183
00184 if (Var (index) -> Type () == AUX) {
00185
00186 std::set <int> deplist;
00187
00188 if (Var (index) -> Image () -> DepList (deplist, STOP_AT_AUX) != 0)
00189 for (std::set <int>::iterator i = deplist.begin (); i != deplist.end (); ++i) {
00190
00191 int token = integerRank_ [*i];
00192 if (isInt) token++;
00193
00194 if (token > integerRank_ [index])
00195 integerRank_ [index] = token;
00196 }
00197 }
00198 }
00199
00200 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "Free (original) integers\n");
00201 for (int i=0; i<nOrigVars_; i++)
00202 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, integerRank_ [i]);
00203
00204
00205 for (int i=0; i<nOrigVars_; i++)
00206 if ((variables_ [i] -> isDefinedInteger ()) &&
00207 (variables_ [i] -> Multiplicity () > 0)) {
00208
00209 int rank = integerRank_ [i];
00210
00211 if (numberInRank_.size () <= (unsigned int) rank)
00212 for (int j=numberInRank_.size (); j <= rank; j++)
00213 numberInRank_ .push_back (0);
00214
00215 numberInRank_ [rank] ++;
00216 }
00217
00218 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "numInteger [neglect non-originals]\n");
00219 for (unsigned int i=0; i<numberInRank_.size(); i++)
00220 jnlst_->Printf (Ipopt::J_VECTOR, J_PROBLEM, "%d: %d\n", i, numberInRank_ [i]);
00221 }