/home/coin/SVN-release/OS-2.2.0/Couenne/src/problem/CouenneProblem.cpp

Go to the documentation of this file.
00001 /* $Id: CouenneProblem.cpp 236 2009-07-19 16:15:55Z pbelotti $ */
00002 /*
00003  * Name:    CouenneProblem.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: methods of the class CouenneProblem
00006  *
00007  * (C) Carnegie-Mellon University, 2006-09.
00008  * This file is licensed under the Common Public License (CPL)
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   // check if image is already in the expression database auxSet_
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   // create new aux associated with that expression
00105   exprAux *w = new exprAux (symbolic,
00106                             var_ind,
00107                             1 + symbolic -> rank (), 
00108                             exprAux::Unset, 
00109                             &domain_);
00110   //symbolic -> isInteger () ? exprAux::Integer : exprAux::Continuous);
00111 
00112   //  w -> linkDomain (&domain_);
00113 
00114   // seek expression in the set
00115   if ((i = auxSet_ -> find (w)) == auxSet_ -> end ()) {
00116 
00117     // no such expression found in the set, create entry therein
00118     variables_ . push_back (w);
00119     auxSet_ -> insert (w); // insert into repetition checking structure
00120     graph_  -> insert (w); // insert into acyclic structure
00121 
00122   } else {  // otherwise, just return the entry's pointer
00123 
00124     w->Image(NULL); // otherwise "delete w" will also delete user given expression "symbolic"
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   // TODO: sort
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   // TODO: sort
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   // 0: fractional
00168   // 1: integer
00169   // k: integer,    depending on at least one integer with associated value k-1, or
00170   // k: fractional, depending on at least one integer with associated value k
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) // depends on something
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]) // there's a free integer below us
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   // fill in numberInRank_
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 }

Generated on Thu Aug 5 03:02:57 2010 by  doxygen 1.4.7