BCP_tm_msg_node_rec.cpp
Go to the documentation of this file.
1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others. All Rights Reserved.
3 #include <cstdlib>
4 #include <algorithm>
5 
6 #include "CoinTime.hpp"
7 
8 #include "BCP_os.hpp"
9 #include "BCP_USER.hpp"
10 #include "BCP_node_change.hpp"
11 #include "BCP_warmstart.hpp"
12 #include "BCP_branch.hpp"
13 #include "BCP_enum_branch.hpp"
14 #include "BCP_message.hpp"
15 #include "BCP_vector.hpp"
16 #include "BCP_tm.hpp"
17 #include "BCP_tm_user.hpp"
18 #include "BCP_tm_functions.hpp"
19 
20 #ifndef BCP_DEBUG_PRINT
21 #define BCP_DEBUG_PRINT 0
22 #endif
23 
24 static int
26 static void
28  const int bvarnum, const int bcutnum,
29  const BCP_internal_brobj* brobj, const int childind);
30 static void
32  const BCP_node_change* parentdesc, const int bvarnum,
33  const BCP_internal_brobj* brobj, const int childind);
34 static void
36  const BCP_node_change* parentdesc, const int bcutnum,
37  const BCP_internal_brobj* brobj, const int childind);
38 static void
40  BCP_tm_node* node);
41 static inline BCP_diving_status
42 BCP_tm_shall_we_dive(BCP_tm_prob& p, const double quality);
43 
44 //#############################################################################
45 
46 static void
48 {
50  if (freq == 0)
51  return;
52 
53  static int lines = 0;
54 
55  if ((lines % 41) == 0) {
56  ++lines;
57  printf("\n");
58  printf("BCP: ");
59  printf(" Nodes ");
60  printf(" Proc'd ");
61  printf(" BestUB ");
62  printf(" LowestQ ");
63  /*
64  printf("AboveUB ");
65  printf("BelowUB ");
66  */
67  printf("\n");
68  }
69  const int processed = p.search_tree.processed();
70  if ((processed % freq) == 0 || processed == 1) {
71  ++lines;
72  printf("BCP: "); // 5
73  printf("%7i ", (int)p.search_tree.size()); // 8
74  printf("%7i ", processed); // 8
75  printf("%10g ", p.ub()); // 11
76  if (p.candidate_list.empty()) {
77  printf("%10g ", 0.0); // 11
78  } else {
79  printf("%10g ", p.candidate_list.bestQuality()); // 11
80  }
81  /*
82  int quality_above_UB;
83  int quality_below_UB;
84  p.candidates.compare_to_UB(quality_above_UB, quality_below_UB);
85  printf("%7i ", quality_above_UB); // 8
86  printf("%7i ", quality_below_UB); // 8
87  */
88  printf("\n");
89  }
90 }
91 
92 //#############################################################################
93 
95 {
96 #if 0
97  static int cnt = 0;
98  ++cnt;
99  if ((cnt % 100) == 0) {
100  long usedheap = BCP_used_heap();
101  if (usedheap > 0) {
102  printf(" mallinfo used: %li\n", usedheap);
103  }
104  }
105 #endif
106 }
107 
108 //#############################################################################
109 
110 static int
112 {
113  // the first thing is the index of the node
114  int index;
115  buf.unpack(index);
116  // get a pointer to this node
117  BCP_tm_node* node = p.search_tree[index];
119 TMDBG;
120 
121  // XXX
122  const int lp_id = node->lp;
123  if (node != p.active_nodes[lp_id]) {
124  throw BCP_fatal_error("\
125 BCP_tm_unpack_node_description: received node is different from processed.\n");
126  }
127 
128  // get the quality and new lb for this node
129  double q, tlb;
130 TMDBG;
131  buf.unpack(q).unpack(tlb);
132  const double oldTrueLB = floor(node->getTrueLB()*p.lb_multiplier);
133  p.lower_bounds.erase(oldTrueLB);
134  node->setQuality(q);
135  node->setTrueLB(tlb);
136 TMDBG;
137 
138  // wipe out any previous description of this node and create a new one if
139  // the description is sent over
140  if (node->_locally_stored) {
141  node->_data._desc = NULL;
142  node->_data._user = NULL;
143  } else {
144  BCP_buffer b;
145 TMDBG;
146  BCP_vec<int> indices(1, index);
147  b.pack(indices);
151 TMDBG;
152  node->_locally_stored = true;
153  }
154 
155  bool desc_sent = false;
156  buf.unpack(desc_sent);
157 
158 TMDBG;
159  if (desc_sent) {
160  BCP_node_change* desc = new BCP_node_change;
161 
162  // unpack core_change
163  if (p.core->varnum() + p.core->cutnum() > 0)
164  desc->core_change.unpack(buf);
165 
166  int cnt;
167  // get the variables. first unpack the new vars. those with negative
168  // bcpind has not yet been sent to the TM from this LP process, but
169  // they may have been sent here by another (if CP is used). those with
170  // positive bcpind have already been sent to the TM, receiving such
171  // var again is an error.
172  buf.unpack(cnt);
173  while (--cnt >= 0) {
174  p.unpack_var();
175  }
176  // Now unpack the change data.
177 TMDBG;
178  desc->var_change.unpack(buf);
179 
180  // same for cuts
181  buf.unpack(cnt);
182  while (--cnt >= 0) {
183  p.unpack_cut();
184  }
185 TMDBG;
186  desc->cut_change.unpack(buf);
187 
188  // warmstart info
189  bool has_data;
190 TMDBG;
191  switch (p.param(BCP_tm_par::WarmstartInfo)) {
192  case BCP_WarmstartNone:
193  break;
194  case BCP_WarmstartRoot:
195  // nothing needs to be done even in this case as the WS has been
196  // sent in a separate message
197  break;
198  case BCP_WarmstartParent:
199  buf.unpack(has_data);
200  if (has_data) {
202  desc->warmstart = p.packer->unpack_warmstart(buf, def);
203  }
204  break;
205  }
206 TMDBG;
207  // user data
208  buf.unpack(has_data);
209 TMDBG;
210  BCP_user_data* udata = has_data ? p.packer->unpack_user_data(buf) : 0;
211 
212  node->_data._desc = desc;
213  node->_data._user = udata;
214  node->_core_storage = desc->core_change.storage();
215  node->_var_storage = desc->var_change.storage();
216  node->_cut_storage = desc->cut_change.storage();
217  node->_ws_storage =
218  desc->warmstart ? desc->warmstart->storage() : BCP_Storage_NoData;
219 TMDBG;
220  } else {
225  }
226 
227  p.active_nodes.erase(lp_id);
228 TMDBG;
229 
230  return index;
231 }
232 
233 //#############################################################################
234 
235 static inline BCP_diving_status
236 BCP_tm_shall_we_dive(BCP_tm_prob& p, const double quality)
237 {
238  if (rand() < p.param(BCP_tm_par::UnconditionalDiveProbability) * RAND_MAX)
239  return BCP_DoDive;
240 
241  const double ratio = p.has_ub() ?
244 
245  if (ratio < 0)
246  return BCP_DoNotDive;
247 
248  if (p.candidate_list.empty())
249  return BCP_TestBeforeDive;
250 
251  const double topq = p.candidate_list.bestQuality();
252 
253  if (quality <= topq)
254  return BCP_TestBeforeDive;
255 
256  if (topq > 0.05) {
257  return (quality / topq < ratio) ? BCP_TestBeforeDive : BCP_DoNotDive;
258  }
259  if (topq >= -0.05) {
260  return (quality < ratio) ? BCP_TestBeforeDive : BCP_DoNotDive;
261  }
262  /* must be topq < -0.05 */
263  return (quality < 0 && topq / quality < ratio) ?
265 }
266 
267 //#############################################################################
268 
269 static void
271  const int bvarnum, const int bcutnum,
272  const BCP_internal_brobj* brobj, const int childind)
273 {
274  if (bvarnum + bcutnum == 0) {
276  return;
277  }
278 
280  if (bvarnum > 0 && brobj->affected_varnum() > 0) {
281  // First count how many of them are affecting core vars
282  int affected_core = 0;
284  BCP_vec<int>::const_iterator lastposi = brobj->var_positions().end();
285  while (posi != lastposi) {
286  if (*posi < bvarnum)
287  ++affected_core;
288  ++posi;
289  }
290 
291  if (affected_core > 0) {
292  BCP_vec<int>& var_pos = desc->core_change.var_pos;
294  var_pos.reserve(affected_core);
295  var_ch.reserve(affected_core);
296  posi = brobj->var_positions().begin();
298  brobj->var_bounds_child(childind);
299  while (posi != lastposi) {
300  if (*posi < bvarnum) {
301  var_pos.unchecked_push_back(*posi);
302  const double lb = *boundsi;
303  const double ub = *(boundsi+1);
304  var_ch.unchecked_push_back(BCP_obj_change(lb, ub,
306  }
307  ++posi;
308  boundsi += 2;
309  }
310  }
311  }
312 
313  if (bcutnum > 0 && brobj->affected_cutnum() > 0) {
314  // First count how many of them are affecting core cuts
315  int affected_core = 0;
317  BCP_vec<int>::const_iterator lastposi = brobj->cut_positions().end();
318  while (posi != lastposi) {
319  if (*posi < bcutnum)
320  ++affected_core;
321  ++posi;
322  }
323 
324  if (affected_core > 0) {
325  BCP_vec<int>& cut_pos = desc->core_change.cut_pos;
327  cut_pos.reserve(affected_core);
328  cut_ch.reserve(affected_core);
329  posi = brobj->cut_positions().begin();
331  brobj->cut_bounds_child(childind);
332  while (posi != lastposi) {
333  if (*posi < bcutnum) {
334  cut_pos.unchecked_push_back(*posi);
335  const double lb = *boundsi;
336  const double ub = *(boundsi+1);
337  cut_ch.unchecked_push_back(BCP_obj_change(lb, ub,
339  }
340  ++posi;
341  boundsi += 2;
342  }
343  }
344  }
345 }
346 
347 //#############################################################################
348 
349 static void
351  const BCP_node_change* parentdesc, const int bvarnum,
352  const BCP_internal_brobj* brobj, const int childind)
353 {
354  // check first how many added var has changed in brobj
355  int affected_added = 0;
357  BCP_vec<int>::const_iterator lastposi = brobj->var_positions().end();
358  while (posi != lastposi) {
359  if (*posi >= bvarnum)
360  ++affected_added;
361  ++posi;
362  }
363 
364  if (affected_added == 0) {
365  if (parentdesc->var_change.storage() == BCP_Storage_Explicit &&
366  parentdesc->var_change.added_num() == 0) {
368  } else {
370  }
371  return;
372  }
373 
375  BCP_vec<int>& dc_pos = desc->var_change._del_change_pos;
377  dc_pos.reserve(affected_added);
378  ch.reserve(affected_added);
379  posi = brobj->var_positions().begin();
380  BCP_vec<double>::const_iterator boundsi = brobj->var_bounds_child(childind);
381  while (posi != lastposi) {
382  if (*posi >= bvarnum) {
383  dc_pos.unchecked_push_back(*posi - bvarnum);
384  const double lb = *boundsi;
385  const double ub = *(boundsi+1);
387  }
388  ++posi;
389  boundsi += 2;
390  }
391 }
392 
393 //#############################################################################
394 
395 static void
397  const BCP_node_change* parentdesc, const int bcutnum,
398  const BCP_internal_brobj* brobj, const int childind)
399 {
400  // check first how many added cut has changed in brobj
401  int affected_added = 0;
403  BCP_vec<int>::const_iterator lastposi = brobj->cut_positions().end();
404  while (posi != lastposi) {
405  if (*posi >= bcutnum)
406  ++affected_added;
407  ++posi;
408  }
409 
410  if (affected_added == 0) {
411  if (parentdesc->cut_change.storage() == BCP_Storage_Explicit &&
412  parentdesc->cut_change.added_num() == 0) {
414  } else {
416  }
417  return;
418  }
419 
421  BCP_vec<int>& dc_pos = desc->cut_change._del_change_pos;
423  dc_pos.reserve(affected_added);
424  ch.reserve(affected_added);
425  posi = brobj->cut_positions().begin();
426  BCP_vec<double>::const_iterator boundsi = brobj->cut_bounds_child(childind);
427  while (posi != lastposi) {
428  if (*posi >= bcutnum) {
429  dc_pos.unchecked_push_back(*posi - bcutnum);
430  const double lb = *boundsi;
431  const double ub = *(boundsi+1);
433  }
434  ++posi;
435  boundsi += 2;
436  }
437 }
438 
439 //#############################################################################
440 
441 static BCP_tm_node*
442 BCP_tm_create_child(BCP_tm_prob& p, const int child_ind,
443  BCP_tm_node* node,
444  const BCP_internal_brobj* brobj,
445  const BCP_vec<BCP_child_action>& action,
446  const BCP_vec<BCP_user_data*>& user_data,
447  const BCP_vec<double>& true_lb,
448  const BCP_vec<double>& qualities)
449 {
450  // generate the children
451  const int bvarnum = p.core->varnum();
452  const int bcutnum = p.core->cutnum();
453  const int depth = node->getDepth() + 1;
454  const BitVector128 nodePref = node->getPreferred();
455 
456  // nodedesc exists, because when we unpack the barnching info we just
457  // received back the description of the node
458  const BCP_node_change* nodedesc = node->_data._desc.GetRawPtr();
459 
460  BCP_node_change* desc = new BCP_node_change;
461  BCP_tm_create_core_change(desc, bvarnum, bcutnum, brobj, child_ind);
462  BCP_tm_create_var_change(desc, nodedesc, bvarnum, brobj, child_ind);
463  BCP_tm_create_cut_change(desc, nodedesc, bcutnum, brobj, child_ind);
464  if (nodedesc->warmstart)
465  // If the parent has warmstart info then
466  desc->warmstart = nodedesc->warmstart->empty_wrt_this();
467 
468  BCP_tm_node* child = new BCP_tm_node(node->getDepth() + 1, desc);
469  child->_core_storage = desc->core_change.storage();
470  child->_var_storage = desc->var_change.storage();
471  child->_cut_storage = desc->cut_change.storage();
472  child->_ws_storage =
473  desc->warmstart ? desc->warmstart->storage() : BCP_Storage_NoData;
474 
475  p.search_tree.insert(child); // this sets _index
476  child->_data._user = user_data[child_ind];
477  child->_parent = node;
478  child->_birth_index = node->child_num();
479  /* Fill out the fields in CoinTreeNode */
480  child->setDepth(depth);
481  child->setQuality(qualities[child_ind]);
482  child->setTrueLB(true_lb[child_ind]);
483  if (child_ind > 0 && depth <= 127) {
484  BitVector128 pref = nodePref;
485  pref.setBit(127-depth);
486  child->setPreferred(pref);
487  } else {
488  child->setPreferred(nodePref);
489  }
490  /* Add the child to the list of children in the parent */
491  node->new_child(child);
492  // _children initialized to be empty -- OK
493  switch (action[child_ind]){
494  case BCP_ReturnChild:
495  child->status = BCP_CandidateNode;
496  break;
497  case BCP_KeepChild:
498  child->status = BCP_CandidateNode; // be conservative
499  break;
500  case BCP_FathomChild:
502  break;
503  }
504  // inherit var/cut pools
505  child->vp = node->vp;
506  child->cp = node->cp;
507  // lp, cg, vg initialized to -1 -- OK, none assigned yet
508 #if (BCP_DEBUG_PRINT != 0)
509  printf("TM %.3lf: parent: %i sibling: %i siblingind: %i depth: %i quality: %lf pref: %s\n",
510  tt, node->_index, i, child->_index, depth, child->getQuality(),
511  child->getPreferred().str().c_str());
512 #endif
513  return child;
514 }
515 
516 //#############################################################################
517 
518 static void
520  BCP_tm_node* node)
521 {
522 TMDBG;
523  BCP_diving_status dive; // the old diving status
524 
526  BCP_vec<BCP_user_data*> user_data;
527  BCP_vec<double> true_lb;
528  BCP_vec<double> qualities;
529 
530 TMDBG;
531  buf.unpack(dive);
532 TMDBG;
533  buf.unpack(action);
534 TMDBG;
535  buf.unpack(qualities);
536 TMDBG;
537  buf.unpack(true_lb);
538 TMDBG;
539 
540  const int child_num = action.size();
541  user_data.insert(user_data.end(), child_num, 0);
542  bool has_user_data = false;
543  for (int i = 0; i < child_num; ++i) {
544  buf.unpack(has_user_data);
545  if (has_user_data) {
546  user_data[i] = p.packer->unpack_user_data(buf);
547  }
548  }
549 TMDBG;
550 
552  brobj->unpack(buf);
553 
554  node->reserve_child_num(brobj->child_num());
555  int keep = -1;
556  BCP_tm_node* child = 0;
557  int i;
558 
559  // fix the number of leaves assigned to the CP/VP
560  if (node->cp != -1) {
561  BCP_vec< std::pair<int, int> >::iterator proc =
563  if (proc == p.leaves_per_cp.end()) {
564  node->cp = -1;
565  } else {
566  proc->second += node->child_num() - 1;
567  }
568  }
569  if (node->vp != -1) {
570  BCP_vec< std::pair<int, int> >::iterator proc =
572  if (proc == p.leaves_per_vp.end()) {
573  node->vp = -1;
574  } else {
575  proc->second += node->child_num() - 1;
576  }
577  }
578 
579  CoinTreeNode** children = new CoinTreeNode*[child_num];
580  int numChildrenAdded = 0;
581 #if (BCP_DEBUG_PRINT != 0)
582  const double tt = CoinWallclockTime()-p.start_time;
583  if (p.candidate_list.size() == 0) {
584  printf("TM %.3lf: parent: %i cand_list empty\n", tt, node->_index);
585  } else {
586  printf("TM %.3lf: parent: %i cand_list top pref: %s\n",
587  tt, node->_index,
588  p.candidate_list.top()->getPreferred().str().c_str());
589  }
590 #endif
591  // First find out if the LP process should keep any of the children to
592  // dive into.
593  for (i = 0; i < child_num; ++i) {
594  if (action[i] == BCP_KeepChild) {
595  assert(keep == -1);
596  keep = i;
597  }
598  }
599  if (keep >= 0) {
600  children[numChildrenAdded++] = BCP_tm_create_child(p, keep, node, brobj,
601  action, user_data,
602  true_lb, qualities);
603  }
604  for (i = 0; i < child_num; ++i) {
605  if (i != keep) {
606  children[numChildrenAdded++] = BCP_tm_create_child(p, i, node, brobj,
607  action, user_data,
608  true_lb, qualities);
609  }
610  }
611 
612  int reply_to_lp = -1;
613  if (numChildrenAdded > 0) {
614  CoinTreeSiblings siblings(numChildrenAdded, children);
615 
618 
619  // check the one that's proposed to be kept if there's one
620  if (keep >= 0) {
621  // The kept child was pushed into the node first.
622  child = node->child(0);
623  if (dive == BCP_DoDive || dive == BCP_TestBeforeDive) {
624  reply_to_lp = node->lp;
625  // we've got to answer
626  buf.clear();
627  if (p.need_a_TS) {
628  /* Force no diving if we need a TS process */
629  dive = BCP_DoNotDive;
630  } else {
631  if (dive == BCP_TestBeforeDive)
632  dive = BCP_tm_shall_we_dive(p, child->getQuality());
633  }
634  buf.pack(dive);
635  if (dive != BCP_DoNotDive){
636  child->status = BCP_ActiveNode;
637  // if diving then send the new index and var/cut_names
638  buf.pack(child->index());
639  siblings.advanceNode();
640  }
641  p.candidate_list.push(siblings);
643  } else {
644  p.candidate_list.push(siblings);
646  }
647  } else {
648  p.candidate_list.push(siblings);
650  dive = BCP_DoNotDive;
651  }
652 
653  if (dive == BCP_DoNotDive){
654  // lp,cg,vg becomes free (zeroes out node->{lp,cg,vg})
655  BCP_tm_free_procs_of_node(p, node);
656  } else {
657  // if diving then the child takes over the parent's lp,cg,vg
658  // XXX
659  if (child != node->child(0)) {
660  throw BCP_fatal_error("\
661 BCP_tm_unpack_branching_info: the value of child is messed up!\n");
662  }
663  if (node->lp == -1) {
664  throw BCP_fatal_error("\
665 BCP_tm_unpack_branching_info: the (old) node has no LP associated with!\n");
666  }
667  child->lp = node->lp;
668  child->cg = node->cg;
669  child->vg = node->vg;
670  p.active_nodes[node->lp] = child;
671  node->lp = node->cg = node->vg = -1;
672  }
673  }
674 
675  delete[] children;
676 
677  // Update the lower bounds
678  for (int i = true_lb.size()-1; i >= 0; --i) {
679  true_lb[i] = floor(true_lb[i]*p.lb_multiplier);
680  }
681  p.lower_bounds.insert(true_lb.begin(), true_lb.end());
682 
683  // and the node is done
684  node->status = BCP_ProcessedNode;
686  true /*after processing*/);
687 
688  delete brobj;
689 
690  if (reply_to_lp >= 0) {
691  // The user will override at most one...
694  false /*before processing*/);
695  p.msg_env->send(reply_to_lp, BCP_Msg_DivingInfo, buf);
696  }
697 
698 #ifdef BCP__DUMP_PROCINFO
699 #if (BCP__DUMP_PROCINFO == 1)
700  dump_procinfo(p, "BCP_tm_unpack_branching_info()");
701 #endif
702 #endif
703 }
704 
705 //#############################################################################
706 
708 {
709  const int index = BCP_tm_unpack_node_description(p, buf);
710  /* In the middle of BCP_tm_unpack_branching_info we check for data
711  balancing just before we (may) allow diving.*/
712  BCP_tm_unpack_branching_info(p, buf, p.search_tree[index]);
713  BCP_tm_print_info_line(p, *p.search_tree[index]);
714  // BCP_tm_list_candidates(p);
715 
717 }
718 
719 //#############################################################################
720 
722  BCP_buffer& buf)
723 {
724  const int index = BCP_tm_unpack_node_description(p, buf);
725 
728 
729  // Mark the lp/cg/vg processes of the node as free
730  BCP_tm_node* node = p.search_tree[index];
731  BCP_tm_print_info_line(p, *node);
732  BCP_tm_free_procs_of_node(p, node);
733 
735 
736  return node;
737 }
BCP_tree search_tree
Definition: BCP_tm.hpp:239
static double lb_multiplier
The lower bounds of the unexplored search tree nodes.
Definition: BCP_tm.hpp:198
static int BCP_tm_unpack_node_description(BCP_tm_prob &p, BCP_buffer &buf)
virtual void send(const int target, const BCP_message_tag tag)=0
Send an empty message (message tag only) to the process given by the frist argument.
This child should be kept and dived into (provided diving is decided on.
BCP_buffer & pack(const T &value)
Pack a single object of type T.
Definition: BCP_buffer.hpp:177
const BCP_vec< int > & var_positions() const
Return a const reference to the vector of positions of variables affected by the branching.
Definition: BCP_branch.hpp:87
static int num_local_nodes
Definition: BCP_tm_node.hpp:73
int child_num() const
Return the number of children.
Definition: BCP_branch.hpp:79
BCP_buffer & unpack(T &value)
Unpack a single object of type T.
Definition: BCP_buffer.hpp:186
BCP_vec< double >::const_iterator cut_bounds_child(const int index) const
Return a const iterator within _cut_bounds to the location where the bound pairs for the index-th chi...
Definition: BCP_branch.hpp:103
void increase_processed()
std::map< int, BCP_tm_node * > active_nodes
A map from the process ids to the nodes (what they work on)
Definition: BCP_tm.hpp:241
Print out a message when the default version of an overridable method is executed.
virtual void change_candidate_heap(CoinSearchTreeManager &candidates, const bool new_solution)
double start_time
Definition: BCP_tm.hpp:203
static BCP_diving_status BCP_tm_shall_we_dive(BCP_tm_prob &p, const double quality)
void insert(BCP_tm_node *node)
Return the worst true lower bound in the search tree.
virtual BCP_user_data * unpack_user_data(BCP_buffer &buf)
Unpack an user data.
Definition: BCP_USER.hpp:126
BCP_tm_node_status status
Definition: BCP_tm_node.hpp:78
BCP_storage_t storage() const
Return the storage type.
double ub() const
Definition: BCP_tm.hpp:321
void reserve_child_num(int num)
BCP_vec< std::pair< int, int > > leaves_per_cp
Definition: BCP_tm.hpp:259
BCP_tm_node * BCP_tm_unpack_node_no_branching_info(BCP_tm_prob &p, BCP_buffer &buf)
static void BCP_tm_create_cut_change(BCP_node_change *desc, const BCP_node_change *parentdesc, const int bcutnum, const BCP_internal_brobj *brobj, const int childind)
BCP_storage_t _storage
Describes how the change is stored.
static int num_remote_nodes
Definition: BCP_tm_node.hpp:74
size_t size() const
int processed() const
At every this many search tree node provide a single line info on the progress of the search tree...
bool BCP_tm_is_data_balanced(BCP_tm_prob &p)
This function is invoked from exactly one place, the beginning of BCP_tm_unpack_node_description().
No data is stored.
Definition: BCP_enum.hpp:86
iterator begin()
Return an iterator to the beginning of the object.
Definition: BCP_vector.hpp:99
CoinSearchTreeManager candidate_list
Definition: BCP_tm.hpp:243
const BCP_vec< int > & cut_positions() const
Return a const reference to the vector of positions of cuts affected by the branching.
Definition: BCP_branch.hpp:90
BCP_problem_core * core
Definition: BCP_tm.hpp:208
void reserve(const size_t n)
Reallocate the object to make space for n entries.
#define TMDBG
Definition: BCP_process.hpp:7
bool BCP_tm_balance_data(BCP_tm_prob &p)
This function is invoked after data from an LP is unpacked (and only if p.need_a_TS is true)...
The object is not removable from the LP formulation, even if the object becomes inactive.
Definition: BCP_enum.hpp:115
BCP_vec< int > cut_pos
The positions of the core cuts (in the cuts member of [BCP_problem_core]{BCP_problem_core.html}) whose bounds and/or stati have changed.
Do not use any warmstart information.
Definition: BCP_enum.hpp:235
virtual BCP_warmstart * unpack_warmstart(BCP_buffer &buf, bool report_if_default=false)
Unpack warmstarting information.
Definition: BCP_USER.hpp:74
TM sends diving information.
int index() const
This class is the internal representation of a branching object.
Definition: BCP_branch.hpp:31
The data stored is an explicit listing of values.
Definition: BCP_enum.hpp:88
size_t varnum() const
Return the number of variables in the core.
BCP_vec< int > var_pos
The positions of the core variables (in the vars member of [BCP_problem_core]{BCP_problem_core.html}) whose bounds and/or stati have changed.
BCP_vec< BCP_obj_change > var_ch
The new lb/ub/status triplet for each variable for which any of those three have changed.
BCP_storage_t _storage
BCP_problem_core_change core_change
void BCP_tm_unpack_node_with_branching_info(BCP_tm_prob &p, BCP_buffer &buf)
void unpack(BCP_buffer &buf)
Unpack an internal branching object from the buffer.
Definition: BCP_branch.cpp:44
static double ratio(Bigint *a, Bigint *b)
Definition: OSdtoa.cpp:1460
int child_num() const
static BCP_tm_node * BCP_tm_create_child(BCP_tm_prob &p, const int child_ind, BCP_tm_node *node, const BCP_internal_brobj *brobj, const BCP_vec< BCP_child_action > &action, const BCP_vec< BCP_user_data * > &user_data, const BCP_vec< double > &true_lb, const BCP_vec< double > &qualities)
bool need_a_TS
Definition: BCP_tm.hpp:234
Coin::SmartPtr< BCP_node_change > _desc
Definition: BCP_tm_node.hpp:53
BCP_obj_set_change cut_change
BCP_diving_status
This enumerative constant describes the diving status of the search tree node processed by the LP pro...
The probability with which the LP process is directed to dive.
The LP process is allowed to dive if the ratio between the quality (for now the presolved objective v...
BCP_vec< std::pair< int, int > > leaves_per_vp
Definition: BCP_tm.hpp:261
virtual BCP_storage_t storage() const =0
Return how the warmstarting info is stored.
virtual BCP_warmstart * empty_wrt_this() const =0
Create a warmstart info describing that no change should be done.
static long BCP_used_heap()
Definition: BCP_os.hpp:54
size_t cutnum() const
Return the number of cuts in the core.
NO OLD DOC.
Definition: BCP_tm.hpp:136
BCP_tm_node_data _data
int affected_cutnum() const
Return the number of affected cuts.
Definition: BCP_branch.hpp:83
Use the warmstart info from the end of the parent in the children.
Definition: BCP_enum.hpp:240
real tt
BCP_tm_node * child(int ind)
The data stored is with respect to the same kind of data in the parent of the search tree node...
Definition: BCP_enum.hpp:91
static void BCP_tm_print_info_line(BCP_tm_prob &p, BCP_tm_node &node)
void BCP_tm_free_procs_of_node(BCP_tm_prob &p, BCP_tm_node *node)
void new_child(BCP_tm_node *node)
void clear()
Completely clear the buffer.
Definition: BCP_buffer.hpp:168
After branching the LP process is free to decide whether it keeps a child to dive into...
BCP_vec< double >::const_iterator var_bounds_child(const int index) const
Return a const iterator within _var_bounds to the location where the bound pairs for the index-th chi...
Definition: BCP_branch.hpp:96
static void BCP_tm_create_core_change(BCP_node_change *desc, const int bvarnum, const int bcutnum, const BCP_internal_brobj *brobj, const int childind)
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...
static void BCP_tm_unpack_branching_info(BCP_tm_prob &p, BCP_buffer &buf, BCP_tm_node *node)
void unpack(BCP_buffer &buf)
Unpack the core change data from the buffer.
void BCP_print_memusage(BCP_tm_prob &p)
Coin::SmartPtr< BCP_user_data > _user
Definition: BCP_tm_node.hpp:54
static void BCP_tm_create_var_change(BCP_node_change *desc, const BCP_node_change *parentdesc, const int bvarnum, const BCP_internal_brobj *brobj, const int childind)
Use the warmstart info from the end of the root in all search tree nodes.
Definition: BCP_enum.hpp:238
bool has_ub() const
Definition: BCP_tm.hpp:319
BCP_storage_t storage() const
int unpack_cut()
Definition: BCP_tm.cpp:217
int unpack_var()
Definition: BCP_tm.cpp:137
This child should be returned to the Tree Manager for later processing.
Currently there isn&#39;t any error handling in BCP.
Definition: BCP_error.hpp:20
BCP_tm_node * _parent
Definition: BCP_tm_node.hpp:82
BCP_message_environment * msg_env
A class that holds the methods about how to pack things.
Definition: BCP_tm.hpp:156
BCP_user_pack * packer
A class that holds the methods about how to pack things.
Definition: BCP_tm.hpp:153
size_t size() const
Return the current number of entries.
Definition: BCP_vector.hpp:116
iterator end()
Return an iterator to the end of the object.
Definition: BCP_vector.hpp:104
void unpack(BCP_buffer &buf)
After branching all children must be returned to the Tree Manager and the LP process should wait for ...
This class describes the message buffer used for all processes of BCP.
Definition: BCP_buffer.hpp:39
void unchecked_push_back(const_reference x)
Append x to the end of the vector.
BCP_vec< int > _del_change_pos
std::multiset< double > lower_bounds
Definition: BCP_tm.hpp:199
BCP_tm_user * user
A class that holds the methods about how to pack things.
Definition: BCP_tm.hpp:151
BCP_obj_set_change var_change
BCP_warmstart * warmstart
Same as above, but this value is used if an upper bound does not exist yet.
virtual void display_node_information(BCP_tree &search_tree, const BCP_tm_node &node)
Display user information just before a new node is sent to the LP or diving into a node is acknowledg...
After branching the LP process must inquire of the Tree Manager whether it can dive into one of the c...
BCP_vec< BCP_obj_change > _change
BCP_vec< std::pair< int, int > >::iterator BCP_tm_identify_process(BCP_vec< std::pair< int, int > > &proclist, int proc)
return b
Definition: OSdtoa.cpp:1719
char param(BCP_tm_par::chr_params key) const
Definition: BCP_tm.hpp:298
Specifies how warmstart information should be stored in the TM.
int affected_varnum() const
Return the number of affected variables.
Definition: BCP_branch.hpp:81
int added_num() const
BCP_vec< BCP_obj_change > cut_ch
The new lb/ub/status triplet for each cut for which any of those three have changed.
This child should be fathomed.