BB_tm.cpp
Go to the documentation of this file.
1 // Last edit: 5/19/07
2 //
3 // Name: BB_tm.cpp
4 // Author: Francois Margot
5 // Tepper School of Business
6 // Carnegie Mellon University, Pittsburgh, PA 15213
7 // email: fmargot@andrew.cmu.edu
8 // Date: 12/28/03
9 //-----------------------------------------------------------------------------
10 // Copyright (C) 2003, Francois Margot, International Business Machines
11 // Corporation and others. All Rights Reserved.
12 
13 #include<iomanip>
14 
15 #include <CoinError.hpp>
16 #include <CoinHelperFunctions.hpp>
17 #include <CoinFileIO.hpp>
18 #include <OsiClpSolverInterface.hpp>
19 
20 #include "BB_init.hpp"
21 #include "BCP_tm.hpp"
22 #include "BB_tm.hpp"
23 #include "BB_cut.hpp"
24 #include "BB_user_data.hpp"
25 
26 #include "BCP_math.hpp"
27 
28 using namespace std;
29 
30 /*************************************************************************/
31 
32 int main(int argc, char* argv[])
33 {
34  WindowsErrorPopupBlocker();
35  BB_init bb_init;
36  return bcp_main(argc, argv, &bb_init);
37 }
38 
39 /*************************************************************************/
40 void
41 BB_tm::readInput(const char* filename)
42 
43  // Initialize the data members of class BB_prob
44 
45 {
46  int i;
47 
48  // Try to read in the problem from file bac.lp.
49  // If that fails then build the problem from scratch.
50  // Note: Do not try to replace the file bac.lp by another
51  // lp file. The code, most likely, will crash.
52 
53  bool found_file = false;
54  CoinFileInput* fi = NULL;
55 
56  OsiClpSolverInterface solver; // defined in class BCP_tm_user
57 
58  if (!found_file) {
59  // Try bac.lp
60  try {
61  found_file = true;
62  fi = CoinFileInput::create("bac.lp");
63  }
64  catch (CoinError& err) {
65  // bac.lp not found
66  found_file = false;
67  }
68  if (found_file) {
69  solver.readLp("bac.lp");
70  printf("Problem read from file bac.lp\n");
71  }
72  }
73 
74  // For MPS files, use the following:
75  /**********
76  if (!found_file) {
77  // Try bac.mps
78  try {
79  found_file = true;
80  fi = CoinFileInput::create("bac.mps");
81  }
82  catch (CoinError& err) {
83  // bac.mps not found
84  found_file = false;
85  }
86  if (found_file) {
87  solver.readMps("bac.mps");
88  printf("Problem read from file bac.mps\n");
89  }
90  }
91  **********/
92 
93  if (found_file) {
94 
95  const int rownum = solver.getNumRows();
96  const int colnum = solver.getNumCols();
97  desc.rownum = rownum;
98  desc.colnum = colnum;
99 
100  // extract integrality information
101 
102  desc.integer = new bool[colnum];
103  for (i = 0; i < colnum; ++i) {
104  desc.integer[i] = solver.isInteger(i);
105  }
106 
107  // extract variable bounds and objective
108 
109  desc.clb = new double[colnum];
110  CoinDisjointCopyN(solver.getColLower(), colnum, desc.clb);
111 
112  desc.cub = new double[colnum];
113  CoinDisjointCopyN(solver.getColUpper(), colnum, desc.cub);
114 
115  desc.obj = new double[colnum];
116  CoinDisjointCopyN(solver.getObjCoefficients(), colnum, desc.obj);
117 
118  const CoinPackedMatrix* byRow = solver.getMatrixByRow();
119 
120  int core_size = 10;
121  int *core_ind = new int[core_size];
122  desc.rlb_core = new double[core_size];
123  desc.rub_core = new double[core_size];
124 
125  int indexed_size = 6;
126  int *indexed_ind = new int[indexed_size];
127  desc.rlb_indexed = new double[indexed_size];
128  desc.rub_indexed = new double[indexed_size];
129 
130 
131  for (i=0; i<core_size; i++) {
132  core_ind[i] = i;
133  }
134  for (i=core_size; i<rownum; i++) {
135  indexed_ind[i-core_size] = i;
136  }
137 
138  cout << "readInput(): core size: " << core_size << " indexed size: "
139  << indexed_size << endl;
140 
141  // make a copy of rlb/rub in the appropriate order
142 
143  const double* solver_rlb = solver.getRowLower();
144  const double* solver_rub = solver.getRowUpper();
145 
146  for (i=0; i<core_size; ++i) {
147  desc.rlb_core[i] = solver_rlb[core_ind[i]];
148  desc.rub_core[i] = solver_rub[core_ind[i]];
149  }
150 
151  for (i=0; i<indexed_size; ++i) {
152  desc.rlb_indexed[i] = solver_rlb[indexed_ind[i]];
153  desc.rub_indexed[i] = solver_rub[indexed_ind[i]];
154  }
155 
156  // split the byRow matrix into core and indexed constraints
157  // these two variables are part of the BB_tm class
158 
159  desc.core = new CoinPackedMatrix(false, 0.0, 0.0);
160  desc.core->submatrixOf(*byRow, core_size, core_ind);
161 
162  desc.indexed = new CoinPackedMatrix(false, 0.0, 0.0);
163  desc.indexed->submatrixOf(*byRow, indexed_size, indexed_ind);
164 
165  delete[] core_ind;
166  delete[] indexed_ind;
167 
168  } else {
169  // create the problem from scratch
170  printf("Problem created in memory\n");
171 
172  desc.colnum = 10;
173  int colnum = desc.colnum;
174  desc.rownum = 16;
175 
176  desc.obj = new double[colnum];
177  desc.clb = new double[colnum];
178  desc.cub = new double[colnum];
179  desc.integer = new bool[colnum];
180 
181  for(i=0; i<colnum; i++) {
182  desc.obj[i] = -1;
183  desc.clb[i] = 0;
184  desc.cub[i] = 1;
185  desc.integer[i] = true;
186  }
187 
188  desc.core = new CoinPackedMatrix(false, 0.0, 0.0);
189  desc.rlb_core = new double[10];
190  desc.rub_core = new double[10];
191 
192  double* cutcoef = new double[colnum];
193  int *cutind = new int[colnum];
194  int j, cutnz;
195 
196  // core constraints
197 
198  cutcoef[0] = 1;
199  cutcoef[1] = 1;
200  cutnz = 2;
201 
202  for(i=0; i<10; i++) {
203  desc.rlb_core[i] = 0;
204  desc.rub_core[i] = 1;
205  j = (i+1) % colnum;
206  cutind[0] = i;
207  cutind[1] = j;
208  desc.core->appendRow(cutnz, cutind, cutcoef);
209  }
210  desc.rlb_core[0] = 1; // first constraint is an equality
211 
212  desc.indexed = new CoinPackedMatrix(false, 0.0, 0.0);
213  desc.rlb_indexed = new double[6];
214  desc.rub_indexed = new double[6];
215 
216  // indexed constraints
217 
218  for(i=0; i<6; i++) {
219  desc.rlb_indexed[i] = -BCP_DBL_MAX;
220  desc.rub_indexed[i] = 1;
221  }
222 
223  cutcoef[0] = 1;
224  cutcoef[1] = 1;
225  cutcoef[2] = 1;
226  cutnz = 3;
227 
228  cutind[1] = 1;
229  cutind[2] = 3;
230  cutind[0] = 9;
231  desc.indexed->appendRow(cutnz, cutind, cutcoef);
232  cutind[0] = 0;
233  cutind[1] = 2;
234  cutind[2] = 4;
235  desc.indexed->appendRow(cutnz, cutind, cutcoef);
236  cutind[0] = 0;
237  cutind[1] = 3;
238  cutind[2] = 7;
239  desc.indexed->appendRow(cutnz, cutind, cutcoef);
240  cutind[0] = 1;
241  cutind[1] = 4;
242  cutind[2] = 5;
243  desc.indexed->appendRow(cutnz, cutind, cutcoef);
244  cutind[0] = 5;
245  cutind[1] = 6;
246  cutind[2] = 7;
247  desc.indexed->appendRow(cutnz, cutind, cutcoef);
248  cutind[0] = 0;
249  cutind[1] = 6;
250  cutind[2] = 8;
251  desc.indexed->appendRow(cutnz, cutind, cutcoef);
252 
253  delete[] cutcoef;
254  delete[] cutind;
255  }
256 }
257 
258 /*************************************************************************/
259 void
261 {
262  // possible process types looked up in BCP_enum_process_t.hpp
263 
264  switch (ptype) {
265  case BCP_ProcessType_LP:
266  {
267  // Pack a pointer; does not work for parallel machines
268 
269  buf.pack(&desc);
270  }
271  break;
272  default:
273  abort();
274  }
275 }
276 
277 /*************************************************************************/
278 void
281  BCP_lp_relax*& matrix)
282 
283 // Transmit the core constraints and variables to BCP
284 
285 {
286  int i;
287 
288  for (i=0; i<desc.colnum; ++i) {
289  if (desc.integer[i]) {
290  if (desc.clb[i] == 0.0 && desc.cub[i] == 1.0) {
291  vars.push_back(new BCP_var_core(BCP_BinaryVar, desc.obj[i], 0, 1));
292  }
293  else {
294  vars.push_back(new BCP_var_core(BCP_IntegerVar, desc.obj[i],
295  desc.clb[i], desc.cub[i]));
296  }
297  }
298  else {
299  vars.push_back(new BCP_var_core(BCP_ContinuousVar, desc.obj[i],
300  desc.clb[i], desc.cub[i]));
301  }
302  }
303 
304  const int corerows = desc.core->getNumRows();
305  for (i=0; i<corerows; ++i) {
306  cuts.push_back(new BCP_cut_core(desc.rlb_core[i], desc.rub_core[i]));
307  }
308 
309  matrix = new BCP_lp_relax;
310 
311  matrix->copyOf(*desc.core, desc.obj, desc.clb, desc.cub,
312  desc.rlb_core, desc.rub_core);
313 }
314 
315 /**************************************************************************/
316 void
318  BCP_vec<BCP_cut*>& added_cuts,
319  BCP_user_data*& user_data)
320 {
321 
322 #ifdef USER_DATA
323  user_data = new MY_user_data(desc.colnum);
324 #endif
325 }
326 
327 /*************************************************************************/
328 void
330 {
331  int i;
332  const BCP_solution_generic *gsol =
333  dynamic_cast<const BCP_solution_generic*>(soln);
334 
335  // put together the solution vector
336 
337  const int colnum = desc.colnum;
338  double* sol = new double[colnum];
339 
340  CoinFillN(sol, colnum, 0.0);
341 
342  const int size = gsol->_vars.size();
343  for (i=0; i<size; ++i) {
344  sol[gsol->_vars[i]->bcpind()] = gsol->_values[i];
345  }
346 
347  cout << "Customized display of the feasible solution:" << endl << endl;
348  cout.setf(ios::fixed);
349  cout.precision(2);
350 
351  for(i=0; i<colnum; i++) {
352  cout << sol[i] << " ";
353 
354  if(i % 10 == 9) {
355  cout << endl;
356  }
357  }
358  cout << endl;
359 
360 
361  cout << "Default BCP display of the feasible solution:" << endl << endl;
363 
364  delete[] sol;
365 }
Binary (0-1) variable.
Definition: BCP_enum.hpp:163
virtual void display_feasible_solution(const BCP_solution *sol)
Display a feasible solution.
BCP_buffer & pack(const T &value)
Pack a single object of type T.
Definition: BCP_buffer.hpp:177
BCP_vec< BCP_var * > _vars
Vector of variables that are at nonzero level in the solution.
int main(int argc, char *argv[])
Definition: BB_tm.cpp:32
BCP_process_t
This enumerative constant describes the various process types.
Core cuts are the cuts that always stay in the LP formulation.
Definition: BCP_cut.hpp:195
BCP_vec< double > _values
Values of these variables in the solution.
Core variables are the variables that always stay in the LP formulation.
Definition: BCP_var.hpp:230
void push_back(const_reference x)
Append x to the end of the vector.
static char * j
Definition: OSdtoa.cpp:3622
void copyOf(const CoinPackedMatrix &m, const double *OBJ, const double *CLB, const double *CUB, const double *RLB, const double *RUB)
Set up the LP relaxation by making a copy of the arguments.
Definition: BCP_matrix.cpp:69
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
#define BCP_DBL_MAX
Definition: BCP_math.hpp:6
virtual void display_feasible_solution(const BCP_solution *sol)
Print a feasible solution.
Definition: BB_tm.cpp:329
Class taking care of interaction between user data and Bcp.
Continuous variable.
Definition: BCP_enum.hpp:167
void readInput(const char *filename)
Read input and set up data in class BB_prob.
Definition: BB_tm.cpp:41
virtual void initialize_core(BCP_vec< BCP_var_core * > &vars, BCP_vec< BCP_cut_core * > &cuts, BCP_lp_relax *&matrix)
Pass the core constraints and core variables to bcp.
Definition: BB_tm.cpp:279
size_t size() const
Return the current number of entries.
Definition: BCP_vector.hpp:116
This class describes the message buffer used for all processes of BCP.
Definition: BCP_buffer.hpp:39
virtual void create_root(BCP_vec< BCP_var * > &added_vars, BCP_vec< BCP_cut * > &added_cuts, BCP_user_data *&user_data)
Create the root node of the enumeration.
Definition: BB_tm.cpp:317
virtual void pack_module_data(BCP_buffer &buf, BCP_process_t ptype)
Pack data into a buffer; will not work in parallel environment as it uses pointer.
Definition: BB_tm.cpp:260
This class holds a MIP feasible primal solution.
General integer variable.
Definition: BCP_enum.hpp:165
An object of type BCP_lp_relax holds the description of an lp relaxation.
Definition: BCP_matrix.hpp:267
This is the abstract base class for a solution to a Mixed Integer Programming problem.