BCP_lp_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 <functional>
4 #include "BCP_message.hpp"
5 #include "BCP_node_change.hpp"
6 #include "BCP_warmstart.hpp"
7 #include "BCP_lp_node.hpp"
8 #include "BCP_lp_user.hpp"
9 #include "BCP_lp.hpp"
10 #include "BCP_lp_functions.hpp"
11 
12 static inline void
14 
15 static inline void
17 
18 static inline void
20 static inline void
22 static inline void
24 
25 static inline void
27 static inline void
29 
30 static inline void
32 
33 //-----------------------------------------------------------------------------
34 
36 {
37  buf.unpack(p.parent->index);
39  p.parent->core_as_change.unpack(buf); // BCP_problem_core_change
40  // make sure the parent's storage is Explicit (convert if it is
41  // WrtCore now). This way later we can test for WrtParent easily.
43  }
44 
45  assert(node.vars.size() == p.core->vars.size());
47  // these are the vars present in the parent
48  p.parent->var_set.unpack(buf);
49 #ifdef PARANOID
51  throw BCP_fatal_error("BCP_lp_unpack_parent(): oops 1\n");
52 #endif
53  } else {
54  assert(p.parent->var_set._change.empty());
55  assert(p.parent->var_set._new_objs.empty());
56  }
57 
58  assert(node.cuts.size() == p.core->cuts.size());
60  // these are the cuts present in the parent
61  p.parent->cut_set.unpack(buf);
62 #ifdef PARANOID
64  throw BCP_fatal_error("BCP_lp_unpack_parent(): oops 1\n");
65 #endif
66  } else {
67  assert(p.parent->cut_set._change.empty());
68  assert(p.parent->cut_set._new_objs.empty());
69  }
70 
73  p.parent->warmstart = p.packer->unpack_warmstart(buf, def);
74  }
75 }
76 
77 //-----------------------------------------------------------------------------
78 // The following two functions are needed below in BCP_lp_create_core()
79 
81 {
82  if (change.varnum() > 0)
83  node.vars.set_lb_ub_st(change.var_pos.begin(), change.var_ch);
84  if (change.cutnum() > 0)
85  node.cuts.set_lb_ub_st(change.cut_pos.begin(), change.cut_ch);
86 }
87 
90 {
91  switch (core.storage()) {
93  if (p.core->varnum() > 0)
94  // this call sets the changes on the core
96  if (p.core->cutnum() > 0)
97  // this call sets the changes on the core
99  BCP_lp_modify_core(node, core);
100  break;
101 
103  if (core.varnum() > 0)
104  // this call sets the changes on the core
105  node.vars.set_lb_ub_st(core.var_ch);
106  if (core.cutnum() > 0)
107  // this call sets the changes on the core
108  node.cuts.set_lb_ub_st(core.cut_ch);
109  break;
110 
111  default:
112  // impossible in this function
113  throw BCP_fatal_error("BCP_lp_set_core: Impossible storage_type.\n");
114  }
115 }
116 
117 //-----------------------------------------------------------------------------
118 
120 {
121  switch (p.node->tm_storage.core_change){
122  case BCP_Storage_WrtCore:
123  //in this case it'll copy the orig core first then update it
125  // in this case it'll apply the core in node_change directly
126  BCP_lp_set_core(p, *p.node, node_change.core_change);
127  break;
128 
130  // copy the parent lb/ub/status then apply the changes in node_change
132  BCP_lp_modify_core(*p.node, node_change.core_change);
133  break;
134 
135  case BCP_Storage_NoData:
136  // there are no core objects
137  break;
138 
139  default:
140  // impossible
141  throw BCP_fatal_error("BCP_lp_create_core: Bad storage.\n");
142  }
143 }
144 
145 //-----------------------------------------------------------------------------
146 
148  // When this function is called, the core vars are already listed in
149  // p.node->vars, be careful not to destroy them
150 {
151  switch (p.node->tm_storage.var_change) {
154  break;
155  case BCP_Storage_NoData:
156  // there are no added vars
157  return;
158  case BCP_Storage_WrtCore:
159  default:
160  // impossible
161  throw BCP_fatal_error("BCP_lp_create_added_vars: Bad storage.\n");
162  }
163  // WrtParent || Explicit
164  // It happens so that in case of explicit storage parent.var_set is empty,
165  // so this is still OK!!
166  BCP_obj_set_change var_set = p.parent->var_set;
167  var_set.update(node_change.var_change);
168  assert(p.node->vars.size() == p.core->varnum() + var_set._change.size());
169  assert(var_set._change.size() == var_set._new_objs.size());
170  BCP_var** added_vars = &p.node->vars[0] + p.core->varnum();
171  for (int i = var_set._change.size() - 1; i >= 0; --i) {
172  added_vars[i]->change_lb_ub_st(var_set._change[i]);
173  }
174 }
175 
176 //-----------------------------------------------------------------------------
177 
179 {
180  switch (p.node->tm_storage.cut_change) {
183  break;
184  case BCP_Storage_NoData:
185  // there are no added cuts
186  return;
187  case BCP_Storage_WrtCore:
188  default:
189  // impossible
190  throw BCP_fatal_error("BCP_lp_create_added_cuts: Bad storage.\n");
191  }
192  // WrtParent || Explicit
193  // It happens so that in case of explicit storage parent.cut_set is empty,
194  // so this is still OK!!
195  BCP_obj_set_change cut_set = p.parent->cut_set;
196  cut_set.update(node_change.cut_change);
197  assert(p.node->cuts.size() == p.core->cutnum() + cut_set._change.size());
198  assert(cut_set._change.size() == cut_set._new_objs.size());
199  BCP_cut** added_cuts = &p.node->cuts[0] + p.core->cutnum();
200  for (int i = cut_set._change.size() - 1; i >= 0; --i) {
201  added_cuts[i]->change_lb_ub_st(cut_set._change[i]);
202  }
203 }
204 
205 //-----------------------------------------------------------------------------
206 
208 {
209  switch (p.node->tm_storage.warmstart) {
211  p.node->warmstart = p.parent->warmstart->clone();
212  p.node->warmstart->update(node_change.warmstart);
213  break;
214 
216  p.node->warmstart = node_change.warmstart;
217  node_change.warmstart = 0;
218  break;
219 
220  case BCP_Storage_NoData: // there's no warmstart info
221  break;
222 
223  case BCP_Storage_WrtCore:
224  default:
225  // impossible
226  throw BCP_fatal_error("BCP_lp_create_warmstart: Bad storage.\n");
227  }
228 }
229 
230 //-----------------------------------------------------------------------------
231 
233 {
234  // we got to put together p.node from parent and node_change
235  p.node->iteration_count = 0;
236 
237  BCP_lp_create_core(p, node_change);
238  BCP_lp_create_added_vars(p, node_change);
239  BCP_lp_create_added_cuts(p, node_change);
240  BCP_lp_create_warmstart(p, node_change);
241 }
242 
243 //#############################################################################
244 
246 {
248 
249  if (p.parent->warmstart != 0 || p.node->warmstart != 0) {
250  throw BCP_fatal_error("\
251 BCP_lp_unpack_active_node: parent's or node's warmstart is non-0.\n");
252  }
253 
254  BCP_lp_node& node = *p.node;
255  // unpack a few essential data
256  buf.unpack(node.colgen).unpack(node.index).unpack(node.level)
258  .unpack(node.dive);
259 
260  // unpack process information
261  buf.unpack(node.cg);
262  buf.unpack(node.cp);
263  buf.unpack(node.vg);
264  buf.unpack(node.vp);
265 
266  // unpack how the various pieces are stored in node
267  buf.unpack(node.tm_storage.core_change)
270  .unpack(node.tm_storage.warmstart);
271 
272  if (node.level > 0)
273  BCP_lp_unpack_parent(p, buf, node);
274 
275  BCP_node_change node_change;
276  node_change.unpack(p.packer, def, buf);
277 
278  // Now unpack the full list of vars/cuts of the node
279  int i, cnt;
280  buf.unpack(cnt);
281  assert(node.vars.size() == p.core->vars.size());
282  node.vars.reserve(cnt+node.vars.size());
283  for (i = 0; i < cnt; ++i) {
285  }
286  buf.unpack(cnt);
287  assert(node.cuts.size() == p.core->cuts.size());
288  node.cuts.reserve(cnt+node.cuts.size());
289  for (i = 0; i < cnt; ++i) {
291  }
292 
293  // Create the active node from the parent and from the last changes
294  BCP_lp_create_node(p, node_change);
295 
296  // Delete the old user data
297  delete p.node->user_data;
298  bool has_data;
299  buf.unpack(has_data);
300  p.node->user_data = has_data ? p.packer->unpack_user_data(buf) : 0;
301 }
This class describes changes in the core of the problem.
BCP_warmstart * warmstart
this is always explicit, it&#39;s just that coding is simpler if we reuse the BCP_obj_set_change object ...
Definition: BCP_lp_node.hpp:64
void unpack(BCP_user_pack *packer, const bool def, BCP_buffer &buf)
This class stores data about how an object set (set of vars or set of cuts) changes.
bool empty() const
Test if there are any entries in the object.
Definition: BCP_vector.hpp:121
BCP_storage_t cut_change
Definition: BCP_lp_node.hpp:31
virtual void update(const BCP_warmstart *const change)=0
Update the current data with the one in the argument.
BCP_lp_node * node
Description he current search tree node.
Definition: BCP_lp.hpp:168
void BCP_lp_unpack_active_node(BCP_lp_prob &p, BCP_buffer &buf)
BCP_buffer & unpack(T &value)
Unpack a single object of type T.
Definition: BCP_buffer.hpp:186
The data stored is with respect to the original description of the base problem (as was given by the ...
Definition: BCP_enum.hpp:94
BCP_lp_parent * parent
Description of the parent of the current node.
Definition: BCP_lp.hpp:170
static void BCP_lp_create_added_cuts(BCP_lp_prob &p, BCP_node_change &node_change)
char param(BCP_lp_par::chr_params key) const
Definition: BCP_lp.hpp:275
Print out a message when the default version of an overridable method is executed.
static void BCP_lp_unpack_parent(BCP_lp_prob &p, BCP_buffer &buf, BCP_lp_node &node)
BCP_var_set vars
void update(const BCP_obj_set_change &objs_change)
double quality
Abstract base class that defines members common to all types of cuts.
Definition: BCP_cut.hpp:29
BCP_node_storage_in_tm tm_storage
virtual BCP_user_data * unpack_user_data(BCP_buffer &buf)
Unpack an user data.
Definition: BCP_USER.hpp:126
BCP_storage_t storage() const
Return the storage type.
size_t varnum() const
Return the number of changed variables (the length of the array var_ch).
BCP_obj_set_change cut_set
this is always explicit, it&#39;s just that coding is simpler if we reuse the BCP_obj_set_change object ...
Definition: BCP_lp_node.hpp:62
BCP_diving_status dive
void set_lb_ub_st(const BCP_vec< BCP_obj_change > &cc)
Set the lower/upper bound pairs and the stati of the first cc.
Definition: BCP_cut.cpp:29
BCP_storage_t warmstart
Definition: BCP_lp_node.hpp:33
virtual BCP_warmstart * clone() const =0
Make a replica of the current warmstart information.
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
NO OLD DOC.
Definition: BCP_lp.hpp:102
BCP_vec< int > _new_objs
void reserve(const size_t n)
Reallocate the object to make space for n entries.
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.
static void BCP_lp_create_warmstart(BCP_lp_prob &p, BCP_node_change &node_change)
virtual BCP_warmstart * unpack_warmstart(BCP_buffer &buf, bool report_if_default=false)
Unpack warmstarting information.
Definition: BCP_USER.hpp:74
size_t cutnum() const
Return the number of changed cuts (the length of the array cut_ch).
BCP_vec< BCP_cut_core * > cuts
A vector of pointers to the cuts in the core of the problem.
int index
this is always explicit, it&#39;s just that coding is simpler if we reuse the BCP_obj_set_change object ...
Definition: BCP_lp_node.hpp:66
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_cut_set cuts
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_problem_core_change core_change
BCP_warmstart * warmstart
BCP_obj_set_change cut_change
NO OLD DOC.
Definition: BCP_lp_node.hpp:92
size_t cutnum() const
Return the number of cuts in the core.
static void BCP_lp_create_core(BCP_lp_prob &p, BCP_node_change &node_change)
BCP_obj_set_change var_set
this is always explicit, it&#39;s just that coding is simpler if we reuse the BCP_obj_set_change object ...
Definition: BCP_lp_node.hpp:59
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
BCP_problem_core_change core_as_change
this is always explicit, it&#39;s just that coding is simpler if we reuse the BCP_obj_set_change object ...
Definition: BCP_lp_node.hpp:56
void unpack(BCP_buffer &buf)
Unpack the core change data from the buffer.
BCP_storage_t storage() const
Abstract base class that defines members common to all types of variables.
Definition: BCP_var.hpp:28
Currently there isn&#39;t any error handling in BCP.
Definition: BCP_error.hpp:20
BCP_cut * unpack_cut()
Definition: BCP_lp.cpp:197
BCP_storage_t core_change
Definition: BCP_lp_node.hpp:27
BCP_storage_t var_change
Definition: BCP_lp_node.hpp:29
size_t size() const
Return the current number of entries.
Definition: BCP_vector.hpp:116
BCP_column_generation colgen
BCP_var * unpack_var()
Definition: BCP_lp.cpp:140
void unpack(BCP_buffer &buf)
double true_lower_bound
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_problem_core * core
Definition: BCP_lp.hpp:153
BCP_obj_set_change var_change
BCP_user_data * user_data
Data the user wants to pass along with the search tree node.
void ensure_explicit(const BCP_problem_core_change &expl_core)
If the current storage is not already explicit then replace it with an explicit description of the co...
BCP_warmstart * warmstart
static void BCP_lp_create_added_vars(BCP_lp_prob &p, BCP_node_change &node_change)
BCP_problem_core_change * core_as_change
Definition: BCP_lp.hpp:155
static void BCP_lp_create_node(BCP_lp_prob &p, BCP_node_change &node_change)
BCP_vec< BCP_obj_change > _change
static void BCP_lp_set_core(BCP_lp_prob &p, BCP_lp_node &node, BCP_problem_core_change &core)
static void BCP_lp_modify_core(BCP_lp_node &node, BCP_problem_core_change &change)
BCP_vec< BCP_var_core * > vars
A vector of pointers to the variables in the core of the problem.
void set_lb_ub_st(const BCP_vec< BCP_obj_change > &vc)
Set the lower/upper bound pairs and the stati of the first cc.
Definition: BCP_var.cpp:27
BCP_vec< BCP_obj_change > cut_ch
The new lb/ub/status triplet for each cut for which any of those three have changed.
BCP_user_pack * packer
A class that holds the methods about how to pack things.
Definition: BCP_lp.hpp:133