source: trunk/Cbc/examples/parallel.cpp @ 2469

Last change on this file since 2469 was 2469, checked in by unxusr, 6 weeks ago

formatting

File size: 7.3 KB
Line 
1// $Id: parallel.cpp 1902 2013-04-10 16:58:16Z stefan $
2// Copyright (C) 2007, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include <cassert>
7#include <iomanip>
8
9#include "CoinPragma.hpp"
10#include "CbcModel.hpp"
11#include "OsiClpSolverInterface.hpp"
12#include "CbcSolver.hpp"
13
14#include "CoinTime.hpp"
15
16//#############################################################################
17
18/************************************************************************
19
20This main program shows how to take advantage of the standalone cbc in your program,
21while still making major modifications.
22This is like driver4 but executes in parallel
23First it reads in a model from an mps file
24Then it initializes three integer models with cbc defaults
25Then it calls CbcMain0/1 using threads passing parameters
26Finally it prints solution (just for first model)
27
28All models have same parameters unless "-switch" is found so --
29
30miplib/p0033 -solve -switch -heuristic off -solve
31
32would solve first model with heuristics and subsequent ones without
33
34This could be used to try different ideas OR on different models
35
36NOTE -
37The minimum has been done to make thread safe so
38no interrupts
39-quit is added to make sure just reads from argv
40*/
41/*************************************************************************/
42#define USE_PTHREAD
43#ifdef USE_PTHREAD
44#include <pthread.h>
45#endif
46/* Return non-zero to return quickly */
47static int callBack(CbcModel *model, int whereFrom)
48{
49  int returnCode = 0;
50  switch (whereFrom) {
51  case 1:
52  case 2:
53    if (!model->status() && model->secondaryStatus())
54      returnCode = 1;
55    break;
56  case 3: {
57    //CbcCompareUser compare;
58    //model->setNodeComparison(compare);
59  } break;
60  case 4:
61    // If not good enough could skip postprocessing
62    break;
63  case 5:
64    break;
65  default:
66    abort();
67  }
68  return returnCode;
69}
70// For threads
71typedef struct {
72  CbcModel *model;
73  CbcSolverUsefulData *data;
74  int argc;
75  char **argv;
76} threadStuff;
77static void *doThread(void *voidInfo)
78{
79  threadStuff *stuff = reinterpret_cast< threadStuff * >(voidInfo);
80  CbcModel *model = stuff->model;
81  CbcMain0(*model, *stuff->data);
82  // Now go into code for standalone solver
83  CbcMain1(stuff->argc, const_cast< const char ** >(stuff->argv),
84    *model, callBack, *stuff->data);
85  return NULL;
86}
87int main(int argc, const char *argv[])
88{
89  // Number of models to do at once
90  int numberModels = 3;
91  // Stuff for each model
92  CbcModel *allModels = new CbcModel[numberModels];
93  OsiClpSolverInterface *allSolvers = new OsiClpSolverInterface[numberModels];
94  CbcSolverUsefulData *data = new CbcSolverUsefulData[numberModels];
95  threadStuff *allData = new threadStuff[numberModels];
96  // First populate first model
97  /* in a real application models would be different */
98  OsiClpSolverInterface &solver1 = allSolvers[0];
99  // Read in model using argv[1]
100  // and assert that it is a clean model
101  std::string mpsFileName;
102#if defined(SAMPLEDIR)
103  mpsFileName = SAMPLEDIR "/p0033.mps";
104#else
105  if (argc < 2) {
106    fprintf(stderr, "Do not know where to find sample MPS files.\n");
107    exit(1);
108  }
109#endif
110  if (argc >= 2)
111    mpsFileName = argv[1];
112  int numMpsReadErrors = solver1.readMps(mpsFileName.c_str(), "");
113  if (numMpsReadErrors != 0) {
114    printf("%d errors reading MPS file\n", numMpsReadErrors);
115    return numMpsReadErrors;
116  }
117  // Tell solver to return fast if presolve or initial solve infeasible
118  solver1.getModelPtr()->setMoreSpecialOptions(3);
119  // create models
120  for (int iModel = 1; iModel < numberModels; iModel++) {
121    allSolvers[iModel] = solver1;
122  }
123  // now create CbcModels and copy parameters (up to end or -switch)
124  // Pass to Cbc initialize defaults
125  CbcModel modelA(solver1);
126  int lastArgPosition = 2;
127  int lastArgc = 0;
128  for (int iModel = 0; iModel < numberModels; iModel++) {
129    allModels[iModel] = CbcModel(allSolvers[iModel]);
130    // default does NOT allow interrupts
131    // allow printing
132    data[iModel].noPrinting_ = false;
133    allData[iModel].model = allModels + iModel;
134    allData[iModel].data = data + iModel;
135    // See how many parameters
136    int endArgc = lastArgPosition;
137    int thisArgc = lastArgc;
138    for (; endArgc < argc; endArgc++) {
139      if (!strcmp(argv[endArgc], "-switch"))
140        break;
141    }
142    thisArgc = endArgc - lastArgPosition;
143    if (thisArgc > 0)
144      lastArgc = thisArgc;
145    else
146      thisArgc = lastArgc;
147    // allow extra for -quit
148    char **thisArgv = new char *[thisArgc + 2];
149    thisArgv[0] = strdup(argv[0]);
150    int put = 1;
151    for (int iArgc = lastArgPosition; iArgc < lastArgPosition + thisArgc; iArgc++)
152      thisArgv[put++] = strdup(argv[iArgc]);
153    // add -quit
154    thisArgv[put++] = strdup("-quit");
155    allData[iModel].argc = put;
156    allData[iModel].argv = thisArgv;
157    if (endArgc < argc)
158      lastArgPosition = endArgc + 1;
159  }
160#ifdef USE_PTHREAD
161  pthread_t *threadId = new pthread_t[numberModels];
162  // solve
163  for (int iModel = 0; iModel < numberModels; iModel++) {
164    pthread_create(threadId + iModel, NULL,
165      doThread,
166      allData + iModel);
167  }
168  // wait
169  for (int iModel = 0; iModel < numberModels; iModel++) {
170    pthread_join(threadId[iModel], NULL);
171  }
172#else
173  for (int iModel = 0; iModel < numberModels; iModel++) {
174    doThread(allData + iModel);
175  }
176#endif
177  // Just print first one
178  CbcModel *model = allModels;
179  // Solver was cloned so get current copy
180  OsiSolverInterface *solver = model->solver();
181  // Print solution if finished (could get from model->bestSolution() as well
182
183  if (model->bestSolution()) {
184
185    const double *solution = solver->getColSolution();
186
187    int iColumn;
188    int numberColumns = solver->getNumCols();
189    std::cout << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setw(14);
190
191    std::cout << "--------------------------------------" << std::endl;
192#ifdef USE_OSI_NAMES
193
194    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
195      double value = solution[iColumn];
196      if (fabs(value) > 1.0e-7 && solver->isInteger(iColumn))
197        std::cout << std::setw(6) << iColumn << " " << std::setw(8) << setiosflags(std::ios::left) << solver->getColName(iColumn)
198                  << resetiosflags(std::ios::adjustfield) << std::setw(14) << " " << value << std::endl;
199    }
200#else
201    // names may not be in current solver - use original
202
203    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
204      double value = solution[iColumn];
205      if (fabs(value) > 1.0e-7 && solver->isInteger(iColumn))
206        std::cout << std::setw(6) << iColumn << " " << std::setw(8) << setiosflags(std::ios::left) << solver1.getModelPtr()->columnName(iColumn)
207                  << resetiosflags(std::ios::adjustfield) << std::setw(14) << " " << value << std::endl;
208    }
209#endif
210    std::cout << "--------------------------------------" << std::endl;
211
212    std::cout << std::resetiosflags(std::ios::fixed | std::ios::showpoint | std::ios::scientific);
213  } else {
214    std::cout << " No solution!" << std::endl;
215  }
216  delete[] allModels;
217  delete[] allSolvers;
218  delete[] data;
219  for (int iModel = 0; iModel < numberModels; iModel++) {
220    char **argv = allData[iModel].argv;
221    int argc = allData[iModel].argc;
222    for (int i = 0; i < argc; i++)
223      free(argv[i]);
224    delete[] argv;
225  }
226  delete[] allData;
227#ifdef USE_PTHREAD
228  delete[] threadId;
229#endif
230  return 0;
231}
Note: See TracBrowser for help on using the repository browser.