/home/coin/SVN-release/OS-2.1.0/Bcp/src/LP/BCP_lp_misc.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #include "BCP_warmstart.hpp"
00005 #include "BCP_lp_result.hpp"
00006 #include "BCP_lp_node.hpp"
00007 #include "BCP_lp.hpp"
00008 #include "BCP_lp_functions.hpp"
00009 #include "BCP_lp_user.hpp"
00010 #include "BCP_solution.hpp"
00011 
00012 //#############################################################################
00013 
00014 void BCP_lp_process_result(BCP_lp_prob& p, const BCP_lp_result& lpres)
00015 {
00016   p.user_has_lp_result_processing = true;
00017   p.user->process_lp_result(lpres, p.node->vars, p.node->cuts,
00018                             p.node->true_lower_bound,
00019                             p.new_true_lower_bound, p.sol,
00020                             p.new_cuts, p.new_rows, p.new_vars, p.new_cols);
00021 }
00022 
00023 //#############################################################################
00024 
00025 void BCP_lp_purge_slack_pool(BCP_lp_prob& p)
00026 {
00027   BCP_vec<int> purge;
00028   p.user->purge_slack_pool(p.slack_pool, purge);
00029   if (purge.size() > 0)
00030     purge_ptr_vector_by_index(p.slack_pool, purge.begin(), purge.end());
00031 }
00032 
00033 //#############################################################################
00034 
00035 void BCP_lp_test_feasibility(BCP_lp_prob& p, const BCP_lp_result& lpres)
00036 {
00037   BCP_solution* sol = p.user_has_lp_result_processing ? p.sol :
00038     p.user->test_feasibility(lpres, p.node->vars, p.node->cuts);
00039   p.sol = NULL;
00040 
00041   if (sol) {
00042     // send the feas sol to the tree manager (that routine also displays)
00043     p.user->send_feasible_solution(sol);
00044     delete sol;
00045   }
00046 }
00047 
00048 //#############################################################################
00049 
00050 double BCP_lp_compute_lower_bound(BCP_lp_prob& p, const BCP_lp_result& lpres)
00051 {
00052   return p.user_has_lp_result_processing ? p.new_true_lower_bound :
00053     p.user->compute_lower_bound(p.node->true_lower_bound,
00054                                 lpres, p.node->vars, p.node->cuts);
00055 }
00056 
00057 //#############################################################################
00058 
00059 void BCP_lp_clean_up_node(BCP_lp_prob& p)
00060 {
00061   p.node->clean();
00062   BCP_vec<BCP_var*>& vars = p.node->vars;
00063   purge_ptr_vector(vars, vars.entry(p.core->varnum()), vars.end());
00064   BCP_vec<BCP_cut*>& cuts = p.node->cuts;
00065   purge_ptr_vector(cuts, cuts.entry(p.core->cutnum()), cuts.end());
00066   p.parent->clean();
00067   // Also, the local pools might contain only locally valid
00068   // cuts/vars, so get rid of them
00069   purge_ptr_vector(*p.local_cut_pool);
00070   purge_ptr_vector(*p.local_var_pool);
00071 }
00072 
00073 //#############################################################################
00074 
00075 BCP_message_tag BCP_lp_pack_for_cg(BCP_lp_prob& p)
00076 {
00077   BCP_buffer& buf = p.msg_buf;
00078   buf.clear();
00079   buf.pack(p.node->level).pack(p.node->index).pack(p.node->iteration_count);
00080 
00081   buf.set_msgtag(BCP_Msg_ForCG_User);
00082 
00083   p.user->pack_primal_solution(buf, *p.lp_result,
00084                                p.node->vars, p.node->cuts);
00085 
00086   return buf.msgtag();
00087 }
00088 
00089 //#############################################################################
00090 
00091 BCP_message_tag BCP_lp_pack_for_vg(BCP_lp_prob& p)
00092 {
00093   BCP_buffer& buf = p.msg_buf;
00094   buf.clear();
00095   buf.pack(p.node->level).pack(p.node->index).pack(p.node->iteration_count);
00096 
00097   buf.set_msgtag(BCP_Msg_ForVG_User);
00098 
00099   p.user->pack_dual_solution(buf, *p.lp_result,
00100                              p.node->vars, p.node->cuts);
00101 
00102   return buf.msgtag();
00103 }
00104 
00105 //#############################################################################
00106 
00107 void
00108 BCP_lp_prepare_for_new_node(BCP_lp_prob& p)
00109 {
00110   int i;
00111 
00112   BCP_var_set& vars = p.node->vars;
00113   BCP_cut_set& cuts = p.node->cuts;
00114 
00115   BCP_vec<int> vcp;
00116   BCP_vec<double> vbd;
00117   BCP_vec<int> ccp;
00118   BCP_vec<double> cbd;
00119 
00120   const int varnum = vars.size();
00121   BCP_vec<BCP_obj_status> vstat;
00122   vstat.reserve(varnum);
00123   for (i = 0; i < varnum; ++i) {
00124     vstat.unchecked_push_back(vars[i]->status());
00125   }
00126 
00127   const int cutnum = cuts.size();
00128   BCP_vec<BCP_obj_status> cstat;
00129   cstat.reserve(cutnum);
00130   for (i = 0; i < cutnum; ++i) {
00131     cstat.unchecked_push_back(cuts[i]->status());
00132   }
00133 
00134   p.user->initialize_new_search_tree_node(vars, cuts, vstat, cstat,
00135                                           vcp, vbd, ccp, cbd);
00136 
00137   p.sol = NULL;
00138 
00139   if (2 * vcp.size() != vbd.size()) {
00140     throw BCP_fatal_error("new node init returned uneven var vectors\n");
00141   }
00142   if (2 * ccp.size() != cbd.size()) {
00143     throw BCP_fatal_error("new node init returned uneven cut vectors\n");
00144   }
00145 
00146   const double petol = p.lp_result->primalTolerance();
00147 
00148   OsiSolverInterface& lp = *p.lp_solver;
00149 
00150   const int var_change_num = vcp.size();
00151   if (var_change_num > 0) {
00152     BCP_vec<double>::const_iterator newbd = vbd.begin();
00153     // check that the new bounds are actually tighter than the old ones.
00154     // throw an exception if not.
00155     for (i = 0; i < var_change_num; ++i) {
00156       const double new_lb = *newbd;
00157       ++newbd;
00158       const double new_ub = *newbd;
00159       ++newbd;
00160       const int pos = vcp[i];
00161       if (vars[pos]->lb() > new_lb+petol || vars[pos]->ub() < new_ub-petol)
00162         throw BCP_fatal_error("new node init enlarged var feas region!\n");
00163     }
00164     lp.setColSetBounds(vcp.begin(), vcp.end(), vbd.begin());
00165     vars.set_lb_ub(vcp, vbd.begin());
00166   }
00167 
00168   const int cut_change_num = ccp.size();
00169   if (cut_change_num > 0) {
00170     BCP_vec<double>::const_iterator newbd = cbd.begin();
00171     // check that the new bounds are actually tighter than the old ones.
00172     // throw an exception if not.
00173     for (i = 0; i < cut_change_num; ++i) {
00174       const double new_lb = *newbd;
00175       ++newbd;
00176       const double new_ub = *newbd;
00177       ++newbd;
00178       const int pos = ccp[i];
00179       if (cuts[pos]->lb() > new_lb+petol || cuts[pos]->ub() < new_ub-petol)
00180         throw BCP_fatal_error("new node init enlarged cut feas region!\n");
00181     }
00182     lp.setRowSetBounds(ccp.begin(), ccp.end(), cbd.begin());
00183     cuts.set_lb_ub(ccp, cbd.begin());
00184   }
00185 
00186   if (lp.numberObjects() == 0) {
00187     if (!p.intAndSosObjects.empty()) {
00188       lp.addObjects(p.intAndSosObjects.size(), &p.intAndSosObjects[0]);
00189       const int numObj = lp.numberObjects();
00190       OsiObject** obj = lp.objects();
00191       for (int i = 0; i < numObj; ++i) {
00192         OsiSimpleInteger* io = dynamic_cast<OsiSimpleInteger*>(obj[i]);
00193         if (io) {
00194           io->resetBounds(&lp);
00195         } else {
00196           // The rest is OsiSOS where we don't need to do anything
00197           break;
00198         }
00199       }
00200     } else {
00201       for (int i = 0; i < varnum; ++i) {
00202         if (vars[i]->var_type() != BCP_ContinuousVar) {
00203           lp.setInteger(i);
00204         }
00205       }
00206       lp.findIntegersAndSOS(false);
00207     }
00208   }
00209 
00210   // If there is a root warmstart info then set it
00211   if (p.param(BCP_lp_par::WarmstartInfo) == BCP_WarmstartRoot &&
00212       p.warmstartRoot != NULL) {
00213     lp.setWarmStart(p.warmstartRoot);
00214   }
00215 }
00216 
00217 //#############################################################################
00218 
00219 void
00220 BCP_lp_add_cols_to_lp(const BCP_vec<BCP_col*>& cols, OsiSolverInterface* lp)
00221 {
00222   const int colnum = cols.size();
00223   double * clb = new double[colnum];
00224   double * cub = new double[colnum];
00225   double * obj = new double[colnum];
00226   const CoinPackedVectorBase** vectors =
00227     new const CoinPackedVectorBase*[colnum];
00228   for (int i = 0; i < colnum; ++i) {
00229     const BCP_col * col = cols[i];
00230     vectors[i] = col;
00231     clb[i] = col->LowerBound();
00232     cub[i] = col->UpperBound();
00233     obj[i] = col->Objective();
00234   }
00235   lp->addCols(colnum, vectors, clb, cub, obj);
00236   delete[] vectors;
00237   delete[] obj;
00238   delete[] cub;
00239   delete[] clb;
00240 }
00241 
00242 //#############################################################################
00243 
00244 void
00245 BCP_lp_add_rows_to_lp(const BCP_vec<BCP_row*>& rows, OsiSolverInterface* lp)
00246 {
00247   const int rownum = rows.size();
00248   double * rlb = new double[rownum];
00249   double * rub = new double[rownum];
00250   const CoinPackedVectorBase** vectors =
00251     new const CoinPackedVectorBase*[rownum];
00252   for (int i = 0; i < rownum; ++i) {
00253     const BCP_row * row = rows[i];
00254     vectors[i] = row;
00255     rlb[i] = row->LowerBound();
00256     rub[i] = row->UpperBound();
00257   }
00258   lp->addRows(rownum, vectors, rlb, rub);
00259   delete[] vectors;
00260   delete[] rub;
00261   delete[] rlb;
00262 }

Generated on Tue Mar 30 03:04:32 2010 by  doxygen 1.4.7