BCP_lp_generate_vars.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 "CoinTime.hpp"
5 #include "BCP_lp_functions.hpp"
6 #include "BCP_enum.hpp"
7 #include "BCP_lp_result.hpp"
8 #include "BCP_lp_pool.hpp"
9 #include "BCP_lp_user.hpp"
10 #include "BCP_lp.hpp"
11 #include "BCP_lp_node.hpp"
12 
14  bool cutset_changed, const bool from_repricing)
15 {
16  double time0 = CoinCpuTime();
17 
18  BCP_lp_result& lpres = *p.lp_result;
20  int prev_size = vp.size();
21 
22  if (prev_size > 0 && ! vp.cols_are_valid()){
23  // we must regenerate the cols from the variables
24  // first delete the old cols then expand the vars again
25 
26  // these will hold vars and cols expanded from the vars
27  BCP_vec<BCP_var*> vars;
28  BCP_vec<BCP_col*> cols;
29 
30  vars.reserve(prev_size);
31  int i;
32  for (i = 0; i < prev_size; ++i) {
33  vp[i]->delete_col();
34  vars.unchecked_push_back(vp[i]->var());
35  }
36  // now expand
37  cols.reserve(prev_size);
38  p.user->vars_to_cols(p.node->cuts, vars, cols,
39  lpres, BCP_Object_Leftover, false);
40  for (i = 0; i < prev_size; ++i) {
41  vp[i]->set_col(cols[i]);
42  }
43  cols.clear();
44  }
45  vp.cols_are_valid(true);
46 
48  printf("LP: Number of leftover vars: %i\n", prev_size);
49 
50  // Generate vars within the LP process
51  BCP_vec<BCP_var*> new_vars;
52  BCP_vec<BCP_col*> new_cols;
53  BCP_price_vars(p, false /* not from fathom */, new_vars, new_cols);
54  if (new_vars.size() > 0) {
55  const int new_size = new_vars.size();
56  vp.reserve(vp.size() + new_size);
57  for (int i = 0; i < new_size; ++i) {
58  new_vars[i]->set_bcpind(-BCP_lp_next_var_index(p));
59  vp.unchecked_push_back(new BCP_lp_waiting_col(new_vars[i],
60  new_cols[i]));
61  }
62  new_cols.clear();
63  new_vars.clear();
65  printf("LP: Number of vars generated in the LP process: %i\n",
66  new_size);
67  prev_size = vp.size();
68  }
69 
70  // Compute the reduced cost for everything in the local var pool and throw
71  // out the ones with positive reduced cost
72  if (prev_size > 0) {
73  vp.compute_red_costs(lpres, vp.begin(), vp.end());
74  // char dumpname[200];
75  //sprintf(dumpname, "reducedcosts-%i-%i",
76  // p.node->index, p.node->iteration_count);
77  //FILE* dumpfile = fopen(dumpname, "w");
78  //for (int i = 0; i < prev_size; ++i) {
79  // fprintf(dumpfile, "%.6f\n", vp[i]->red_cost());
80  //}
81  //fclose(dumpfile);
82  double detol = 0.0;
83  p.lp_solver->getDblParam(OsiDualTolerance, detol);
84  const int cnt = vp.remove_positives(detol);
86  printf("LP: Positive rc (hence removed): %i\n", cnt);
87  prev_size = vp.size();
88  }
89 
91  // If the message passing environment is not really parallel (i.e., while
92  // the VG/VP are working the LP stops and also the LP must immediately
93  // process any vars sent back then this is the place to send the lp
94  // solution to the VG/VP.
95  // send the current solution to VG, and also to VP if we are either
96  // - at the beginning of a chain (but not in the root in the
97  // first phase)
98  // - or this is the var_pool_check_freq-th iteration.
99  if (p.node->vg != -1 || p.node->vp != -1) {
100  const BCP_message_tag msgtag = BCP_lp_pack_for_vg(p);
101  if (p.node->vg != -1) {
102  ++p.no_more_vars_cnt;
103  p.msg_env->send(p.node->vg, msgtag, p.msg_buf);
104  }
105  if (p.node->vp != -1) {
106  if (! (p.node->iteration_count %
108  || cutset_changed) {
109  ++p.no_more_vars_cnt;
110  p.msg_env->send(p.node->vp, msgtag, p.msg_buf);
111  }
112  }
113  }
114  }
115 
116  if (p.no_more_vars_cnt > 0){
117  // Receive vars if we have sent out the lp solution somewhere.
118  // set the timeout (all the times are in microseconds).
119  double first_var_time_out = cutset_changed ?
122  double all_vars_time_out = cutset_changed ?
125  double tout = vp.size() == 0 ? first_var_time_out : all_vars_time_out;
126  double tin = CoinCpuTime();
127 
128  while(true){
129  p.msg_buf.clear();
131  p.msg_buf, tout);
132  if (p.msg_buf.msgtag() == BCP_Msg_NoMessage){
133  // check that everyone is still alive
134  if (! p.msg_env->alive(p.get_parent() /*tree_manager*/))
135  throw BCP_fatal_error("LP: The TM has died -- LP exiting\n");
136  if (p.node->cg != -1 && ! p.msg_env->alive(p.node->cg))
137  throw BCP_fatal_error("LP: The CG has died -- LP exiting\n");
138  if (p.node->cp != -1 && ! p.msg_env->alive(p.node->cp))
139  throw BCP_fatal_error("LP: The CP has died -- LP exiting\n");
140  if (p.node->vg != -1 && ! p.msg_env->alive(p.node->vg))
141  throw BCP_fatal_error("LP: The VG has died -- LP exiting\n");
142  if (p.node->vp != -1 && ! p.msg_env->alive(p.node->vp))
143  throw BCP_fatal_error("LP: The VP has died -- LP exiting\n");
144  // now the message queue is empty and received_message has
145  // returned, i.e., we have waited enough
147  printf("LP: Receive vars timed out after %f secs\n",
148  (prev_size != static_cast<int>(vp.size())?
149  all_vars_time_out : first_var_time_out));
150  break;
151  }
152  p.process_message();
153  // break out if no more vars can come
154  if (p.no_more_vars_cnt == 0)
155  break;
156 
157  // reset the timeout
158  tout = vp.size() == 0 ? first_var_time_out : all_vars_time_out;
159  if (tout >= 0){
160  // with this tout we'll read out the rest of the message queue
161  // even if var generation times out.
162  tout = std::max<double>(0.0, tout - (CoinCpuTime() - tin));
163  }
164  }
165  }
166  // reset no_more_vars_cnt to 0
167  p.no_more_vars_cnt = 0;
168 
170  printf("LP: Number of vars received from VG: %i\n",
171  static_cast<int>(vp.size() - prev_size));
172  printf("LP: Total number of vars in local pool: %i\n",
173  static_cast<int>(vp.size()));
174  }
175 
176  if (vp.size() > 0) {
177  const int oldsize = vp.size();
178  double detol = 0.0;
179  p.lp_solver->getDblParam(OsiDualTolerance, detol);
180  const int cnt = vp.remove_positives(detol);
181  if (cnt > 0) {
182  printf("\
183 LP: *WARNING*: There are vars with positive red cost in the local VP\n\
184  at the end of var generation.\n\
185  Discarding %i variables out of %i.\n", cnt, oldsize);
186  }
187  }
188 
189  p.stat.time_var_generation += CoinCpuTime() - time0;
190 
191  return vp.size();
192 }
BCP_message_tag
This enumerative constant describes the message tags different processes of BCP understand.
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.
Used when receiving, message with any message tag will be received.
Print information if receiving variables is timed out.
BCP_lp_node * node
Description he current search tree node.
Definition: BCP_lp.hpp:168
Used to indicate that there is no message in the buffer of a process.
virtual void receive(const int source, const BCP_message_tag tag, BCP_buffer &buf, const double timeout)=0
Blocking receive with timeout.
void clear()
Delete every entry.
char param(BCP_lp_par::chr_params key) const
Definition: BCP_lp.hpp:275
int BCP_lp_next_var_index(BCP_lp_prob &p)
int BCP_lp_generate_vars(BCP_lp_prob &p, bool first_in_loop, const bool from_repricing)
const int BCP_AnyProcess
Definition: BCP_message.hpp:21
BCP_lp_statistics stat
Definition: BCP_lp.hpp:213
Indicates whether message passing is serial (all processes are on the same processor) or not...
virtual void process_message()
iterator begin()
Return an iterator to the beginning of the object.
Definition: BCP_vector.hpp:99
NO OLD DOC.
Definition: BCP_lp.hpp:102
void reserve(const size_t n)
Reallocate the object to make space for n entries.
void BCP_price_vars(BCP_lp_prob &p, const bool from_fathom, BCP_vec< BCP_var * > &vars_to_add, BCP_vec< BCP_col * > &cols_to_add)
double time_var_generation
Definition: BCP_lp.hpp:63
BCP_cut_set cuts
Similar as above for variables.
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.
The Variable Pool is queried for columns that improve the formulation after the first LP realxation i...
int remove_positives(const double etol)
Definition: BCP_lp_pool.cpp:41
This parameter specifies the time to wait for variables at the first LP relaxation at a search tree n...
BCP_lp_user * user
A class that holds the methods about how to pack things.
Definition: BCP_lp.hpp:131
The object was left over in the local variable or cut pool of the LP process from the previous iterat...
Definition: BCP_enum.hpp:252
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
int get_parent() const
Definition: BCP_process.hpp:25
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
This and the following three parameters control how long the LP process waits for generated variables...
Currently there isn&#39;t any error handling in BCP.
Definition: BCP_error.hpp:20
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 unchecked_push_back(const_reference x)
Append x to the end of the vector.
int no_more_vars_cnt
Definition: BCP_lp.hpp:230
This parameter specifies the time to wait for variables at iterations that are not the first at a sea...
BCP_message_environment * msg_env
A class that holds the methods about how to pack things.
Definition: BCP_lp.hpp:139
This class holds the results after solving an LP relaxation.
bool cols_are_valid() const
virtual bool alive(const int pid)=0
Test if the process given by the argument is alive or not.
BCP_buffer msg_buf
Definition: BCP_lp.hpp:239
This parameter specifies the time to wait for the first generated variable at iterations that are not...
void compute_red_costs(const BCP_lp_result &lpres, BCP_lp_var_pool::iterator first, BCP_lp_var_pool::iterator last)