00001
00021
00022
00023 #include "OSCoinSolver.h"
00024 #include "OSInstance.h"
00025 #include "OSFileUtil.h"
00026 #include "CoinTime.hpp"
00027 #include "CglPreProcess.hpp"
00028 #include "CglGomory.hpp"
00029 #include "CglSimpleRounding.hpp"
00030 #include "CglMixedIntegerRounding2.hpp"
00031 #include "CglKnapsackCover.hpp"
00032 #include "CglFlowCover.hpp"
00033 #include "CbcBranchActual.hpp"
00034 #include "CoinMessageHandler.hpp"
00035 #include "CoinMessage.hpp"
00036
00037 #include "OsiClpSolverInterface.hpp"
00038
00039 #ifdef COIN_HAS_SYMPHONY
00040 #include "OsiSymSolverInterface.hpp"
00041 #endif
00042
00043 #ifdef COIN_HAS_VOL
00044 #include "OsiVolSolverInterface.hpp"
00045 #endif
00046
00047 #ifdef COIN_HAS_DYLP
00048 #include "OsiDylpSolverInterface.hpp"
00049 #endif
00050
00051 #ifdef COIN_HAS_GLPK
00052 #include "OsiGlpkSolverInterface.hpp"
00053 #endif
00054
00055 #ifdef COIN_HAS_CPX
00056 #include "OsiCpxSolverInterface.hpp"
00057 #endif
00058
00059 #include "OSDataStructures.h"
00060 #include "OSParameters.h"
00061 #include "OSMathUtil.h"
00062
00063 #include<map>
00064
00065 #include <iostream>
00066 #ifdef HAVE_CTIME
00067 # include <ctime>
00068 #else
00069 # ifdef HAVE_TIME_H
00070 # include <time.h>
00071 # else
00072 # error "don't have header file for time"
00073 # endif
00074 #endif
00075 using std::cout;
00076 using std::endl;
00077 using std::ostringstream;
00078
00079
00080
00081 CoinSolver::CoinSolver() :
00082 osiSolver(NULL),
00083 m_osilreader(NULL),
00084 m_osolreader(NULL),
00085 m_CoinPackedMatrix(NULL),
00086 cbc_argv( NULL),
00087 num_cbc_argv( 0),
00088 cpuTime( 0)
00089
00090 {
00091 osrlwriter = new OSrLWriter();
00092 }
00093
00094 CoinSolver::~CoinSolver() {
00095 #ifdef DEBUG
00096 cout << "inside CoinSolver destructor" << endl;
00097 #endif
00098 if(m_osilreader != NULL) delete m_osilreader;
00099 m_osilreader = NULL;
00100 if(m_osolreader != NULL) delete m_osolreader;
00101 m_osolreader = NULL;
00102 delete m_CoinPackedMatrix;
00103 m_CoinPackedMatrix = NULL;
00104 delete osiSolver;
00105 if(osiSolver != NULL) osiSolver = NULL;
00106 delete osrlwriter;
00107 osrlwriter = NULL;
00108 delete osresult;
00109 osresult = NULL;
00110 if(num_cbc_argv > 0){
00111 int i;
00112 for(i = 0; i < num_cbc_argv; i++){
00113
00114 }
00115
00116 cbc_argv = NULL;
00117 }
00118 #ifdef DEBUG
00119 cout << "leaving CoinSolver destructor" << endl;
00120 #endif
00121 }
00122
00123
00124 void CoinSolver::buildSolverInstance() throw (ErrorClass) {
00125 try{
00126 osresult = new OSResult();
00127 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00128 clock_t start, finish;
00129 double duration;
00130 start = clock();
00131 if(osinstance == NULL){
00132 m_osilreader = new OSiLReader();
00133 osinstance = m_osilreader->readOSiL( osil);
00134 }
00135 finish = clock();
00136 duration = (double) (finish - start) / CLOCKS_PER_SEC;
00137
00138 bool solverIsDefined = false;
00139 if( sSolverName.find("clp") != std::string::npos){
00140 solverIsDefined = true;
00141 osiSolver = new OsiClpSolverInterface();
00142 }
00143 else{
00144 if( sSolverName.find("vol") != std::string::npos){
00145 #ifdef COIN_HAS_VOL
00146 solverIsDefined = true;
00147 osiSolver = new OsiVolSolverInterface();
00148 #endif
00149 }
00150 else{
00151 if( sSolverName.find( "cplex") != std::string::npos){
00152 #ifdef COIN_HAS_CPX
00153 solverIsDefined = true;
00154 osiSolver = new OsiCpxSolverInterface();
00155 #endif
00156 }
00157 else{
00158 if(sSolverName.find( "glpk") != std::string::npos){
00159 #ifdef COIN_HAS_GLPK
00160 solverIsDefined = true;
00161 osiSolver = new OsiGlpkSolverInterface();
00162 #endif
00163 }
00164 else{
00165 if(sSolverName.find( "dylp") != std::string::npos){
00166 #ifdef COIN_HAS_DYLP
00167 solverIsDefined = true;
00168 osiSolver = new OsiDylpSolverInterface();
00169 #endif
00170 }
00171 else{
00172 if( sSolverName.find( "symphony") != std::string::npos) {
00173 #ifdef COIN_HAS_SYMPHONY
00174 solverIsDefined = true;
00175 osiSolver = new OsiSymSolverInterface();
00176 #endif
00177 }
00178 else{
00179
00180
00181 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0) sSolverName = "cbc";
00182 else sSolverName = "clp";
00183 solverIsDefined = true;
00184 osiSolver = new OsiClpSolverInterface();
00185 }
00186 }
00187 }
00188 }
00189 }
00190 }
00191
00192 if(solverIsDefined == false) throw ErrorClass("a supported solver was not defined");
00193
00194
00195 if( (osinstance->getNumberOfNonlinearExpressions() > 0)
00196 || (osinstance->getNumberOfQuadraticTerms() > 0) ){
00197 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
00198 }
00199
00200 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00201 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
00202 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
00203 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
00204
00205 }
00206
00207
00208
00209 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver:" + sSolverName + " needs an objective function");
00210 if(osinstance->getNumberOfStringVariables() > 0) throw ErrorClass("Coin solver:" + sSolverName + " can only handle numeric variables");
00211 if(osinstance->getLinearConstraintCoefficientNumber() <= 0 && sSolverName == "symphony") throw ErrorClass("Coin solver:" + sSolverName + " needs a positive number of variables");
00212
00213 if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
00214 osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(),
00215 osinstance->getVariableUpperBounds(),
00216 osinstance->getDenseObjectiveCoefficients()[0],
00217 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
00218 );
00219
00220
00221 if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
00222 else osiSolver->setObjSense(-1.0);
00223
00224 int *intIndex = NULL;
00225 int i = 0;
00226 int k = 0;
00227 char *varType;
00228 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00229 if(numOfIntVars > 0) {
00230 intIndex = new int[ numOfIntVars];
00231 varType = osinstance->getVariableTypes();
00232 for(i = 0; i < osinstance->getVariableNumber(); i++){
00233 if( (varType[i] == 'B') || (varType[i]) == 'I' ) {
00234 intIndex[k++] = i;
00235 }
00236 }
00237 osiSolver->setInteger( intIndex, numOfIntVars);
00238 }
00239 if(numOfIntVars > 0){
00240 delete[] intIndex;
00241 intIndex = NULL;
00242 }
00243 bCallbuildSolverInstance = true;
00244 }
00245 catch(const ErrorClass& eclass){
00246 osresult->setGeneralMessage( eclass.errormsg);
00247 osresult->setGeneralStatusType( "error");
00248 osrl = osrlwriter->writeOSrL( osresult);
00249 throw ErrorClass( osrl) ;
00250 }
00251 }
00252
00253
00254
00255 void CoinSolver::setSolverOptions() throw (ErrorClass) {
00256
00257 #ifdef DEBUG
00258 std::cout << "build solver options" << std::endl;
00259 #endif
00260 this->bSetSolverOptions = true;
00261
00262
00263 std::map<std::string, OsiHintParam> hintParamMap;
00264 hintParamMap["OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
00265 hintParamMap["OsiDoDualInInitial"] = OsiDoDualInInitial;
00266 hintParamMap["OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
00267 hintParamMap["OsiDoDualInResolve"] = OsiDoDualInResolve;
00268 hintParamMap["OsiDoScale"] = OsiDoScale;
00269 hintParamMap["OsiDoCrash"] = OsiDoCrash;
00270 hintParamMap["OsiDoReducePrint"] = OsiDoReducePrint;
00271 hintParamMap["OsiDoInBranchAndCut"] = OsiDoInBranchAndCut;
00272 hintParamMap["OsiLastHintParam"] = OsiLastHintParam;
00273
00274
00275 std::map<std::string, OsiHintStrength> hintStrengthMap;
00276 hintStrengthMap["OsiHintIgnore"] = OsiHintIgnore;
00277 hintStrengthMap["OsiHintTry"] = OsiHintTry;
00278 hintStrengthMap["OsiHintDo"] = OsiHintDo;
00279 hintStrengthMap["OsiForceDo"] = OsiForceDo;
00280
00281
00282 std::map<std::string, OsiStrParam> strParamMap;
00283 strParamMap["OsiProbName"] = OsiProbName;
00284 strParamMap["OsiSolverName"] = OsiSolverName;
00285 strParamMap["OsiLastStrParam"] = OsiLastStrParam;
00286
00287
00288 std::map<std::string, OsiDblParam> dblParamMap;
00289 dblParamMap["OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
00290 dblParamMap["OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
00291 dblParamMap["OsiDualTolerance"] = OsiDualTolerance;
00292 dblParamMap["OsiPrimalTolerance"] = OsiPrimalTolerance;
00293 dblParamMap["OsiObjOffset"] = OsiObjOffset;
00294 dblParamMap["OsiLastDblParam"] = OsiLastDblParam;
00295
00296
00297
00298 std::map<std::string, OsiIntParam> intParamMap;
00299 intParamMap["OsiMaxNumIteration"] = OsiMaxNumIteration;
00300 intParamMap["OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
00301 intParamMap["OsiNameDiscipline"] = OsiNameDiscipline;
00302 intParamMap["OsiLastIntParam"] = OsiLastIntParam;
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 OsiHintStrength hintStrength = OsiHintTry;
00314 osiSolver->setHintParam(OsiDoReducePrint, true, hintStrength);
00315
00316
00317 osiSolver->setDblParam(OsiObjOffset, -osinstance->getObjectiveConstants()[0]);
00318
00319
00320
00321
00322 #ifdef COIN_HAS_SYMPHONY
00323 if( sSolverName.find( "symphony") != std::string::npos) {
00324 OsiSymSolverInterface * si =
00325 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00326
00327 si->setSymParam("verbosity", -2);
00328 }
00329 #endif //symphony end
00330
00331
00332
00333
00334
00335
00336 try{
00337 if(osoption == NULL && osol.length() > 0)
00338 {
00339 m_osolreader = new OSoLReader();
00340 osoption = m_osolreader->readOSoL( osol);
00341 }
00342
00343 if(osoption != NULL){
00344
00345 #ifdef DEBUG
00346 std::cout << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
00347 #endif
00348 if( osoption->getNumberOfSolverOptions() <= 0) return;
00349
00350 std::vector<SolverOption*> optionsVector;
00351
00352 optionsVector = osoption->getSolverOptions( "osi");
00353 int num_osi_options = optionsVector.size();
00354 int i;
00355 char *pEnd;
00356 bool yesNo;
00357
00358 for(i = 0; i < num_osi_options; i++){
00359 #ifdef DEBUG
00360 std::cout << "osi solver option " << optionsVector[ i]->name << std::endl;
00361 #endif
00362 if (optionsVector[ i]->type == "OsiHintStrength" ){
00363 if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() ){
00364 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
00365 }
00366 }
00367 }
00368 for(i = 0; i < num_osi_options; i++){
00369 #ifdef DEBUG
00370 std::cout << "osi solver option " << optionsVector[ i]->name << std::endl;
00371 #endif
00372 if (optionsVector[ i]->type == "OsiHintParam" ){
00373
00374 if( optionsVector[ i]->value == "true" ) {
00375 yesNo = true;
00376 }
00377 else{
00378 yesNo = false;
00379 }
00380 if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() ){
00381
00382 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
00383 }
00384
00385 }
00386 else if(optionsVector[ i]->type == "OsiStrParam" ){
00387
00388 if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() ){
00389
00390 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
00391 }
00392
00393 }
00394 else if(optionsVector[ i]->type == "OsiDblParam" ){
00395
00396 if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() ){
00397
00398 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] , os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
00399 }
00400
00401 }
00402 else if(optionsVector[ i]->type == "OsiIntParam" ){
00403
00404
00405 if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() ){
00406
00407 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
00408 }
00409
00410 }
00411 }
00412
00413
00414
00415 if( sSolverName.find( "cbc") != std::string::npos) {
00416
00417 if(optionsVector.size() > 0) optionsVector.clear();
00418 optionsVector = osoption->getSolverOptions( "cbc");
00419 int num_cbc_options = optionsVector.size();
00420 char *cstr;
00421 std::string cbc_option;
00422 num_cbc_argv = optionsVector.size() + 3;
00423 cbc_argv = new const char*[ num_cbc_argv];
00424
00425
00426 cbc_option = "OS";
00427 cstr = new char [cbc_option.size() + 1];
00428 strcpy (cstr, cbc_option.c_str());
00429 cbc_argv[ 0] = cstr;
00430
00431
00432 for(i = 0; i < num_cbc_options; i++){
00433 #ifdef DEBUG
00434 std::cout << "cbc solver option " << optionsVector[ i]->name << std::endl;
00435 std::cout << "cbc solver value " << optionsVector[ i]->value << std::endl;
00436 #endif
00437 if(optionsVector[ i]->value.length() > 0){
00438 cbc_option = "-" + optionsVector[ i]->name +"="+optionsVector[ i]->value;
00439 }
00440 else{
00441 cbc_option = "-" + optionsVector[ i]->name ;
00442 }
00443 cstr = new char [cbc_option.size() + 1];
00444 strcpy (cstr, cbc_option.c_str());
00445 cbc_argv[i + 1] = cstr;
00446 }
00447
00448
00449 cbc_option = "-solve";
00450 cstr = new char [cbc_option.size() + 1];
00451 strcpy (cstr, cbc_option.c_str());
00452 cbc_argv[ num_cbc_argv - 2] = cstr;
00453
00454
00455 cbc_option = "-quit";
00456 cstr = new char [cbc_option.size() + 1];
00457 strcpy (cstr, cbc_option.c_str());
00458 cbc_argv[ num_cbc_argv - 1] = cstr;
00459
00460 }
00461
00462
00463
00464
00465 #ifdef COIN_HAS_SYMPHONY
00466 if(optionsVector.size() > 0) optionsVector.clear();
00467
00468
00469 if( sSolverName.find( "symphony") != std::string::npos) {
00470 OsiSymSolverInterface * si =
00471 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00472 optionsVector = osoption->getSolverOptions( "symphony");
00473 int num_sym_options = optionsVector.size();
00474 for(i = 0; i < num_sym_options; i++){
00475 #ifdef DEBUG
00476 std::cout << "symphony solver option " << optionsVector[ i]->name << std::endl;
00477 std::cout << "symphony solver value " << optionsVector[ i]->value << std::endl;
00478 #endif
00479 si->setSymParam(optionsVector[ i]->name, optionsVector[ i]->value);
00480 }
00481 }
00482 #endif //symphony end
00483
00484
00485 int n,m,k;
00486 if (osoption != NULL)
00487 m = osoption->getNumberOfInitVarValues();
00488 else
00489 m = 0;
00490 #ifdef DEBUG
00491 cout << "number of variables initialed: " << m << endl;
00492 #endif
00493
00494 if (m > 0)
00495 {
00496 #ifdef DEBUG
00497 cout << "get initial values " << endl;
00498 #endif
00499 n = osinstance->getVariableNumber();
00500 double* denseInitVarVector;
00501 denseInitVarVector = new double[n];
00502 bool* initialed;
00503 initialed = new bool[n];
00504
00505 for(k = 0; k < n; k++)
00506 initialed[k] = false;
00507
00508 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
00509 #ifdef DEBUG
00510 cout << "done " << endl;
00511 #endif
00512
00513 double initval;
00514 for(k = 0; k < m; k++){
00515 i = initVarVector[k]->idx;
00516 if (initVarVector[k]->idx > n)
00517 throw ErrorClass ("Illegal index value in variable initialization");
00518
00519 initval = initVarVector[k]->value;
00520 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00521 { if (osinstance->instanceData->variables->var[k]->lb > initval)
00522 throw ErrorClass ("Initial value outside of bounds");
00523 }
00524 else
00525 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00526 { if (osinstance->instanceData->variables->var[k]->ub < initval)
00527 throw ErrorClass ("Initial value outside of bounds");
00528 }
00529 else
00530 { if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
00531 (osinstance->instanceData->variables->var[k]->ub < initval))
00532 throw ErrorClass ("Initial value outside of bounds");
00533 }
00534
00535 denseInitVarVector[initVarVector[k]->idx] = initval;
00536 initialed[initVarVector[k]->idx] = true;
00537 }
00538
00539 double default_initval;
00540 default_initval = 0.0;
00541
00542 for(k = 0; k < n; k++){
00543 if (!initialed[k])
00544 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00545 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00546 denseInitVarVector[k] = default_initval;
00547 else
00548 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00549 else
00550 if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00551 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00552 denseInitVarVector[k] = default_initval;
00553 else
00554 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00555 else
00556 if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
00557 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00558 denseInitVarVector[k] = default_initval;
00559 else
00560 if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00561 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00562 else
00563 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00564 denseInitVarVector[k] = default_initval;
00565 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00566 }
00567 #ifdef DEBUG
00568 cout << "set initial values: " << endl;
00569 for (k=0; k < n; k++)
00570 cout << " " << k << ": " << denseInitVarVector[k] << endl;
00571 #endif
00572 osiSolver->setColSolution( denseInitVarVector);
00573 delete[] denseInitVarVector;
00574 delete[] initialed;
00575 #ifdef DEBUG
00576 cout << "done " << endl;
00577 #endif
00578
00579 }
00580 }
00581
00582 #ifdef DEBUG
00583 std::cout << "solver options set" << std::endl;
00584 #endif
00585 }
00586 catch(const ErrorClass& eclass){
00587 std::cout << "THERE IS AN ERROR" << std::endl;
00588 osresult->setGeneralMessage( eclass.errormsg);
00589 osresult->setGeneralStatusType( "error");
00590 osrl = osrlwriter->writeOSrL( osresult);
00591 throw ErrorClass( osrl) ;
00592 }
00593 }
00594
00595
00596 bool CoinSolver::setCoinPackedMatrix(){
00597 bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
00598 try{
00599 double maxGap = 0;
00600 if(osinstance->getVariableNumber() > 0){
00601 m_CoinPackedMatrix = new CoinPackedMatrix(
00602 columnMajor,
00603 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00604 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00605 osinstance->getLinearConstraintCoefficientNumber(),
00606 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values,
00607 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes,
00608 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts,
00609 0, 0, maxGap );
00610 }else {
00611 int start = 0;
00612 m_CoinPackedMatrix = new CoinPackedMatrix(
00613 columnMajor,
00614 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00615 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00616 osinstance->getLinearConstraintCoefficientNumber(),
00617 NULL,
00618 NULL,
00619 &start,
00620 NULL, 0.0, maxGap );
00621 }
00622
00623
00624 return true;
00625 }
00626 catch(const ErrorClass& eclass){
00627 osresult->setGeneralMessage( eclass.errormsg);
00628 osresult->setGeneralStatusType( "error");
00629 osrl = osrlwriter->writeOSrL( osresult);
00630 throw ErrorClass( osrl) ;
00631 }
00632 }
00633
00634 void CoinSolver::solve() throw (ErrorClass) {
00635 try{
00636
00637 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00638
00639 if( this->bSetSolverOptions == false) setSolverOptions();
00640 }
00641 catch(const ErrorClass& eclass){
00642 throw ErrorClass( osrl) ;
00643 }
00644
00645
00646 if(osresult->setSolverInvoked("COIN-OR " + sSolverName) != true)
00647 throw ErrorClass("OSResult error: SetSolverInvoked");
00648 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00649 throw ErrorClass("OSResult error: setInstanceName");
00650
00651
00652
00653
00654
00655
00656 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00657 throw ErrorClass("OSResult error: setVariableNumer");
00658 if(osresult->setObjectiveNumber( 1) != true)
00659 throw ErrorClass("OSResult error: setObjectiveNumber");
00660 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00661 throw ErrorClass("OSResult error: setConstraintNumber");
00662 if(osresult->setSolutionNumber( 1) != true)
00663 throw ErrorClass("OSResult error: setSolutionNumer");
00664
00665
00666 try{
00667 double start = CoinCpuTime();
00668 try{
00669 if( sSolverName.find( "cbc") != std::string::npos){
00670
00671
00672 CbcModel model( *osiSolver);
00673
00674
00675
00676
00677
00678
00679
00680 CbcMain0( model);
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 if(num_cbc_argv <= 0){
00700 char *cstr;
00701 std::string cbc_option;
00702 num_cbc_argv = 4;
00703 cbc_argv = new const char*[ num_cbc_argv];
00704
00705
00706 cbc_option = "OS";
00707 cstr = new char [cbc_option.size() + 1];
00708 strcpy (cstr, cbc_option.c_str());
00709 cbc_argv[ 0] = cstr;
00710
00711
00712
00713 cbc_option = "-log=0";
00714 cstr = new char [cbc_option.size() + 1];
00715 strcpy (cstr, cbc_option.c_str());
00716 cbc_argv[ 1] = cstr;
00717
00718
00719
00720 cbc_option = "-solve";
00721 cstr = new char [cbc_option.size() + 1];
00722 strcpy (cstr, cbc_option.c_str());
00723 cbc_argv[ 2] = cstr;
00724
00725
00726 cbc_option = "-quit";
00727 cstr = new char [cbc_option.size() + 1];
00728 strcpy (cstr, cbc_option.c_str());
00729 cbc_argv[ 3] = cstr;
00730
00731 }
00732 int i;
00733
00734 #ifdef DEBUG
00735 std::cout << "CALLING THE CBC SOLVER CBCMAIN1()" << std::endl;
00736 for(i = 0; i < num_cbc_argv; i++){
00737 std::cout << "Cbc Option: " << cbc_argv[ i] << std::endl;
00738 }
00739 #endif
00740
00741 CbcMain1( num_cbc_argv, cbc_argv, model);
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 for(i = 0; i < num_cbc_argv; i++){
00761 delete[] cbc_argv[ i];
00762 cbc_argv[i] = NULL;
00763 }
00764 if( num_cbc_argv > 0){
00765 delete[] cbc_argv;
00766 cbc_argv = NULL;
00767 num_cbc_argv = 0;
00768 }
00769
00770
00771
00772 cpuTime = CoinCpuTime() - start;
00773
00774
00775 OsiSolverInterface *solver = model.solver();
00776 if(osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00777 writeResult( &model);
00778 }else{
00779 writeResult( solver);
00780 }
00781 }
00782 else{
00783
00784 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00785 osiSolver->branchAndBound();
00786 }
00787 else{
00788 osiSolver->initialSolve();
00789 }
00790 cpuTime = CoinCpuTime() - start;
00791
00792 writeResult( osiSolver);
00793 }
00794
00795
00796 }
00797 catch(CoinError e){
00798 std::string errmsg;
00799 errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "
00800 + e.methodName() + " in class " + e.className();
00801 throw ErrorClass( errmsg );
00802 }
00803
00804 }
00805 catch(const ErrorClass& eclass){
00806 osresult->setGeneralMessage( eclass.errormsg);
00807 osresult->setGeneralStatusType( "error");
00808 osrl = osrlwriter->writeOSrL( osresult);
00809 throw ErrorClass( osrl) ;
00810 }
00811 }
00812
00813 std::string CoinSolver::getCoinSolverType(std::string lcl_osol){
00814
00815 try{
00816 if( lcl_osol.find( "clp") != std::string::npos){
00817 return "coin_solver_glpk";
00818 }
00819 else{
00820 if( lcl_osol.find( "cbc") != std::string::npos){
00821 return "coin_solver_cpx";
00822 }
00823 else{
00824 if( lcl_osol.find( "cpx") != std::string::npos){
00825 return "coin_solver_clp";
00826 }
00827 else{
00828 if(lcl_osol.find( "glpk") != std::string::npos){
00829 return "";
00830 }
00831 else throw ErrorClass("a supported solver was not defined");
00832 }
00833 }
00834 }
00835 }
00836 catch(const ErrorClass& eclass){
00837 osresult->setGeneralMessage( eclass.errormsg);
00838 osresult->setGeneralStatusType( "error");
00839 osrl = osrlwriter->writeOSrL( osresult);
00840 throw ErrorClass( osrl) ;
00841 }
00842 }
00843
00844 void CoinSolver::dataEchoCheck(){
00845 int i;
00846
00847 cout << "This is problem: " << osinstance->getInstanceName() << endl;
00848 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
00849 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
00850 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00851 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00852
00853
00854 if(osinstance->getVariableNumber() > 0){
00855 for(i = 0; i < osinstance->getVariableNumber(); i++){
00856 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
00857 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
00858 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
00859 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
00860 }
00861 }
00862
00863
00864 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
00865 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
00866 else cout << "problem is a maximization" << endl;
00867 for(i = 0; i < osinstance->getVariableNumber(); i++){
00868 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00869 }
00870 }
00871
00872 if(osinstance->getConstraintNumber() > 0){
00873 for(i = 0; i < osinstance->getConstraintNumber(); i++){
00874 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
00875 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
00876 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
00877 }
00878 }
00879
00880
00881 if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
00882 }
00883
00884
00885
00886 void CoinSolver::writeResult(OsiSolverInterface *solver){
00887 double *x = NULL;
00888 double *y = NULL;
00889 double *z = NULL;
00890 int *idx = NULL;
00891 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00892 std::string *rcost = NULL;
00893 if( osinstance->getVariableNumber() > 0 ) x = new double[osinstance->getVariableNumber() ];
00894 if( osinstance->getConstraintNumber() > 0 ) y = new double[osinstance->getConstraintNumber() ];
00895 if( osinstance->getVariableNumber() > 0 ) idx = new int[ osinstance->getVariableNumber() ];
00896 z = new double[1];
00897 if( osinstance->getVariableNumber() > 0 ) rcost = new std::string[ osinstance->getVariableNumber()];
00898 int numberOfVar = osinstance->getVariableNumber();
00899 int solIdx = 0;
00900 int i = 0;
00901 int numberOfOtherVariableResults = 1;
00902 int otherIdx = 0;
00903 std::string description = "";
00904 osresult->setGeneralStatusType("normal");
00905 osresult->setTime(cpuTime);
00906 osresult->setServiceName( getVersionInfo() );
00907 osresult->setSolverInvoked( "COIN-OR " + sSolverName );
00908 if (solver->isProvenOptimal() == true){
00909 osresult->setSolutionStatus(solIdx, "optimal", description);
00910 }
00911 else{
00912 if(solver->isProvenPrimalInfeasible() == true)
00913 osresult->setSolutionStatus(solIdx, "infeasible", "the problem is primal infeasible");
00914 else{
00915 if(solver->isProvenDualInfeasible() == true)
00916 osresult->setSolutionStatus(solIdx, "unbounded", "the problem is unbounded");
00917 else{
00918 if(solver->isPrimalObjectiveLimitReached() == true)
00919 osresult->setSolutionStatus(solIdx, "other", "primal objective limit reached");
00920 else{
00921 if(solver->isDualObjectiveLimitReached() == true)
00922 osresult->setSolutionStatus(solIdx, "other", "dual objective limit reached");
00923 else{
00924 if(solver->isIterationLimitReached() == true)
00925 osresult->setSolutionStatus(solIdx, "other", "iteration limit reached");
00926 else{
00927 if(solver->isAbandoned() == true)
00928 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
00929 if( osinstance->getVariableNumber() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
00930 else
00931 osresult->setSolutionStatus(solIdx, "other", description);
00932 }
00933 }
00934 }
00935 }
00936 }
00937 }
00938
00939
00940
00941 *(z + 0) = solver->getObjValue();
00942
00943 osresult->setObjectiveValuesDense(solIdx, z);
00944 for(i=0; i < osinstance->getVariableNumber(); i++){
00945 *(x + i) = solver->getColSolution()[i];
00946 *(idx + i) = i;
00947 }
00948 osresult->setPrimalVariableValuesDense(solIdx, x);
00949
00950 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0) {
00951 assert(solver->getNumRows() >= osinstance->getConstraintNumber());
00952 assert(solver->getRowPrice() != NULL);
00953 for(i=0; i < osinstance->getConstraintNumber(); i++){
00954 *(y + i) = solver->getRowPrice()[ i];
00955 }
00956 if(numOfIntVars <= 0) osresult->setDualVariableValuesDense(solIdx, y);
00957 }
00958
00959
00960 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0){
00961
00962 if(numOfIntVars <= 0){
00963 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
00964 for(i=0; i < numberOfVar; i++){
00965 rcost[ i] = os_dtoa_format( solver->getReducedCost()[ i]);
00966 }
00967 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx, rcost, osinstance->getVariableNumber());
00968
00969 }
00970 }
00971 osrl = osrlwriter->writeOSrL( osresult);
00972 if(osinstance->getVariableNumber() > 0) delete[] x;
00973 x = NULL;
00974 if(osinstance->getConstraintNumber() > 0) delete[] y;
00975 y = NULL;
00976 delete[] z;
00977 z = NULL;
00978 if(osinstance->getVariableNumber() > 0){
00979 delete[] rcost;
00980 rcost = NULL;
00981 delete[] idx;
00982 idx = NULL;
00983 }
00984 }
00985
00986
00987 void CoinSolver::writeResult(CbcModel *model){
00988 double *x = NULL;
00989 double *y = NULL;
00990 double *z = NULL;
00991 int *idx = NULL;
00992 std::string *rcost = NULL;
00993 if( osinstance->getVariableNumber() > 0 ) x = new double[osinstance->getVariableNumber() ];
00994 if( osinstance->getConstraintNumber() > 0 ) y = new double[osinstance->getConstraintNumber() ];
00995 if( osinstance->getVariableNumber() > 0 ) idx = new int[ osinstance->getVariableNumber() ];
00996 z = new double[1];
00997 if( osinstance->getVariableNumber() > 0 ) rcost = new std::string[ osinstance->getVariableNumber()];
00998
00999 int numberOfOtherVariableResults = 1;
01000 int otherIdx = 0;
01001 int numberOfVar = osinstance->getVariableNumber();
01002 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
01003 int i = 0;
01004 int solIdx = 0;
01005 std::string description = "";
01006 osresult->setGeneralStatusType("normal");
01007 osresult->setTime(cpuTime);
01008 osresult->setServiceName( getVersionInfo() );
01009
01010 if (model->isProvenOptimal() == true ){
01011 osresult->setSolutionStatus(solIdx, "optimal", description);
01012 }
01013 else{
01014 if(model->isProvenInfeasible() == true)
01015 osresult->setSolutionStatus(solIdx, "infeasible", "the integer program is infeasible");
01016 else{
01017 if(model->isProvenDualInfeasible() == true)
01018 osresult->setSolutionStatus(solIdx, "infeasible", "the continuous relaxation is dual infeasible");
01019 else{
01020 if(model->isContinuousUnbounded() == true)
01021 osresult->setSolutionStatus(solIdx, "other", "the continuous relaxation is unbounded");
01022 else{
01023 if(model->isNodeLimitReached() == true)
01024 osresult->setSolutionStatus(solIdx, "other", "node limit reached");
01025 else{
01026 if(model->isSecondsLimitReached() == true)
01027 osresult->setSolutionStatus(solIdx, "other", "time limit reached");
01028 else{
01029 if(model->isSolutionLimitReached() == true)
01030 osresult->setSolutionStatus(solIdx, "other", "solution limit reached");
01031 else{
01032 if(model->isAbandoned() == true)
01033 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
01034 else
01035 osresult->setSolutionStatus(solIdx, "other","unknown");
01036 }
01037 }
01038 }
01039 }
01040 }
01041 }
01042 }
01043
01044
01045 if(numOfIntVars > 0) *(z + 0) = model->getObjValue();
01046 osresult->setObjectiveValuesDense(solIdx, z);
01047 for(i=0; i < osinstance->getVariableNumber(); i++){
01048 *(x + i) = model->getColSolution()[i];
01049 *(idx + i) = i;
01050 }
01051 osresult->setPrimalVariableValuesDense(solIdx, x);
01052 for(i=0; i < osinstance->getConstraintNumber(); i++){
01053 *(y + i) = model->getRowPrice()[ i];
01054 }
01055 if(numOfIntVars <= 0) osresult->setDualVariableValuesDense(solIdx, y);
01056
01057
01058 if(numOfIntVars <= 0){
01059 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01060 for(i=0; i < numberOfVar; i++){
01061 rcost[ i] = os_dtoa_format( model->getReducedCost()[ i]);
01062 }
01063 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx, rcost, osinstance->getVariableNumber());
01064 }
01065
01066 osrl = osrlwriter->writeOSrL( osresult);
01067
01068 if(osinstance->getVariableNumber() > 0) delete[] x;
01069 x = NULL;
01070 if(osinstance->getConstraintNumber() > 0) delete[] y;
01071 y = NULL;
01072 delete[] z;
01073 z = NULL;
01074 if(osinstance->getVariableNumber() > 0){
01075 delete[] rcost;
01076 rcost = NULL;
01077 delete[] idx;
01078 idx = NULL;
01079 }
01080 }
01081
01082