BCP_lp_misc.cpp
Go to the documentation of this file.
1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others. All Rights Reserved.
3 
4 #include "BCP_warmstart.hpp"
5 #include "BCP_lp_result.hpp"
6 #include "BCP_lp_node.hpp"
7 #include "BCP_lp.hpp"
8 #include "BCP_lp_functions.hpp"
9 #include "BCP_lp_user.hpp"
10 #include "BCP_solution.hpp"
11 
12 //#############################################################################
13 
15 {
17  p.user->process_lp_result(lpres, p.node->vars, p.node->cuts,
20  p.new_cuts, p.new_rows, p.new_vars, p.new_cols);
21 }
22 
23 //#############################################################################
24 
26 {
27  BCP_vec<int> purge;
28  p.user->purge_slack_pool(p.slack_pool, purge);
29  if (purge.size() > 0)
30  purge_ptr_vector_by_index(p.slack_pool, purge.begin(), purge.end());
31 }
32 
33 //#############################################################################
34 
36 {
38  p.user->test_feasibility(lpres, p.node->vars, p.node->cuts);
39  p.sol = NULL;
40 
41  if (sol) {
42  // send the feas sol to the tree manager (that routine also displays)
44  delete sol;
45  }
46 }
47 
48 //#############################################################################
49 
51 {
54  lpres, p.node->vars, p.node->cuts);
55 }
56 
57 //#############################################################################
58 
60 {
61  p.node->clean();
62  BCP_vec<BCP_var*>& vars = p.node->vars;
63  purge_ptr_vector(vars, vars.entry(p.core->varnum()), vars.end());
64  BCP_vec<BCP_cut*>& cuts = p.node->cuts;
65  purge_ptr_vector(cuts, cuts.entry(p.core->cutnum()), cuts.end());
66  p.parent->clean();
67  // Also, the local pools might contain only locally valid
68  // cuts/vars, so get rid of them
71 }
72 
73 //#############################################################################
74 
76 {
77  BCP_buffer& buf = p.msg_buf;
78  buf.clear();
80 
82 
84  p.node->vars, p.node->cuts);
85 
86  return buf.msgtag();
87 }
88 
89 //#############################################################################
90 
92 {
93  BCP_buffer& buf = p.msg_buf;
94  buf.clear();
96 
98 
100  p.node->vars, p.node->cuts);
101 
102  return buf.msgtag();
103 }
104 
105 //#############################################################################
106 
107 void
109 {
110  int i;
111 
112  BCP_var_set& vars = p.node->vars;
113  BCP_cut_set& cuts = p.node->cuts;
114 
115  BCP_vec<int> vcp;
116  BCP_vec<double> vbd;
117  BCP_vec<int> ccp;
118  BCP_vec<double> cbd;
119 
120  const int varnum = vars.size();
122  vstat.reserve(varnum);
123  for (i = 0; i < varnum; ++i) {
124  vstat.unchecked_push_back(vars[i]->status());
125  }
126 
127  const int cutnum = cuts.size();
129  cstat.reserve(cutnum);
130  for (i = 0; i < cutnum; ++i) {
131  cstat.unchecked_push_back(cuts[i]->status());
132  }
133 
134  p.user->initialize_new_search_tree_node(vars, cuts, vstat, cstat,
135  vcp, vbd, ccp, cbd);
136 
137  p.sol = NULL;
138 
139  if (2 * vcp.size() != vbd.size()) {
140  throw BCP_fatal_error("new node init returned uneven var vectors\n");
141  }
142  if (2 * ccp.size() != cbd.size()) {
143  throw BCP_fatal_error("new node init returned uneven cut vectors\n");
144  }
145 
146  const double petol = p.lp_result->primalTolerance();
147 
148  OsiSolverInterface& lp = *p.lp_solver;
149 
150  const int var_change_num = vcp.size();
151  if (var_change_num > 0) {
153  // check that the new bounds are actually tighter than the old ones.
154  // throw an exception if not.
155  for (i = 0; i < var_change_num; ++i) {
156  const double new_lb = *newbd;
157  ++newbd;
158  const double new_ub = *newbd;
159  ++newbd;
160  const int pos = vcp[i];
161  if (vars[pos]->lb() > new_lb+petol || vars[pos]->ub() < new_ub-petol)
162  throw BCP_fatal_error("new node init enlarged var feas region!\n");
163  }
164  lp.setColSetBounds(vcp.begin(), vcp.end(), vbd.begin());
165  vars.set_lb_ub(vcp, vbd.begin());
166  }
167 
168  const int cut_change_num = ccp.size();
169  if (cut_change_num > 0) {
171  // check that the new bounds are actually tighter than the old ones.
172  // throw an exception if not.
173  for (i = 0; i < cut_change_num; ++i) {
174  const double new_lb = *newbd;
175  ++newbd;
176  const double new_ub = *newbd;
177  ++newbd;
178  const int pos = ccp[i];
179  if (cuts[pos]->lb() > new_lb+petol || cuts[pos]->ub() < new_ub-petol)
180  throw BCP_fatal_error("new node init enlarged cut feas region!\n");
181  }
182  lp.setRowSetBounds(ccp.begin(), ccp.end(), cbd.begin());
183  cuts.set_lb_ub(ccp, cbd.begin());
184  }
185 
186  if (lp.numberObjects() == 0) {
187  if (!p.intAndSosObjects.empty()) {
188  lp.addObjects(p.intAndSosObjects.size(), &p.intAndSosObjects[0]);
189  const int numObj = lp.numberObjects();
190  OsiObject** obj = lp.objects();
191  for (int i = 0; i < numObj; ++i) {
192  OsiSimpleInteger* io = dynamic_cast<OsiSimpleInteger*>(obj[i]);
193  if (io) {
194  io->resetBounds(&lp);
195  } else {
196  // The rest is OsiSOS where we don't need to do anything
197  break;
198  }
199  }
200  } else {
201  for (int i = 0; i < varnum; ++i) {
202  if (vars[i]->var_type() != BCP_ContinuousVar) {
203  lp.setInteger(i);
204  }
205  }
206  lp.findIntegersAndSOS(false);
207  }
208  }
209 
210  // If there is a root warmstart info then set it
212  p.warmstartRoot != NULL) {
213  lp.setWarmStart(p.warmstartRoot);
214  }
215 }
216 
217 //#############################################################################
218 
219 void
220 BCP_lp_add_cols_to_lp(const BCP_vec<BCP_col*>& cols, OsiSolverInterface* lp)
221 {
222  const int colnum = cols.size();
223  double * clb = new double[colnum];
224  double * cub = new double[colnum];
225  double * obj = new double[colnum];
226  const CoinPackedVectorBase** vectors =
227  new const CoinPackedVectorBase*[colnum];
228  for (int i = 0; i < colnum; ++i) {
229  const BCP_col * col = cols[i];
230  vectors[i] = col;
231  clb[i] = col->LowerBound();
232  cub[i] = col->UpperBound();
233  obj[i] = col->Objective();
234  }
235  lp->addCols(colnum, vectors, clb, cub, obj);
236  delete[] vectors;
237  delete[] obj;
238  delete[] cub;
239  delete[] clb;
240 }
241 
242 //#############################################################################
243 
244 void
245 BCP_lp_add_rows_to_lp(const BCP_vec<BCP_row*>& rows, OsiSolverInterface* lp)
246 {
247  const int rownum = rows.size();
248  double * rlb = new double[rownum];
249  double * rub = new double[rownum];
250  const CoinPackedVectorBase** vectors =
251  new const CoinPackedVectorBase*[rownum];
252  for (int i = 0; i < rownum; ++i) {
253  const BCP_row * row = rows[i];
254  vectors[i] = row;
255  rlb[i] = row->LowerBound();
256  rub[i] = row->UpperBound();
257  }
258  lp->addRows(rownum, vectors, rlb, rub);
259  delete[] vectors;
260  delete[] rub;
261  delete[] rlb;
262 }
double LowerBound() const
Return the lower bound.
Definition: BCP_matrix.hpp:167
void BCP_lp_add_rows_to_lp(const BCP_vec< BCP_row * > &rows, OsiSolverInterface *lp)
BCP_message_tag
This enumerative constant describes the message tags different processes of BCP understand.
This class holds a column in a compressed form.
Definition: BCP_matrix.hpp:26
BCP_buffer & pack(const T &value)
Pack a single object of type T.
Definition: BCP_buffer.hpp:177
double LowerBound() const
Return the lower bound.
Definition: BCP_matrix.hpp:46
double UpperBound() const
Return the upper bound.
Definition: BCP_matrix.hpp:48
BCP_lp_node * node
Description he current search tree node.
Definition: BCP_lp.hpp:168
virtual void process_lp_result(const BCP_lp_result &lpres, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts, const double old_lower_bound, double &true_lower_bound, BCP_solution *&sol, BCP_vec< BCP_cut * > &new_cuts, BCP_vec< BCP_row * > &new_rows, BCP_vec< BCP_var * > &new_vars, BCP_vec< BCP_col * > &new_cols)
Process the result of an iteration.
BCP_lp_parent * parent
Description of the parent of the current node.
Definition: BCP_lp.hpp:170
pos
position where the operator should be printed when printing the expression
char param(BCP_lp_par::chr_params key) const
Definition: BCP_lp.hpp:275
BCP_var_set vars
void BCP_lp_process_result(BCP_lp_prob &p, const BCP_lp_result &lpres)
Definition: BCP_lp_misc.cpp:14
void BCP_lp_add_cols_to_lp(const BCP_vec< BCP_col * > &cols, OsiSolverInterface *lp)
void BCP_lp_test_feasibility(BCP_lp_prob &p, const BCP_lp_result &lpres)
Definition: BCP_lp_misc.cpp:35
virtual double compute_lower_bound(const double old_lower_bound, const BCP_lp_result &lpres, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts)
Compute a true lower bound for the subproblem.
iterator begin()
Return an iterator to the beginning of the object.
Definition: BCP_vector.hpp:99
NO OLD DOC.
Definition: BCP_lp.hpp:102
This class is just a collection of pointers to cuts with a number of methods to manipulate these cuts...
Definition: BCP_cut.hpp:279
void reserve(const size_t n)
Reallocate the object to make space for n entries.
virtual void pack_primal_solution(BCP_buffer &buf, const BCP_lp_result &lp_result, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts)
Pack the information necessary for cut generation into the buffer.
BCP_solution * sol
Definition: BCP_lp.hpp:249
double BCP_lp_compute_lower_bound(BCP_lp_prob &p, const BCP_lp_result &lpres)
Definition: BCP_lp_misc.cpp:50
The user packed everything.
virtual void purge_slack_pool(const BCP_vec< BCP_cut * > &slack_pool, BCP_vec< int > &to_be_purged)
Selectively purge the list of slack cuts.
BCP_vec< BCP_var * > new_vars
Definition: BCP_lp.hpp:247
size_t varnum() const
Return the number of variables in the core.
BCP_cut_set cuts
Specifies how warmstart information should be stored in the TM.
BCP_lp_cut_pool * local_cut_pool
Definition: BCP_lp.hpp:193
The user packed everything.
double primalTolerance() const
Return the primal tolerance of the solver.
BCP_lp_user * user
A class that holds the methods about how to pack things.
Definition: BCP_lp.hpp:131
void fint fint fint real fint real real real real real real real real real fint real fint * lp
BCP_message_tag BCP_lp_pack_for_vg(BCP_lp_prob &p)
Definition: BCP_lp_misc.cpp:91
OsiSolverInterface * lp_solver
A class that holds the methods about how to pack things.
Definition: BCP_lp.hpp:137
BCP_lp_result * lp_result
Definition: BCP_lp.hpp:185
CoinWarmStart * warmstartRoot
Description of the warmstart info from the end of the root node.
Definition: BCP_lp.hpp:174
void set_msgtag(const BCP_message_tag tag)
Set the message tag on the buffer.
Definition: BCP_buffer.hpp:116
size_t cutnum() const
Return the number of cuts in the core.
double Objective() const
Return the objective coefficient.
Definition: BCP_matrix.hpp:44
BCP_lp_var_pool * local_var_pool
Definition: BCP_lp.hpp:191
void clear()
Completely clear the buffer.
Definition: BCP_buffer.hpp:168
BCP_message_tag msgtag() const
Return the message tag of the message in the buffer.
Definition: BCP_buffer.hpp:90
Use the warmstart info from the end of the root in all search tree nodes.
Definition: BCP_enum.hpp:238
Continuous variable.
Definition: BCP_enum.hpp:167
void set_lb_ub(const BCP_vec< int > &pos, BCP_vec< double >::const_iterator bounds)
Set the lower/upper bound pairs of the entries given by the contents of pos to the values in [bounds...
Definition: BCP_var.cpp:10
void BCP_lp_purge_slack_pool(BCP_lp_prob &p)
Definition: BCP_lp_misc.cpp:25
bool user_has_lp_result_processing
Definition: BCP_lp.hpp:244
virtual BCP_solution * test_feasibility(const BCP_lp_result &lp_result, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts)
Evaluate and return MIP feasibility of the current solution.
Currently there isn&#39;t any error handling in BCP.
Definition: BCP_error.hpp:20
double UpperBound() const
Return the upper bound.
Definition: BCP_matrix.hpp:169
void BCP_lp_prepare_for_new_node(BCP_lp_prob &p)
void BCP_lp_clean_up_node(BCP_lp_prob &p)
Definition: BCP_lp_misc.cpp:59
size_t size() const
Return the current number of entries.
Definition: BCP_vector.hpp:116
BCP_vec< BCP_cut * > slack_pool
Definition: BCP_lp.hpp:189
iterator end()
Return an iterator to the end of the object.
Definition: BCP_vector.hpp:104
This class is just a collection of pointers to variables with a number of methods to manipulate these...
Definition: BCP_var.hpp:316
std::vector< OsiObject * > intAndSosObjects
Things that can be branched on.
Definition: BCP_lp.hpp:161
double true_lower_bound
This class describes the message buffer used for all processes of BCP.
Definition: BCP_buffer.hpp:39
BCP_message_tag BCP_lp_pack_for_cg(BCP_lp_prob &p)
Definition: BCP_lp_misc.cpp:75
void unchecked_push_back(const_reference x)
Append x to the end of the vector.
void purge_ptr_vector_by_index(BCP_vec< T * > &pvec, typename BCP_vec< int >::const_iterator first, typename BCP_vec< int >::const_iterator last)
This function purges the entries indexed by [first,last) from the vector of pointers pvec...
Definition: BCP_vector.hpp:297
BCP_problem_core * core
Definition: BCP_lp.hpp:153
BCP_vec< BCP_cut * > new_cuts
Definition: BCP_lp.hpp:245
void purge_ptr_vector(BCP_vec< T * > &pvec, typename BCP_vec< T * >::iterator first, typename BCP_vec< T * >::iterator last)
This function purges the entries [first,last) from the vector of pointers pvec.
Definition: BCP_vector.hpp:266
void set_lb_ub(const BCP_vec< int > &pos, BCP_vec< double >::const_iterator bounds)
Set the lower/upper bound pairs of the entries given by the contents of pos to the values in [bounds...
Definition: BCP_cut.cpp:12
double new_true_lower_bound
Definition: BCP_lp.hpp:250
This class holds the results after solving an LP relaxation.
BCP_vec< BCP_row * > new_rows
Definition: BCP_lp.hpp:246
iterator entry(const int i)
Return an iterator to the i-th entry.
Definition: BCP_vector.hpp:109
virtual void pack_dual_solution(BCP_buffer &buf, const BCP_lp_result &lp_result, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts)
Pack the information necessary for variable generation into the buffer.
void send_feasible_solution(const BCP_solution *sol)
Definition: BCP_lp_user.cpp:77
BCP_buffer msg_buf
Definition: BCP_lp.hpp:239
BCP_vec< BCP_col * > new_cols
Definition: BCP_lp.hpp:248
virtual void initialize_new_search_tree_node(const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts, const BCP_vec< BCP_obj_status > &var_status, const BCP_vec< BCP_obj_status > &cut_status, BCP_vec< int > &var_changed_pos, BCP_vec< double > &var_new_bd, BCP_vec< int > &cut_changed_pos, BCP_vec< double > &cut_new_bd)
Initializing a new search tree node.
This class holds a row in a compressed form.
Definition: BCP_matrix.hpp:152
This is the abstract base class for a solution to a Mixed Integer Programming problem.
void clean()
Definition: BCP_lp_node.cpp:17