source: stable/2.8/Cbc/examples/parallel2.cpp @ 2004

Last change on this file since 2004 was 2004, checked in by forrest, 5 years ago

more for threadsafe

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