BCP_tm_main.cpp
Go to the documentation of this file.
1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others. All Rights Reserved.
3 #include <cstdio>
4 #include <cerrno>
5 #include <cmath>
6 #include <queue>
7 #ifdef _MSC_VER
8 #include <process.h>
9 #endif
10 
11 #include "CoinTime.hpp"
12 
13 #include "BcpConfig.h"
14 #include "BCP_os.hpp"
15 
16 #include "BCP_USER.hpp"
17 #include "BCP_string.hpp"
18 #include "BCP_vector.hpp"
19 #include "BCP_buffer.hpp"
20 #include "BCP_message.hpp"
21 #include "BCP_var.hpp"
22 #include "BCP_cut.hpp"
23 #include "BCP_node_change.hpp"
24 #include "BCP_tm.hpp"
25 #include "BCP_tm_functions.hpp"
26 #include "BCP_main_fun.hpp"
27 
28 #include "BCP_tm_user.hpp"
29 #include "BCP_lp_user.hpp"
30 
31 #include "BCP_message_single.hpp"
32 #include "BCP_message_mpi.hpp"
33 #include "BCP_message_pvm.hpp"
34 
35 //#############################################################################
36 
37 int bcp_main(int argc, char* argv[], USER_initialize* user_init)
38 {
39  BCP_message_environment* msg_env = user_init->msgenv_init(argc, argv);
40  BCP_single_environment* single_env =
41  dynamic_cast<BCP_single_environment*>(msg_env);
42  if (single_env) {
43  // this way when register_process takes over the execution the single
44  // environment will have access to the command line arguments and can
45  // parse it.
46  single_env->set_arguments(argc, argv);
47  }
48 
49  int my_id = msg_env->register_process(user_init);
50 
51  if (single_env) {
52  // register process did everything. We just return.
53  delete msg_env;
54  return 0;
55  }
56 
57  int parent = msg_env->parent_process();
58 
59  if (parent == -1) {
60  //We compute the real numeber of arguments because Mpi can change
61  //list of arguments
62  int cnt;
63  for (cnt = 0; cnt < argc; ++cnt) {
64  if (argv[cnt] == NULL)
65  break;
66  }
67  BCP_tm_main(msg_env, user_init, cnt, argv);
68  } else {
69  // In MPI all processes get the argument list, so we must not check
70  // this
71 #if defined(COIN_HAS_MPI)
72  BCP_mpi_environment* mpi_env =
73  dynamic_cast<BCP_mpi_environment*>(msg_env);
74  if (!mpi_env && argc != 1) {
75  throw BCP_fatal_error("The slaves do not take any argument!\n");
76  }
77 #endif
78  BCP_buffer msg_buf;
79  msg_env->receive(parent, BCP_Msg_AnyMessage, msg_buf, -1);
80  if (msg_buf.msgtag() != BCP_Msg_ProcessType) {
81  throw BCP_fatal_error("The first message is not ProcessType!!!\n");
82  }
83  // got a new identity, act on it
84  BCP_process_t ptype;
85  double ub;
86  msg_buf.unpack(ptype);
87  msg_buf.unpack(ub);
88  while (ptype != BCP_ProcessType_EndProcess) {
89  const bool maxheap_set = false;
90  switch (ptype) {
91  case BCP_ProcessType_LP:
92  if (maxheap_set) {
93  printf("usedheap before LP: %li\n", BCP_used_heap());
94  }
95  ptype = BCP_lp_main(msg_env, user_init, my_id, parent, ub);
96  if (maxheap_set) {
97  printf("usedheap after LP: %li\n", BCP_used_heap());
98  }
99  break;
100  case BCP_ProcessType_CP:
101  // BCP_cp_main(msg_env, user_init, my_id, parent, ub);
102  break;
103  case BCP_ProcessType_VP:
104  // BCP_vp_main(msg_env, user_init, my_id, parent, ub);
105  break;
106  case BCP_ProcessType_CG:
107  ptype = BCP_cg_main(msg_env, user_init, my_id, parent, ub);
108  break;
109  case BCP_ProcessType_VG:
110  ptype = BCP_vg_main(msg_env, user_init, my_id, parent, ub);
111  break;
112  case BCP_ProcessType_TS:
113  if (maxheap_set) {
114  printf("usedheap before TS: %li\n", BCP_used_heap());
115  }
116  ptype = BCP_tmstorage_main(msg_env, user_init, my_id, parent, ub);
117  if (maxheap_set) {
118  printf("usedheap after TS: %li\n", BCP_used_heap());
119  }
120  break;
121  case BCP_ProcessType_Any:
122  throw BCP_fatal_error("\
123 New process identity is BCP_ProcessType_Any!\n");
124  case BCP_ProcessType_TM:
125  throw BCP_fatal_error("\
126 New process identity is BCP_ProcessType_TM!\n");
128  break;
129  }
130  }
131  }
132  delete msg_env;
133 
134  return 0;
135 }
136 
137 //#############################################################################
138 
139 void
141  USER_initialize* user_init,
142  const int argnum, const char* const * arglist)
143 {
144  // If we ever get here then the environment is parallel
145 
146  // Start to create the universe... (we don't have a user universe yet).
147  BCP_tm_prob p;
148 
149  // If we ever get here then the environment is parallel
154  /*
155  p.slave_pars.cp.set_entry(BCP_cp_par::MessagePassingIsSerial,false);
156  p.slave_pars.vp.set_entry(BCP_vp_par::MessagePassingIsSerial,false);
157  */
158 
159  // this also reads in the parameters from a file
160  BCP_tm_parse_command_line(p, argnum, arglist);
161 
162  BCP_buffer msg_buf;
163  p.msg_env = msg_env;
164 
165  //We check if the number of BCP processes is the same as in MPI
166 #if defined(COIN_HAS_MPI)
167  BCP_mpi_environment* mpi_env = dynamic_cast<BCP_mpi_environment*>(msg_env);
168  if (mpi_env) {
169  const int n_proc =
175  if (p.msg_env->num_procs() < n_proc) {
176  throw BCP_fatal_error("\
177 Number of process in parameter file %d > n_proc in mpirun -np %d!\n",
178  n_proc, p.msg_env->num_procs());
179  }
180  }
181 #endif
182 
184 
185  p.start_time = CoinWallclockTime();
186 
187  FILE* logfile = 0;
188 
190  if (! (p.par.entry(BCP_tm_par::LogFileName) == "")) {
191  int len = log.length();
192  char *logname = new char[len + 300];
193  memcpy(logname, log.c_str(), len);
194  memcpy(logname + len, "-tm-", 4);
195  len += 4;
196  gethostname(logname + len, 255);
197  len = strlen(logname);
198  logname[len++] = '-';
199  sprintf(logname + len, "%i", static_cast<int>(GETPID));
200  logfile = freopen(logname, "a", stdout);
201  if (logfile == 0) {
202  fprintf(stderr, "Error while redirecting stdout: %i\n", errno);
203  abort();
204  }
205  setvbuf(logfile, NULL, _IOLBF, 0); // make it line buffered
206  delete[] logname;
207  } else {
208  setvbuf(stdout, NULL, _IOLBF, 0); // make it line buffered
209  }
210 
211  // BCP_tm_user_init() returns a BCP_tm_user* and that will be part of p.
212  // Also, it should take care of every I/O, heuristic startup, etc. the user
213  // wants to do. Wreak havoc in p if (s)he wants.
214  // BUT: once this function returns, the processes designated to be part of
215  // BCP must be idle and waiting for a message. See the
216  // BCP_slave_process_stub() function below.
217  p.user = user_init->tm_init(p, argnum, arglist);
218  p.user->setTmProblemPointer(&p);
219  p.packer = user_init->packer_init(p.user);
220  p.packer->user_class = p.user;
221 
222  // Set the core (variables & cuts)
223  p.core = BCP_tm_create_core(p);
225  *p.core_as_change = *p.core;
226 
227  // Fire up the LP/CG/CP/VG/VP processes
228  // Actually, this is firing up enough copies of self.
230  p.lp_scheduler.
233  10.0, /* estimated root time */
240 
241  // Notify the LP/CG/CP/VG/VP processes about their identity. Also, send out
242  // their parameters, core and user info.
244 
245 #if ! defined(BCP_ONLY_LP_PROCESS_HANDLING_WORKS)
246  // Initialize the number of leaves assigned to CP's and VP's as 0
247  if (p.param(BCP_tm_par::CpProcessNum) > 0) {
248  for (int i = p.slaves.cp->procs().size() - 1; i >= 0; --i)
249  p.leaves_per_cp.push_back(std::make_pair(p.slaves.cp->procs()[i], 0));
250  }
251  if (p.param(BCP_tm_par::VpProcessNum) > 0) {
252  for (int i = p.slaves.vp->procs().size() - 1; i >= 0; --i)
253  p.leaves_per_vp.push_back(std::make_pair(p.slaves.vp->procs()[i], 0));
254  }
255 #endif
256 
257  // Initialize the root of the search tree (can't invoke directly
258  // p.user->create_root(), b/c the root might contain extra vars/cuts and
259  // it's better if we take care of inserting them into the appropriate data
260  // structures.
261  BCP_tm_node* root = BCP_tm_create_root(p);
262 
263  p.next_phase_nodes.push_back(root);
264  p.search_tree.insert(root);
265  p.lower_bounds.insert(root->getTrueLB());
266 
268 
269  //-------------------------------------------------------------------------
270  // The main loop
271  //-------------------------------------------------------------------------
272  bool something_died = false;
273  for ( p.phase = 0; true ; ++p.phase) {
274  // insert the nodes in next_phase_nodes into candidates, print out some
275  // statistics about the previous phase (if there was one) and do some
276  // other stuff, too.
278  // do one phase (return true/false depending on success)
279  something_died = BCP_tm_do_one_phase(p);
280  // If nothing is left for the next phase or if something has died then
281  // quit the infinite loop.
282  if (p.next_phase_nodes.size() == 0 || something_died)
283  break;
284  }
285 
286  //-------------------------------------------------------------------------
287  // Everything is done
288  //-------------------------------------------------------------------------
289  // first let the processes know that they're not needed in BCP any more,
290  // they can start idling (this will be used when we'll loop around in TM).
291  // The processes will respond by sending statistics.
294 
295  BCP_tm_wrapup(&p, 0, 0, 0, true);
296 
297  // Finally stop all the processes.
299 
300  if (logfile)
301  fclose(logfile);
302 }
303 
304 //#############################################################################
305 
307 {
308  BCP_buffer& buf = p.msg_buf;
309  // While there are nodes waiting to be processed (or being processed) we
310  // don't go to the next phase
311  while (!p.candidate_list.empty() > 0 || p.lp_scheduler.numNodeIds() > 0){
312  // Fill up as many free LP processes as we can
314  // Error indicates that something has died
315  return true;
316  buf.clear();
317  // Check if need to balance data
320 
321  // Process incoming messages. If there are no active nodes left then
322  // timeout is set to 0, so we just check the queue, but not wait.
323  const int numNodeIds = p.lp_scheduler.numNodeIds();
324  const double t0 = CoinWallclockTime();
325  const double timeout = (p.lp_scheduler.numNodeIds() == 0 ?
328  const double t1 = CoinWallclockTime();
329  p.stat.update_wait_time(numNodeIds, t1-t0);
330 #ifdef COIN_HAS_MPI
331  p.stat.update_queue_length(numNodeIds, MPIDI_BGLTS_get_num_messages());
332 #endif
333  p.stat.print(false /* not final */, t1 - p.start_time);
334  try {
335  p.process_message();
336  }
337  catch (BCP_fatal_error& err) {
338  // something is baaaad... e.g. timeout
339  return true;
340  }
341  }
342  return false;
343 }
344 
345 //#############################################################################
346 
348 {
351  BCP_lp_relax* matrix = 0;
352 
353  p.user->initialize_core(bvars, bcuts, matrix);
354 
355  const int bvarnum = bvars.size();
356  if (bvarnum > 0) {
357  int i = p.next_var_index_set_start;
358  for (i = 0; i < bvarnum; ++i) {
359  BCP_var_core* var = bvars[i];
360  // make certain that the bounds of integer vars is integer...
361  if (var->var_type() != BCP_ContinuousVar) {
362  var->set_lb(ceil(var->lb()-1e-8));
363  var->set_ub(floor(var->ub()+1e-8));
364  }
365  var->set_bcpind(i);
366  p.vars_local[i] = new BCP_var_core(*var);
367  }
369  }
370 
371  const int bcutnum = bcuts.size();
372  if (bcutnum > 0) {
373  int i = p.next_cut_index_set_start;
374  for (i = 0; i < bcutnum; ++i) {
375  BCP_cut_core* cut = bcuts[i];
376  cut->set_bcpind(i);
377  p.cuts_local[i] = new BCP_cut_core(*cut);
378  }
380  }
381 
382  if (!matrix)
383  matrix = new BCP_lp_relax;
384 
385  return new BCP_problem_core(bvars, bcuts, matrix);
386 }
387 
388 //#############################################################################
389 
390 static inline BCP_cut*
392 {
393  BCP_cut* cut;
394  BCP_buffer& buf = tm.msg_buf;
395  BCP_object_t obj_t;
396  double lb, ub;
397  BCP_obj_status stat;
398  buf.unpack(obj_t).unpack(stat).unpack(lb).unpack(ub);
399  switch (obj_t) {
400  case BCP_CoreObj:
401  cut = new BCP_cut_core(lb, ub);
402  break;
403  case BCP_AlgoObj:
404  cut = tm.packer->unpack_cut_algo(buf);
405  cut->change_bounds(lb, ub);
406  break;
407  default:
408  throw BCP_fatal_error("BCP_tm_unpack_root_cut: unexpected obj_t.\n");
409  }
410  cut->set_bcpind(0);
411  cut->set_status(stat);
412 
413  return cut;
414 }
415 
416 //#############################################################################
417 
419 {
420  BCP_vec<BCP_var*> added_vars;
421  BCP_vec<BCP_cut*> added_cuts;
422  BCP_user_data* user_data = 0;
423 
424  // If the root cuts are saved then read them in
425  const BCP_string& cutfile = p.param(BCP_tm_par::ReadRootCutsFrom);
426  if (cutfile.length() > 0) {
427  BCP_buffer& buf = p.msg_buf;
428  buf.clear();
429  FILE* f = fopen(cutfile.c_str(), "r");
430  size_t size;
431  if (fread(&size, 1, sizeof(size), f) != sizeof(size))
432  throw BCP_fatal_error("ReadRootCutsFrom read error.\n");
433  char * data = new char[size];
434  if (fread(data, 1, size, f) != size)
435  throw BCP_fatal_error("ReadRootCutsFrom read error.\n");
436  fclose(f);
437  buf.set_content(data, size, 0, BCP_Msg_NoMessage);
438  delete[] data;
439 
440  int num;
441  buf.unpack(num);
442  added_cuts.reserve(added_cuts.size() + num);
443  for (int i = 0; i < num; ++i) {
445  }
446  }
447 
448  p.user->create_root(added_vars, added_cuts, user_data);
449 
450  BCP_node_change* root_changes = new BCP_node_change;
451  root_changes->core_change._storage = BCP_Storage_WrtCore;
452 
453  if (added_vars.size() > 0) {
454  const int num = added_vars.size();
455  BCP_obj_set_change& vc = root_changes->var_change;
456  vc._change.reserve(num);
457  vc._new_objs.reserve(num);
458  int ind = p.next_var_index_set_start;
459  for (int i = 0; i < num; ++i) {
460  BCP_var* var = added_vars[i];
462  p.vars_local[ind] = var;
463  var->set_bcpind(ind++);
464  vc._change.unchecked_push_back(BCP_obj_change(var->lb(), var->ub(),
465  var->status()));
466  }
467  p.next_var_index_set_start = ind;
468  }
469 
470  if (added_cuts.size() > 0) {
471  const int num = added_cuts.size();
472  BCP_obj_set_change& cc = root_changes->cut_change;
473  cc._change.reserve(num);
474  cc._new_objs.reserve(num);
475  int ind = p.next_cut_index_set_start;
476  for (int i = 0; i < num; ++i) {
477  BCP_cut* cut = added_cuts[i];
479  p.cuts_local[ind] = cut;
480  cut->set_bcpind(ind++);
481  cc._change.unchecked_push_back(BCP_obj_change(cut->lb(), cut->ub(),
482  cut->status()));
483  }
484  p.next_cut_index_set_start = ind;
485  }
486 
487  BCP_tm_node* root = new BCP_tm_node(0, root_changes);
488 
489  root->_data._user = user_data;
490 
491  root->_core_storage = root->_data._desc->core_change.storage();
495 
496  return root;
497 }
498 
499 //#############################################################################
500 
502 {
504  printf("##########################################################\n");
505  printf("TM: Starting phase %i\n", p.phase);
506  printf("##########################################################\n");
507  }
508 
509  if (p.phase > 0) {
510  // Notify the LPs about the start of the new phase and get back the
511  // timing data for the previous phase
513 
514  // print statistics about the previous phase
515  BCP_tm_wrapup(&p, 0, 0, 0, false); // false refers to not being final
516 
517  // trim the tree if needed and possible
519  BCP_tm_trim_tree_wrapper(p, true /* called between phases */);
520  }
521 
522  if (p.candidate_list.getTree() && !p.candidate_list.empty()) {
523  throw BCP_fatal_error("\
524 BCP_tm_tasks_before_new_phase: candidate_list should be empty!\n");
525  }
526 
527  // build up candidates. initialize the candidate list comparison function.
529  p.candidate_list.setTree(NULL);
530  CoinSearchTreeBase* candidates = NULL;
531  p.user->init_new_phase(p.phase, p.current_phase_colgen, candidates);
532  if (candidates == NULL) {
533  candidates = new CoinSearchTree<CoinSearchTreeCompareBest>;
534  }
535  p.candidate_list.setTree(candidates);
536 
537  for (int i = p.next_phase_nodes.size() - 1; i >= 0; --i) {
538  p.candidate_list.push(p.next_phase_nodes[i]);
539  }
540 
542 }
543 
544 //#############################################################################
545 
546 
BCP_tree search_tree
Definition: BCP_tm.hpp:239
This class describes changes in the core of the problem.
BCP_buffer msg_buf
members to measure how long it took to process the root node.
Definition: BCP_tm.hpp:183
Indicates whether to trim the search tree before a new phase.
BCP_problem_core * BCP_tm_create_core(BCP_tm_prob &p)
void BCP_tm_notify_about_new_phase(BCP_tm_prob &p)
This class describes the core of the MIP problem, the variables/cuts in it as well as the matrix corr...
void set_arguments(const int argnum, const char *const *args)
Parameters related to scheduling the LP processes.
This class stores data about how an object set (set of vars or set of cuts) changes.
virtual int num_procs()
Return the number of processes.
BCP_parameter_set< BCP_vg_par > vg
Definition: BCP_tm.hpp:67
Used when receiving, message with any message tag will be received.
int next_cut_index_set_start
Definition: BCP_tm.hpp:229
void print(bool final, double t)
Definition: BCP_tm.cpp:50
BCP_parameter_set< BCP_cg_par > cg
Definition: BCP_tm.hpp:65
void set_ub(const double ub)
Set the upper bound.
Definition: BCP_var.hpp:150
Used to indicate that there is no message in the buffer of a process.
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
virtual void receive(const int source, const BCP_message_tag tag, BCP_buffer &buf, const double timeout)=0
Blocking receive with timeout.
Parameters related to scheduling the LP processes.
void clear()
Delete every entry.
double start_time
Definition: BCP_tm.hpp:203
std::map< int, Coin::SmartPtr< BCP_cut > > cuts_local
Definition: BCP_tm.hpp:224
BCP_process_t BCP_vg_main(BCP_message_environment *msg_env, USER_initialize *user_init, int my_id, int parent, double ub)
Definition: BCP_vg_main.cpp:24
void update_idle_times()
Update idle times with the last idle time.
const int BCP_AnyProcess
Definition: BCP_message.hpp:21
This is an abstract base class that describes the message passing environment.
Definition: BCP_message.hpp:30
Abstract base class that defines members common to all types of cuts.
Definition: BCP_cut.hpp:29
void insert(BCP_tm_node *node)
Return the worst true lower bound in the search tree.
virtual BCP_cut_algo * unpack_cut_algo(BCP_buffer &buf)
Unpack an algorithmic cut.
Definition: BCP_USER.hpp:109
void set_bcpind(const int bcpind)
Set the internal index of the cut.
Definition: BCP_cut.hpp:149
BCP_process_t
This enumerative constant describes the various process types.
Indicates whether message passing is serial (all processes are on the same processor) or not...
char entry(const chr_params key) const
const char * c_str() const
Definition: BCP_string.hpp:19
virtual BCP_user_pack * packer_init(BCP_user_class *p)
Definition: BCP_USER.hpp:225
void set_bcpind(const int bcpind)
Set the internal index of the variable.
Definition: BCP_var.hpp:176
BCP_vec< std::pair< int, int > > leaves_per_cp
Definition: BCP_tm.hpp:259
BCP_storage_t _storage
Describes how the change is stored.
void set_num_lp(int num)
Definition: BCP_tm.hpp:110
Indicates whether message passing is serial (all processes are on the same processor) or not...
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().
The number of Variable Generator processes that should be spawned.
void update_queue_length(int i, int len)
Definition: BCP_tm.hpp:125
Core cuts are the cuts that always stay in the LP formulation.
Definition: BCP_cut.hpp:195
No data is stored.
Definition: BCP_enum.hpp:86
double ub() const
Return the upper bound on the cut.
Definition: BCP_cut.hpp:84
The TM sends the process type to the process (LP, Cut Generator, etc.)
BCP_process_t BCP_tmstorage_main(BCP_message_environment *msg_env, USER_initialize *user_init, int my_id, int parent, double ub)
CoinSearchTreeManager candidate_list
Definition: BCP_tm.hpp:243
BCP_vec< int > _new_objs
BCP_problem_core * core
Definition: BCP_tm.hpp:208
BCP_vec< BCP_tm_node * > next_phase_nodes
a vector of nodes to be processed in the next phase
Definition: BCP_tm.hpp:250
void reserve(const size_t n)
Reallocate the object to make space for n entries.
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)...
void BCP_tm_main(BCP_message_environment *msg_env, USER_initialize *user_init, const int argnum, const char *const *arglist)
Indicates whether message passing is serial (all processes are on the same processor) or not...
virtual BCP_message_environment * msgenv_init(int argc, char *argv[])
Create a message passing environment.
Definition: BCP_USER.cpp:16
This class is a very simple impelementation of a constant length string.
Definition: BCP_string.hpp:13
void setTmProblemPointer(BCP_tm_prob *ptr)
Set the pointer.
Definition: BCP_tm_user.hpp:69
void set_content(const char *data, const size_t size, int sender, BCP_message_tag msgtag)
Set the buffer to be a copy of the given data.
Definition: BCP_buffer.hpp:119
void BCP_tm_stop_processes(BCP_tm_prob &p)
Indicates whether message passing is serial (all processes are on the same processor) or not...
Core variables are the variables that always stay in the LP formulation.
Definition: BCP_var.hpp:230
Parameters related to scheduling the LP processes.
void push_back(const_reference x)
Append x to the end of the vector.
virtual void process_message()
void BCP_tm_start_processes(BCP_tm_prob &p)
void fint fint fint real fint real real real real * f
BCP_process_t BCP_cg_main(BCP_message_environment *msg_env, USER_initialize *user_init, int my_id, int parent, double ub)
Definition: BCP_cg_main.cpp:23
BCP_obj_status
This enumerative constant gives the status of an object (variable or cut).
Definition: BCP_enum.hpp:105
The data stored is an explicit listing of values.
Definition: BCP_enum.hpp:88
Print the &quot;Starting phase x&quot; line.
void BCP_tm_parse_command_line(BCP_tm_prob &p, const int argnum, const char *const *arglist)
The name of the file where cuts to be added to the root description should be read ot from...
int bcp_main(int argc, char *argv[], USER_initialize *user_init)
This is the function the user must invoke when (s)he is ready to turn contrl over to BCP...
Definition: BCP_tm_main.cpp:37
double lb() const
Return the lower bound on the cut.
Definition: BCP_cut.hpp:82
void fint fint fint real fint real real real real real real real real real * e
BCP_problem_core_change core_change
BCP_process_t BCP_lp_main(BCP_message_environment *msg_env, USER_initialize *user_init, int my_id, int parent, double ub)
Definition: BCP_lp_main.cpp:59
int numNodeIds() const
Return the number of busy LP processes.
Definition: BCP_process.hpp:95
std::map< int, Coin::SmartPtr< BCP_var > > vars_local
Definition: BCP_tm.hpp:220
BCP_node_start_result BCP_tm_start_new_nodes(BCP_tm_prob &p)
void BCP_tm_tasks_before_new_phase(BCP_tm_prob &p)
bool need_a_TS
Definition: BCP_tm.hpp:234
double ub() const
Return the upper bound.
Definition: BCP_var.hpp:91
Coin::SmartPtr< BCP_node_change > _desc
Definition: BCP_tm_node.hpp:53
BCP_obj_set_change cut_change
The number of Cut Generator processes that should be spawned.
This class is an abstract base class for the initializer class the user has to provide.
Definition: BCP_USER.hpp:160
int next_var_index_set_start
Definition: BCP_tm.hpp:231
#define GETPID
Definition: BCP_os.hpp:31
int length() const
Definition: BCP_string.hpp:16
BCP_vec< std::pair< int, int > > leaves_per_vp
Definition: BCP_tm.hpp:261
static long BCP_used_heap()
Definition: BCP_os.hpp:54
void set_entry(const chr_params key, const char val)
BCP_user_class * user_class
A pointer ot the usr class of the process from which the methods of this class are invoked from...
Definition: BCP_USER.hpp:55
#define gethostname(x, y)
Definition: BCP_os.hpp:25
NO OLD DOC.
Definition: BCP_tm.hpp:136
BCP_tm_node_data _data
void BCP_tm_trim_tree_wrapper(BCP_tm_prob &p, const bool between_phases)
BCP_obj_status status() const
Return the status of the cut.
Definition: BCP_cut.hpp:91
bool BCP_tm_do_one_phase(BCP_tm_prob &p)
void set_status(const BCP_obj_status stat)
Set the status of the cut.
Definition: BCP_cut.hpp:156
BCP_parameter_set< BCP_tm_par > par
Definition: BCP_tm.hpp:168
void BCP_tm_idle_processes(BCP_tm_prob &p)
void clear()
Completely clear the buffer.
Definition: BCP_buffer.hpp:168
BCP_tm_stat stat
Definition: BCP_tm.hpp:265
void BCP_sanity_checks(BCP_tm_prob &p)
BCP_message_tag msgtag() const
Return the message tag of the message in the buffer.
Definition: BCP_buffer.hpp:90
void BCP_tm_wrapup(BCP_tm_prob *tm, BCP_lp_prob *lp, BCP_cg_prob *cg, BCP_vg_prob *vg, bool final_stat)
BCP_var_t var_type() const
Return the integrality type of the variable.
Definition: BCP_var.hpp:85
virtual void init_new_phase(int phase, BCP_column_generation &colgen, CoinSearchTreeBase *&candidates)
Do whatever initialization is necessary before the phase-th phase.
Coin::SmartPtr< BCP_user_data > _user
Definition: BCP_tm_node.hpp:54
bool has_ub() const
Definition: BCP_tm.hpp:319
Continuous variable.
Definition: BCP_enum.hpp:167
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_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
virtual BCP_tm_user * tm_init(BCP_tm_prob &p, const int argnum, const char *const *arglist)
Definition: BCP_USER.hpp:187
size_t size() const
Return the current number of entries.
Definition: BCP_vector.hpp:116
Algorithmic object.
Definition: BCP_enum.hpp:53
BCP_obj_status status() const
Return the status of the variable.
Definition: BCP_var.hpp:98
void BCP_tm_notify_processes(BCP_tm_prob &p)
virtual void create_root(BCP_vec< BCP_var * > &added_vars, BCP_vec< BCP_cut * > &added_cuts, BCP_user_data *&user_data)
Create the set of extra variables and cuts that should be added to the formulation in the root node...
Do fathom the node.
Definition: BCP_enum.hpp:67
This class describes the message buffer used for all processes of BCP.
Definition: BCP_buffer.hpp:39
void change_bounds(const double lb, const double ub)
Change just the lower/upper bounds.
Definition: BCP_cut.hpp:142
void unchecked_push_back(const_reference x)
Append x to the end of the vector.
BCP_scheduler lp_scheduler
members to measure how long it took to process the root node.
Definition: BCP_tm.hpp:188
BCP_parameter_set< BCP_lp_par > lp
Definition: BCP_tm.hpp:61
virtual int parent_process()=0
Return the process id of the parent process (the process that spawned the currnet process...
virtual void initialize_core(BCP_vec< BCP_var_core * > &vars, BCP_vec< BCP_cut_core * > &cuts, BCP_lp_relax *&matrix)
Create the core of the problem by filling out the last three arguments.
std::multiset< double > lower_bounds
Definition: BCP_tm.hpp:199
double lb() const
Return the lower bound.
Definition: BCP_var.hpp:89
BCP_tm_user * user
A class that holds the methods about how to pack things.
Definition: BCP_tm.hpp:151
void set_lb(const double lb)
Set the lower bound.
Definition: BCP_var.hpp:145
BCP_problem_core_change * core_as_change
Definition: BCP_tm.hpp:210
The number of Variable Pool processes that should be spawned.
BCP_slave_params slave_pars
Definition: BCP_tm.hpp:170
virtual int register_process(USER_initialize *user_init)=0
A process can register (receive its process id) with the message passing environment.
BCP_obj_set_change var_change
BCP_tm_node * BCP_tm_create_root(BCP_tm_prob &p)
BCP_column_generation current_phase_colgen
Definition: BCP_tm.hpp:216
Max how many SB nodes should the scheduler give to an LP process.
BCP_vec< BCP_obj_change > _change
BCP_object_t
This enumerative constant describes the possible types of objects (variables and cuts).
Definition: BCP_enum.hpp:49
char param(BCP_tm_par::chr_params key) const
Definition: BCP_tm.hpp:298
void update_wait_time(int i, double t)
Definition: BCP_tm.hpp:124
Base object.
Definition: BCP_enum.hpp:51
static BCP_cut * BCP_tm_unpack_root_cut(BCP_tm_prob &tm)
An object of type BCP_lp_relax holds the description of an lp relaxation.
Definition: BCP_matrix.hpp:267
The number of Cut Pool processes that should be spawned.
CouExpr & log(CouExpr &e)
The number of LP processes that should be spawned.