8 #include "CoinWarmStart.hpp"
9 #include "CoinTime.hpp"
25 static inline std::pair<int,int>
31 const int added_col_num,
32 const int added_row_num);
43 const int orig_varnum,
44 const int candidate_num,
const int selected,
50 p.
user->
print(
true,
"\nLP: SB selected candidate %i out of %i.\n\n",
51 selected, candidate_num);
52 p.
user->
print(
true,
"LP: The selected object is:");
58 for (
int i = 0; i < can->
child_num; ++i) {
60 const double lb = res.
objval();
62 (lb>
BCP_DBL_MAX/10 ?
" [%e,%i,%i]":
" [%.4f,%i,%i]"),
70 for (
int i = can->
child_num - 1; i >= 0; --i)
76 p.
user->
print(
true,
"LP: Child %i is fathomed.\n", i);
84 static inline std::pair<int,int>
88 if (candidates.
size() == 0)
89 return std::pair<int,int>(0, 0);
100 for (cani = candidates.
begin(); cani != lastcani; ++cani){
103 cuts.
size() + newcut_num);
110 const int orig_col_num = vars.
size();
111 const int orig_row_num = cuts.
size();
119 for (cani = candidates.
begin(); cani != lastcani; ++cani){
132 for (
int i = 0; i < newvar_num; ++i) {
142 for (cani = candidates.
begin(); cani != lastcani; ++cani){
161 for (
int i = 0; i < newcut_num; ++i) {
173 if (newvar_num > 0) {
174 for (
int i = orig_col_num; i < orig_col_num + newvar_num; ++i)
175 lp->setColBounds(i, 0.0, 0.0);
177 if (newcut_num > 0) {
178 const double inf = lp->getInfinity();
179 for (
int i = orig_row_num; i < orig_row_num + newcut_num; ++i)
180 lp->setRowBounds(i, -inf, inf);
183 return std::pair<int,int>(newvar_num, newcut_num);
191 const int added_col_num,
192 const int added_row_num)
198 for ( ; ii != lastii; ++ii)
199 vars[*ii]->make_non_removable();
206 for ( ; ii != lastii; ++ii)
207 vars[*ii]->make_active();
213 for ( ; vari != lastvari; ++vari) {
214 if (! (*vari)->is_non_removable())
223 for ( ; ii != lastii; ++ii)
224 cuts[*ii]->make_non_removable();
231 for ( ; ii != lastii; ++ii)
232 cuts[*ii]->make_active();
234 if (added_row_num > 0){
237 for ( ; cuti != lastcuti; ++cuti) {
238 if (! (*cuti)->is_non_removable())
255 const int orig_colnum = vars.
size();
257 const std::pair<int,int> added_object_num =
260 const int added_colnum = added_object_num.first;
261 const int added_rownum = added_object_num.second;
263 const int colnum = vars.
size();
264 const int rownum = cuts.
size();
268 const CoinWarmStart *
ws = p.
lp_solver->getWarmStart();
277 const int maxind = std::max<int>(rownum, colnum);
279 for (i = 0; i < maxind; ++i)
282 const double * rlb_orig = lp->getRowLower();
283 const double * rub_orig = lp->getRowUpper();
284 for (j = -1, i = 0; i < rownum; ++i) {
285 rowbounds[++
j] = rlb_orig[i];
286 rowbounds[++
j] = rub_orig[i];
289 const double * clb_orig = lp->getColLower();
290 const double * cub_orig = lp->getColUpper();
291 for (j = -1, i = 0; i < colnum; ++i) {
292 colbounds[++
j] = clb_orig[i];
293 colbounds[++
j] = cub_orig[i];
302 lp->setIntParam(OsiMaxNumIterationHotStart,
307 "\nLP: Starting strong branching:\n\n");
312 for (cani = candidates.
begin(); cani != candidates.
end(); ++cani){
324 sprintf(fname,
"matrix-%i.%i.%i-child-%i.%i",
327 lp->writeMps(fname,
"mps");
329 lp->solveFromHotStart();
341 lp->setRowSetBounds(all_indices.begin(), all_indices.entry(rownum),
344 lp->setColSetBounds(all_indices.begin(), all_indices.entry(colnum),
356 const double lb = res.
objval();
358 (lb>
BCP_DBL_MAX/10 ?
" [%e,%i,%i]":
" [%.4f,%i,%i]"),
369 std::swap(tmp_presolved, best_presolved);
375 std::swap(tmp_presolved, best_presolved);
378 delete tmp_presolved;
382 lp->unmarkHotStart();
390 for (i=0, cani=candidates.
begin(); cani != candidates.
end(); ++cani, ++i) {
441 for (
int i = vars.
size() - 1; i >= 0; --i) {
443 if (x[i] + petol < v->lb() || x[i] - petol > v->
ub()) {
448 for (
int i = cuts.
size() - 1; i >= 0; --i) {
450 if (lhs[i] + petol < c->lb() || lhs[i] - petol > c->
ub()) {
455 LP: ***WARNING*** : BCP_DoNotBranch, but nothing can be added! ***WARNING***\n");
464 if (candidates.
size() < 1) {
466 BCP_lp_select_branching_object: branching forced but no candidates selected\n");
470 double time0 = CoinCpuTime();
477 if (candidates.
size() > 1) {
479 LP: Strong branching is disabled but more than one candidate is selected.\n\
480 Deleting all candidates but the first.\n");
484 for (++can; can != candidates.
end(); ++can) {
491 if (candidates[0]->objval_) {
493 *candidates[0]->termcode_,
510 bool needed_overriding =
false;
511 for (
int i = can->
child_num - 1; i >= 0; --i) {
514 needed_overriding =
true;
519 "LP: Every child is returned because of not diving.\n");
569 const int varnum = vars.
size();
575 var_ind.
reserve(varnum - bvarnum);
576 var_ch.
reserve(varnum - bvarnum);
577 for (i = bvarnum; i < varnum; ++i) {
579 assert(var->
bcpind() > 0);
587 const int cutnum = cuts.
size();
593 cut_ind.
reserve(cutnum - bcutnum);
594 cut_ch.
reserve(cutnum - bcutnum);
595 for (i = bcutnum; i < cutnum; ++i) {
597 assert(cut->
bcpind() > 0);
658 p.
user->
print(
true,
"LP: Forcibly Pruning node\n");
660 p.
user->
print(
true,
"LP: Returned children to TM. Waiting for new node.\n");
663 delete best_presolved;
680 for (
int p = pos.
size() - 1; p >= 0; --p) {
681 vars[pos[p]]->make_non_removable();
692 for (
int p = pos.
size() - 1; p >= 0; --p) {
693 cuts[pos[p]]->make_non_removable();
706 delete best_presolved;
int BCP_lp_send_node_description(BCP_lp_prob &p, BCP_presolved_lp_brobj *brobj, BCP_message_tag msgtag)
bool is_pruned() const
Fill up obj with the lower bound on each child.
BCP_vec< double >::const_iterator implied_cut_bd_child(const int index) const
Return a const iterator to the position in the implied cut bound changes where the new bounds for the...
void BCP_lp_add_rows_to_lp(const BCP_vec< BCP_row * > &rows, OsiSolverInterface *lp)
void apply_child_bd(OsiSolverInterface *lp, const int child_ind) const
This method invokes the appropriate methods of lp to apply the forced and implied bound changes of th...
BCP_vec< int > * implied_var_pos
BCP_warmstart * warmstart
this is always explicit, it's just that coding is simpler if we reuse the BCP_obj_set_change object ...
This child should be kept and dived into (provided diving is decided on.
This class stores data about how an object set (set of vars or set of cuts) changes.
Upper limit on the number of iterations performed in each of the children of the search tree node whe...
BCP_lp_node * node
Description he current search tree node.
void print(const bool ifprint, const char *format,...) const
A method to print a message with the process id.
Used to indicate that there is no message in the buffer of a process.
static void BCP_print_brobj_stat(BCP_lp_prob &p, const int orig_varnum, const int candidate_num, const int selected, const BCP_presolved_lp_brobj *best_presolved)
No branching happend, continue to work on the same node.
BCP_lp_parent * parent
Description of the parent of the current node.
pos
position where the operator should be printed when printing the expression
void clear()
Delete every entry.
char param(BCP_lp_par::chr_params key) const
int BCP_lp_next_var_index(BCP_lp_prob &p)
Print information on the branching candidate selected by strong branching.
void print_branching_info(const int orig_varnum, const double *x, const double *obj) const
This method prints out some information about the branching object.
void set_objective_values(const BCP_vec< double > &obj, const BCP_vec< int > &termcode, const double itlim_objval)
Set the appropriate fields of all _lpres to the given termcode and objval if the termcode is "normal"...
Abstract base class that defines members common to all types of cuts.
virtual BCP_branching_object_relation compare_branching_candidates(BCP_presolved_lp_brobj *new_solved, BCP_presolved_lp_brobj *old_solved)
Decide which branching object is preferred for branching.
OsiBabSolver * getOsiBabSolver()
BCP_node_storage_in_tm tm_storage
int vars_affected() const
Return the number of variables whose bounds are affected by the branching.
BCP_vec< double >::const_iterator forced_var_bd_child(const int index) const
Return a const iterator to the position in the forced variable bound changes where the new bounds for...
void BCP_lp_add_cols_to_lp(const BCP_vec< BCP_col * > &cols, OsiSolverInterface *lp)
"new" is better, discard "old".
BCP_branching_result BCP_lp_branch(BCP_lp_prob &p)
void BCP_lp_test_feasibility(BCP_lp_prob &p, const BCP_lp_result &lpres)
BCP_obj_set_change cut_set
this is always explicit, it's just that coding is simpler if we reuse the BCP_obj_set_change object ...
static std::pair< int, int > BCP_add_branching_objects(BCP_lp_prob &p, BCP_vec< BCP_lp_branching_object * > &candidates)
iterator begin()
Return an iterator to the beginning of the object.
BCP_vec< BCP_vec< BCP_row * > > & get_new_rows()
Fill up obj with the lower bound on each child.
double ub() const
Return the upper bound on the cut.
BCP should continue to work on this node.
const double * lhs() const
This class is just a collection of pointers to cuts with a number of methods to manipulate these cuts...
void reserve(const size_t n)
Reallocate the object to make space for n entries.
BCP_branching_result
This enumerative constant describes the possible outcomes of a branching attempt. ...
void BCP_lp_perform_fathom(BCP_lp_prob &p, const char *msg, BCP_message_tag msgtag)
void append(const BCP_vec< BCP_cut * > &x)
Append the cuts in the vector x to the end of the cut set.
int index
this is always explicit, it's just that coding is simpler if we reuse the BCP_obj_set_change object ...
"new" is better and it's so good that even if there are more candidates forget them and use "new" a...
size_t varnum() const
Return the number of variables in the core.
double lb() const
Return the lower bound on the cut.
virtual void set_actions_for_children(BCP_presolved_lp_brobj *best)
Decide what to do with the children of the selected branching object.
virtual void vars_to_cols(const BCP_vec< BCP_cut * > &cuts, BCP_vec< BCP_var * > &vars, BCP_vec< BCP_col * > &cols, const BCP_lp_result &lpres, BCP_object_origin origin, bool allow_multiple)
Convert a set of variables into corresponding columns for the current LP relaxation.
BCP_vec< int > * implied_cut_pos
BCP_lp_cut_pool * local_cut_pool
int BCP_lp_next_cut_index(BCP_lp_prob &p)
double ub() const
Return the upper bound.
void erase(iterator pos)
Erase the entry pointed to by pos.
BCP_vec< BCP_user_data * > & user_data()
Return a reference to the user data vector.
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.
BCP_vec< int > * forced_cut_pos
Positions of cuts whose bounds change ("forcibly", by branching) in the children. ...
Print detailed information on the branching candidate selected by strong branching.
BCP_warmstart * warmstart
void fint fint fint real fint real real real real real real real real real fint real fint * lp
virtual BCP_branching_decision select_branching_candidates(const BCP_lp_result &lpres, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts, const BCP_lp_var_pool &local_var_pool, const BCP_lp_cut_pool &local_cut_pool, BCP_vec< BCP_lp_branching_object * > &cands, bool force_branch=false)
Decide whether to branch or not and select a set of branching candidates if branching is decided upon...
"old" is better, discard "new".
The node is fathomed, the LP process should wait for a new node.
void get_results(OsiSolverInterface &lp, const int child_ind)
Extract the lp results from the LP solver for the child_ind-th child.
The node is discarded (fathomed).
OsiSolverInterface * lp_solver
A class that holds the methods about how to pack things.
BCP_lp_result * lp_result
int child_num
The number of children for this branching object.
size_t cutnum() const
Return the number of cuts in the core.
BCP_obj_set_change var_set
this is always explicit, it's just that coding is simpler if we reuse the BCP_obj_set_change object ...
void BCP_lp_send_cuts_to_cp(BCP_lp_prob &p, const int eff_cnt_limit)
After a branching object is selected print what happens to the presolved children (e...
int cuts_affected() const
Return the number of cuts whose bounds are affected by the branching.
BCP_obj_status status() const
Return the status of the cut.
This class describes a generic branching object.
The data stored is with respect to the same kind of data in the parent of the search tree node...
BCP_vec< double > lb_at_cutgen
BCP_branching_decision
This enumerative constant is the return value of the select_branching_candidates() method in [BCP_lp_...
Branching happened, one of the children is kept and that's what the LP process will continue to work ...
BCP_vec< BCP_var * > * vars_to_add
Variables to be added to the formulation.
BCP_lp_var_pool * local_var_pool
const BCP_lp_result & lpres(const int child_ind) const
Return a const reference to the presolved results of the child_ind-th child.
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real * ws
void insert(iterator position, const void *first, const size_t num)
Insert num entries starting from memory location first into the vector from position pos...
BCP_vec< double >::const_iterator implied_var_bd_child(const int index) const
Return a const iterator to the position in the implied variable bound changes where the new bounds fo...
This child should be returned to the Tree Manager for later processing.
The object originates from a branching object.
BCP_vec< int > * forced_var_pos
Positions of variables whose bounds change ("forcibly", by branching) in the children.
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...
Print information related to fathoming.
Abstract base class that defines members common to all types of variables.
Currently there isn't any error handling in BCP.
BCP_storage_t core_change
BCP_vec< double >::const_iterator forced_cut_bd_child(const int index) const
Return a const iterator to the position in the forced cut bound changes where the new bounds for the ...
The node should be fathomed without even trying to branch.
A presolved branching object candidate.
virtual void cuts_to_rows(const BCP_vec< BCP_var * > &vars, BCP_vec< BCP_cut * > &cuts, BCP_vec< BCP_row * > &rows, const BCP_lp_result &lpres, BCP_object_origin origin, bool allow_multiple)
Convert (and possibly lift) a set of cuts into corresponding rows for the current LP relaxation...
int bcpind() const
Return the internal index of the variable.
void BCP_lp_clean_up_node(BCP_lp_prob &p)
static bool abort_on_error
size_t size() const
Return the current number of entries.
virtual void generate_cuts_in_lp(const BCP_lp_result &lpres, const BCP_vec< BCP_var * > &vars, const BCP_vec< BCP_cut * > &cuts, BCP_vec< BCP_cut * > &new_cuts, BCP_vec< BCP_row * > &new_rows)
Generate cuts within the LP process.
iterator end()
Return an iterator to the end of the object.
Print information on the presolved branching candidates during strong branching.
BCP_obj_status status() const
Return the status of the variable.
static void BCP_lp_make_parent_from_node(BCP_lp_prob &p)
This class is just a collection of pointers to variables with a number of methods to manipulate these...
virtual void set_user_data_for_children(BCP_presolved_lp_brobj *best, const int selected)
For each child create a user data object and put it into the appropriate entry in best->user_data()...
The class BCP_vec serves the same purpose as the vector class in the standard template library...
After branching all children must be returned to the Tree Manager and the LP process should wait for ...
BCP_vec< BCP_cut * > * cuts_to_add
Cuts to be added to the formulation.
BCP_vec< BCP_vec< BCP_cut * > > & get_new_cuts()
Fill up obj with the lower bound on each child.
void unchecked_push_back(const_reference x)
Append x to the end of the vector.
void get_results(OsiSolverInterface &lp_solver)
Get the result from the LP solver.
double lb() const
Return the lower bound.
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.
void append(const BCP_vec< BCP_var * > &x)
Append the variables in the vector x to the end of the variable set.
BCP_vec< BCP_child_action > & action()
Return a reference to the actions to be taken.
static int BCP_lp_perform_strong_branching(BCP_lp_prob &p, BCP_vec< BCP_lp_branching_object * > &candidates, BCP_presolved_lp_brobj *&best_presolved)
BCP_user_data * user_data
Data the user wants to pass along with the search tree node.
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...
This class holds the results after solving an LP relaxation.
void make_to_be_removed()
Mark the cut as ToBeRemoved.
iterator entry(const int i)
Return an iterator to the i-th entry.
static void BCP_mark_result_of_strong_branching(BCP_lp_prob &p, const BCP_lp_branching_object *can, const int added_col_num, const int added_row_num)
A cut has to remain effective through this many iterations in the LP before it is sent to the Cut Poo...
BCP_vec< BCP_obj_change > _change
int bcpind() const
Return the internal index of the cut.
BCP_lp_branching_object * candidate()
Return a pointer to the candidate.
void initialize_lower_bound(const double val)
Fill up obj with the lower bound on each child.
virtual void modify_lp_parameters(OsiSolverInterface *lp, const int changeType, bool in_strong_branching)
Modify parameters of the LP solver before optimization.
void init_pos_for_added(const int added_vars_start, const int added_cuts_start)
This method "cleans up" the positions and bounds.
void BCP_lp_delete_cols_and_rows(BCP_lp_prob &p, BCP_lp_branching_object *can, const int added_colnum, const int added_rownum, const bool from_fathom, const bool force_delete)
void append(const BCP_vec< T > &x)
Append the entries in x to the end of the vector.
void make_to_be_removed()
Mark the variable as ToBeRemoved.
static BCP_branching_decision BCP_lp_select_branching_object(BCP_lp_prob &p, BCP_presolved_lp_brobj *&best_presolved)
Print detailed information about all the branching candidates during strong branching.
void fint fint fint real fint real * x
This child should be fathomed.