00001
00019
00020
00021 #include "OSCoinSolver.h"
00022 #include "OSInstance.h"
00023 #include "OSFileUtil.h"
00024 #include "CoinTime.hpp"
00025 #include "CglPreProcess.hpp"
00026 #include "CglGomory.hpp"
00027 #include "CglSimpleRounding.hpp"
00028 #include "CglMixedIntegerRounding2.hpp"
00029 #include "CglKnapsackCover.hpp"
00030 #include "CglFlowCover.hpp"
00031 #include "CbcBranchActual.hpp"
00032 #include "CoinMessageHandler.hpp"
00033 #include "CoinMessage.hpp"
00034
00035 #include "OsiClpSolverInterface.hpp"
00036
00037 #ifdef COIN_HAS_SYMPHONY
00038 #include "OsiSymSolverInterface.hpp"
00039 #endif
00040
00041 #ifdef COIN_HAS_VOL
00042 #include "OsiVolSolverInterface.hpp"
00043 #endif
00044
00045 #ifdef COIN_HAS_DYLP
00046 #include "OsiDylpSolverInterface.hpp"
00047 #endif
00048
00049 #ifdef COIN_HAS_GLPK
00050 #include "OsiGlpkSolverInterface.hpp"
00051 #endif
00052
00053 #ifdef COIN_HAS_CPX
00054 #include "OsiCpxSolverInterface.hpp"
00055 #endif
00056
00057 #include "OSGeneral.h"
00058 #include "OSParameters.h"
00059 #include "OSMathUtil.h"
00060
00061 #include<map>
00062
00063 #include <iostream>
00064 #ifdef HAVE_CTIME
00065 # include <ctime>
00066 #else
00067 # ifdef HAVE_TIME_H
00068 # include <time.h>
00069 # else
00070 # error "don't have header file for time"
00071 # endif
00072 #endif
00073 using std::cout;
00074 using std::endl;
00075 using std::ostringstream;
00076
00077
00078
00079 CoinSolver::CoinSolver() :
00080 osiSolver(NULL),
00081 m_osilreader(NULL),
00082 m_osolreader(NULL),
00083 m_CoinPackedMatrix(NULL),
00084 cbc_argv( NULL),
00085 num_cbc_argv( 0),
00086 cpuTime( 0)
00087
00088 {
00089 osrlwriter = new OSrLWriter();
00090 }
00091
00092 CoinSolver::~CoinSolver()
00093 {
00094 #ifdef DEBUG
00095 cout << "inside CoinSolver destructor" << endl;
00096 #endif
00097 if(m_osilreader != NULL) delete m_osilreader;
00098 m_osilreader = NULL;
00099 if(m_osolreader != NULL) delete m_osolreader;
00100 m_osolreader = NULL;
00101 delete m_CoinPackedMatrix;
00102 m_CoinPackedMatrix = NULL;
00103 delete osiSolver;
00104 if(osiSolver != NULL) osiSolver = NULL;
00105 delete osrlwriter;
00106 osrlwriter = NULL;
00107 delete osresult;
00108 osresult = NULL;
00109 if(num_cbc_argv > 0)
00110 {
00111 int i;
00112 for(i = 0; i < num_cbc_argv; i++)
00113 {
00114
00115 }
00116
00117 cbc_argv = NULL;
00118 }
00119 #ifdef DEBUG
00120 cout << "leaving CoinSolver destructor" << endl;
00121 #endif
00122 }
00123
00124
00125 void CoinSolver::buildSolverInstance() throw (ErrorClass)
00126 {
00127 try
00128 {
00129
00130 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00131 clock_t start, finish;
00132 double duration;
00133 start = clock();
00134 if(osinstance == NULL)
00135 {
00136 m_osilreader = new OSiLReader();
00137 osinstance = m_osilreader->readOSiL( osil);
00138 }
00139 finish = clock();
00140 duration = (double) (finish - start) / CLOCKS_PER_SEC;
00141
00142 bool solverIsDefined = false;
00143 if( sSolverName.find("clp") != std::string::npos)
00144 {
00145 solverIsDefined = true;
00146 osiSolver = new OsiClpSolverInterface();
00147 }
00148 else
00149 {
00150 if( sSolverName.find("vol") != std::string::npos)
00151 {
00152 #ifdef COIN_HAS_VOL
00153 solverIsDefined = true;
00154 osiSolver = new OsiVolSolverInterface();
00155 #endif
00156 }
00157 else
00158 {
00159 if( sSolverName.find( "cplex") != std::string::npos)
00160 {
00161 #ifdef COIN_HAS_CPX
00162 solverIsDefined = true;
00163 osiSolver = new OsiCpxSolverInterface();
00164 #endif
00165 }
00166 else
00167 {
00168 if(sSolverName.find( "glpk") != std::string::npos)
00169 {
00170 #ifdef COIN_HAS_GLPK
00171 solverIsDefined = true;
00172 osiSolver = new OsiGlpkSolverInterface();
00173 #endif
00174 }
00175 else
00176 {
00177 if(sSolverName.find( "dylp") != std::string::npos)
00178 {
00179 #ifdef COIN_HAS_DYLP
00180 solverIsDefined = true;
00181 osiSolver = new OsiDylpSolverInterface();
00182 #endif
00183 }
00184 else
00185 {
00186 if( sSolverName.find( "symphony") != std::string::npos)
00187 {
00188 #ifdef COIN_HAS_SYMPHONY
00189 solverIsDefined = true;
00190 osiSolver = new OsiSymSolverInterface();
00191 #endif
00192 }
00193 else
00194 {
00195
00196
00197 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0 ||
00198 sSolverName.find( "cbc") != std::string::npos ) sSolverName = "cbc";
00199 else sSolverName = "clp";
00200 solverIsDefined = true;
00201 osiSolver = new OsiClpSolverInterface();
00202 }
00203 }
00204 }
00205 }
00206 }
00207 }
00208
00209 if(solverIsDefined == false) throw ErrorClass("a supported solver was not defined");
00210
00211
00212 if( (osinstance->getNumberOfNonlinearExpressions() > 0)
00213 || (osinstance->getNumberOfQuadraticTerms() > 0) )
00214 {
00215 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
00216 }
00217
00218 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00219 {
00220 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
00221 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
00222 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
00223
00224 }
00225
00226 if( osinstance->getNumberOfSemiIntegerVariables() + osinstance->getNumberOfSemiContinuousVariables() > 0)
00227 {
00228 throw ErrorClass( "Semi-integer and semi-continuous variables not supported");
00229
00230
00231
00232
00233 }
00234
00235
00236
00237 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver:" + sSolverName + " needs an objective function");
00238 if(osinstance->getNumberOfStringVariables() > 0) throw ErrorClass("Coin solver:" + sSolverName + " can only handle numeric variables");
00239 if(osinstance->getLinearConstraintCoefficientNumber() <= 0 && sSolverName == "symphony") throw ErrorClass("Coin solver:" + sSolverName + " needs a positive number of variables");
00240
00241 if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
00242 osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(),
00243 osinstance->getVariableUpperBounds(),
00244 osinstance->getDenseObjectiveCoefficients()[0],
00245 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
00246 );
00247
00248
00249 if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
00250 else osiSolver->setObjSense(-1.0);
00251
00252 int *intIndex = NULL;
00253 int i = 0;
00254 int k = 0;
00255 char *varType;
00256 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00257 if(numOfIntVars > 0)
00258 {
00259 intIndex = new int[ numOfIntVars];
00260 varType = osinstance->getVariableTypes();
00261 for(i = 0; i < osinstance->getVariableNumber(); i++)
00262 {
00263 if( (varType[i] == 'B') || (varType[i]) == 'I' )
00264 {
00265 intIndex[k++] = i;
00266 }
00267 }
00268 osiSolver->setInteger( intIndex, numOfIntVars);
00269 }
00270 if(numOfIntVars > 0)
00271 {
00272 delete[] intIndex;
00273 intIndex = NULL;
00274 }
00275 bCallbuildSolverInstance = true;
00276 }
00277 catch(const ErrorClass& eclass)
00278 {
00279 osresult = new OSResult();
00280 osresult->setGeneralMessage( eclass.errormsg);
00281 osresult->setGeneralStatusType( "error");
00282 osrl = osrlwriter->writeOSrL( osresult);
00283 throw ErrorClass( osrl) ;
00284 }
00285 }
00286
00287
00288
00289 void CoinSolver::setSolverOptions() throw (ErrorClass)
00290 {
00291
00292 #ifdef DEBUG
00293 std::cout << "build solver options" << std::endl;
00294 #endif
00295 this->bSetSolverOptions = true;
00296
00297
00298 std::map<std::string, OsiHintParam> hintParamMap;
00299 hintParamMap["OsiDoPresolveInInitial"] = OsiDoPresolveInInitial;
00300 hintParamMap["OsiDoDualInInitial"] = OsiDoDualInInitial;
00301 hintParamMap["OsiDoPresolveInResolve"] = OsiDoPresolveInResolve;
00302 hintParamMap["OsiDoDualInResolve"] = OsiDoDualInResolve;
00303 hintParamMap["OsiDoScale"] = OsiDoScale;
00304 hintParamMap["OsiDoCrash"] = OsiDoCrash;
00305 hintParamMap["OsiDoReducePrint"] = OsiDoReducePrint;
00306 hintParamMap["OsiDoInBranchAndCut"] = OsiDoInBranchAndCut;
00307 hintParamMap["OsiLastHintParam"] = OsiLastHintParam;
00308
00309
00310 std::map<std::string, OsiHintStrength> hintStrengthMap;
00311 hintStrengthMap["OsiHintIgnore"] = OsiHintIgnore;
00312 hintStrengthMap["OsiHintTry"] = OsiHintTry;
00313 hintStrengthMap["OsiHintDo"] = OsiHintDo;
00314 hintStrengthMap["OsiForceDo"] = OsiForceDo;
00315
00316
00317 std::map<std::string, OsiStrParam> strParamMap;
00318 strParamMap["OsiProbName"] = OsiProbName;
00319 strParamMap["OsiSolverName"] = OsiSolverName;
00320 strParamMap["OsiLastStrParam"] = OsiLastStrParam;
00321
00322
00323 std::map<std::string, OsiDblParam> dblParamMap;
00324 dblParamMap["OsiDualObjectiveLimit"] = OsiDualObjectiveLimit;
00325 dblParamMap["OsiPrimalObjectiveLimit"] = OsiPrimalObjectiveLimit;
00326 dblParamMap["OsiDualTolerance"] = OsiDualTolerance;
00327 dblParamMap["OsiPrimalTolerance"] = OsiPrimalTolerance;
00328 dblParamMap["OsiObjOffset"] = OsiObjOffset;
00329 dblParamMap["OsiLastDblParam"] = OsiLastDblParam;
00330
00331
00332
00333 std::map<std::string, OsiIntParam> intParamMap;
00334 intParamMap["OsiMaxNumIteration"] = OsiMaxNumIteration;
00335 intParamMap["OsiMaxNumIterationHotStart"] = OsiMaxNumIterationHotStart;
00336 intParamMap["OsiNameDiscipline"] = OsiNameDiscipline;
00337 intParamMap["OsiLastIntParam"] = OsiLastIntParam;
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 OsiHintStrength hintStrength = OsiHintTry;
00349 osiSolver->setHintParam(OsiDoReducePrint, true, hintStrength);
00350
00351
00352 osiSolver->setDblParam(OsiObjOffset, -osinstance->getObjectiveConstants()[0]);
00353
00354
00355
00356
00357 #ifdef COIN_HAS_SYMPHONY
00358 if( sSolverName.find( "symphony") != std::string::npos)
00359 {
00360 OsiSymSolverInterface * si =
00361 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00362
00363 si->setSymParam("verbosity", -2);
00364 }
00365 #endif //symphony end
00366
00367
00368
00369
00370
00371
00372 try
00373 {
00374 if(osoption == NULL && osol.length() > 0)
00375 {
00376 m_osolreader = new OSoLReader();
00377 osoption = m_osolreader->readOSoL( osol);
00378 }
00379
00380 if(osoption != NULL)
00381 {
00382
00383 #ifdef DEBUG
00384 std::cout << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
00385 #endif
00386 if( osoption->getNumberOfSolverOptions() <= 0) return;
00387
00388 std::vector<SolverOption*> optionsVector;
00389
00390 optionsVector = osoption->getSolverOptions( "osi",true);
00391 int num_osi_options = optionsVector.size();
00392 int i;
00393 char *pEnd;
00394 bool yesNo;
00395
00396 for(i = 0; i < num_osi_options; i++)
00397 {
00398 #ifdef DEBUG
00399 std::cout << "osi solver option " << optionsVector[ i]->name << std::endl;
00400 #endif
00401 if (optionsVector[ i]->type == "OsiHintStrength" )
00402 {
00403 if( hintStrengthMap.find( optionsVector[ i]->name ) != hintStrengthMap.end() )
00404 {
00405 hintStrength = hintStrengthMap[ optionsVector[ i]->name] ;
00406 }
00407 }
00408 }
00409 for(i = 0; i < num_osi_options; i++)
00410 {
00411 #ifdef DEBUG
00412 std::cout << "osi solver option " << optionsVector[ i]->name << std::endl;
00413 #endif
00414 if (optionsVector[ i]->type == "OsiHintParam" )
00415 {
00416
00417 if( optionsVector[ i]->value == "true" )
00418 {
00419 yesNo = true;
00420 }
00421 else
00422 {
00423 yesNo = false;
00424 }
00425 if( hintParamMap.find( optionsVector[ i]->name ) != hintParamMap.end() )
00426 {
00427
00428 osiSolver->setHintParam( hintParamMap[ optionsVector[ i]->name] , yesNo, hintStrength);
00429 }
00430
00431 }
00432 else if(optionsVector[ i]->type == "OsiStrParam" )
00433 {
00434
00435 if( strParamMap.find( optionsVector[ i]->name ) != strParamMap.end() )
00436 {
00437
00438 osiSolver->setStrParam( strParamMap[ optionsVector[ i]->name] , optionsVector[ i]->value);
00439 }
00440
00441 }
00442 else if(optionsVector[ i]->type == "OsiDblParam" )
00443 {
00444
00445 if( dblParamMap.find( optionsVector[ i]->name ) != dblParamMap.end() )
00446 {
00447
00448 osiSolver->setDblParam( dblParamMap[ optionsVector[ i]->name] , os_strtod( optionsVector[ i]->value.c_str(), &pEnd ));
00449 }
00450
00451 }
00452 else if(optionsVector[ i]->type == "OsiIntParam" )
00453 {
00454
00455
00456 if( intParamMap.find( optionsVector[ i]->name ) != intParamMap.end() )
00457 {
00458
00459 osiSolver->setIntParam( intParamMap[ optionsVector[ i]->name] , atoi( optionsVector[ i]->value.c_str() ) );
00460 }
00461
00462 }
00463 }
00464
00465
00466
00467 if( sSolverName.find( "cbc") != std::string::npos)
00468 {
00469
00470
00471
00472 if(optionsVector.size() > 0) optionsVector.clear();
00473 optionsVector = osoption->getSolverOptions( "cbc",true);
00474
00475
00476
00477
00478
00479
00480
00481
00482 int num_cbc_options = optionsVector.size();
00483 char *cstr;
00484 std::string cbc_option;
00485 num_cbc_argv = optionsVector.size() + 3;
00486 cbc_argv = new const char*[ num_cbc_argv];
00487
00488
00489 cbc_option = "OS";
00490 cstr = new char [cbc_option.size() + 1];
00491 strcpy (cstr, cbc_option.c_str());
00492 cbc_argv[ 0] = cstr;
00493
00494
00495 for(i = 0; i < num_cbc_options; i++)
00496 {
00497 #ifdef DEBUG
00498 std::cout << "cbc solver option " << optionsVector[ i]->name << std::endl;
00499 std::cout << "cbc solver value " << optionsVector[ i]->value << std::endl;
00500 #endif
00501
00502 if(optionsVector[ i]->value.length() > 0 )
00503 {
00504 cbc_option = "-" + optionsVector[ i]->name +"="+optionsVector[ i]->value;
00505 }
00506 else
00507 {
00508 cbc_option = "-" + optionsVector[ i]->name ;
00509 }
00510 cstr = new char [cbc_option.size() + 1];
00511 strcpy (cstr, cbc_option.c_str());
00512 cbc_argv[i + 1] = cstr;
00513
00514 }
00515
00516
00517 cbc_option = "-solve";
00518 cstr = new char [cbc_option.size() + 1];
00519 strcpy (cstr, cbc_option.c_str());
00520 cbc_argv[ num_cbc_argv - 2] = cstr;
00521
00522
00523 cbc_option = "-quit";
00524 cstr = new char [cbc_option.size() + 1];
00525 strcpy (cstr, cbc_option.c_str());
00526 cbc_argv[ num_cbc_argv - 1] = cstr;
00527
00528 }
00529
00530
00531
00532
00533 #ifdef COIN_HAS_SYMPHONY
00534 if(optionsVector.size() > 0) optionsVector.clear();
00535
00536
00537 if( sSolverName.find( "symphony") != std::string::npos)
00538 {
00539 OsiSymSolverInterface * si =
00540 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00541 optionsVector = osoption->getSolverOptions( "symphony",true);
00542 int num_sym_options = optionsVector.size();
00543 for(i = 0; i < num_sym_options; i++)
00544 {
00545 #ifdef DEBUG
00546 std::cout << "symphony solver option " << optionsVector[ i]->name << std::endl;
00547 std::cout << "symphony solver value " << optionsVector[ i]->value << std::endl;
00548 #endif
00549 si->setSymParam(optionsVector[ i]->name, optionsVector[ i]->value);
00550 }
00551 }
00552 #endif //symphony end
00553
00554
00555 int n,m,k;
00556 if (osoption != NULL)
00557 m = osoption->getNumberOfInitVarValues();
00558 else
00559 m = 0;
00560 #ifdef DEBUG
00561 cout << "number of variables initialed: " << m << endl;
00562 #endif
00563
00564 if (m > 0)
00565 {
00566 #ifdef DEBUG
00567 cout << "get initial values " << endl;
00568 #endif
00569 n = osinstance->getVariableNumber();
00570 double* denseInitVarVector;
00571 denseInitVarVector = new double[n];
00572 bool* initialed;
00573 initialed = new bool[n];
00574
00575 for(k = 0; k < n; k++)
00576 initialed[k] = false;
00577
00578 InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
00579 #ifdef DEBUG
00580 cout << "done " << endl;
00581 #endif
00582
00583 double initval;
00584 for(k = 0; k < m; k++)
00585 {
00586 i = initVarVector[k]->idx;
00587 if (initVarVector[k]->idx > n)
00588 throw ErrorClass ("Illegal index value in variable initialization");
00589
00590 initval = initVarVector[k]->value;
00591 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00592 {
00593 if (osinstance->instanceData->variables->var[k]->lb > initval)
00594 throw ErrorClass ("Initial value outside of bounds");
00595 }
00596 else if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00597 {
00598 if (osinstance->instanceData->variables->var[k]->ub < initval)
00599 throw ErrorClass ("Initial value outside of bounds");
00600 }
00601 else
00602 {
00603 if ((osinstance->instanceData->variables->var[k]->lb > initval) ||
00604 (osinstance->instanceData->variables->var[k]->ub < initval))
00605 throw ErrorClass ("Initial value outside of bounds");
00606 }
00607
00608 denseInitVarVector[initVarVector[k]->idx] = initval;
00609 initialed[initVarVector[k]->idx] = true;
00610 }
00611
00612 double default_initval;
00613 default_initval = 0.0;
00614
00615 for(k = 0; k < n; k++)
00616 {
00617 if (!initialed[k])
00618 if (osinstance->instanceData->variables->var[k]->ub == OSDBL_MAX)
00619 if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
00620 denseInitVarVector[k] = default_initval;
00621 else
00622 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00623 else if (osinstance->instanceData->variables->var[k]->lb == -OSDBL_MAX)
00624 if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
00625 denseInitVarVector[k] = default_initval;
00626 else
00627 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00628 else if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
00629 (osinstance->instanceData->variables->var[k]->ub >= default_initval))
00630 denseInitVarVector[k] = default_initval;
00631 else if (osinstance->instanceData->variables->var[k]->lb > default_initval)
00632 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00633 else
00634 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->ub;
00635 denseInitVarVector[k] = default_initval;
00636 denseInitVarVector[k] = osinstance->instanceData->variables->var[k]->lb;
00637 }
00638 #ifdef DEBUG
00639 cout << "set initial values: " << endl;
00640 for (k=0; k < n; k++)
00641 cout << " " << k << ": " << denseInitVarVector[k] << endl;
00642 #endif
00643 osiSolver->setColSolution( denseInitVarVector);
00644 delete[] denseInitVarVector;
00645 delete[] initialed;
00646 #ifdef DEBUG
00647 cout << "done " << endl;
00648 #endif
00649
00650 }
00651 }
00652
00653 #ifdef DEBUG
00654 std::cout << "solver options set" << std::endl;
00655 #endif
00656 }
00657 catch(const ErrorClass& eclass)
00658 {
00659 std::cout << "THERE IS AN ERROR" << std::endl;
00660 osresult = new OSResult();
00661 osresult->setGeneralMessage( eclass.errormsg);
00662 osresult->setGeneralStatusType( "error");
00663 osrl = osrlwriter->writeOSrL( osresult);
00664 throw ErrorClass( osrl) ;
00665 }
00666 }
00667
00668
00669 bool CoinSolver::setCoinPackedMatrix()
00670 {
00671 bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
00672 try
00673 {
00674 double maxGap = 0;
00675 if(osinstance->getVariableNumber() > 0)
00676 {
00677 m_CoinPackedMatrix = new CoinPackedMatrix(
00678 columnMajor,
00679 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00680 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00681 osinstance->getLinearConstraintCoefficientNumber(),
00682 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values,
00683 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes,
00684 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts,
00685 0, 0, maxGap );
00686 }
00687 else
00688 {
00689 int start = 0;
00690 m_CoinPackedMatrix = new CoinPackedMatrix(
00691 columnMajor,
00692 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00693 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00694 osinstance->getLinearConstraintCoefficientNumber(),
00695 NULL,
00696 NULL,
00697 &start,
00698 NULL, 0.0, maxGap );
00699 }
00700
00701
00702 return true;
00703 }
00704 catch(const ErrorClass& eclass)
00705 {
00706 osresult = new OSResult();
00707 osresult->setGeneralMessage( eclass.errormsg);
00708 osresult->setGeneralStatusType( "error");
00709 osrl = osrlwriter->writeOSrL( osresult);
00710 throw ErrorClass( osrl) ;
00711 }
00712 }
00713
00714 void CoinSolver::solve() throw (ErrorClass)
00715 {
00716 if(osresult != NULL) delete osresult;
00717 osresult = new OSResult();
00718 try
00719 {
00720
00721 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00722
00723 if( this->bSetSolverOptions == false) setSolverOptions();
00724 }
00725 catch(const ErrorClass& eclass)
00726 {
00727 throw ErrorClass( osrl) ;
00728 }
00729
00730
00731 if(osresult->setSolverInvoked("COIN-OR " + sSolverName) != true)
00732 throw ErrorClass("OSResult error: SetSolverInvoked");
00733 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00734 throw ErrorClass("OSResult error: setInstanceName");
00735
00736
00737
00738
00739
00740
00741 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00742 throw ErrorClass("OSResult error: setVariableNumer");
00743 if(osresult->setObjectiveNumber( 1) != true)
00744 throw ErrorClass("OSResult error: setObjectiveNumber");
00745 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00746 throw ErrorClass("OSResult error: setConstraintNumber");
00747 if(osresult->setSolutionNumber( 1) != true)
00748 throw ErrorClass("OSResult error: setSolutionNumer");
00749
00750
00751 try
00752 {
00753 double start = CoinCpuTime();
00754 try
00755 {
00756 if( sSolverName.find( "cbc") != std::string::npos)
00757 {
00758
00759
00760 CbcModel model( *osiSolver);
00761
00762
00763
00764
00765
00766
00767
00768 CbcMain0( model);
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 if(num_cbc_argv <= 0)
00788 {
00789 char *cstr;
00790 std::string cbc_option;
00791 num_cbc_argv = 4;
00792 cbc_argv = new const char*[ num_cbc_argv];
00793
00794
00795 cbc_option = "OS";
00796 cstr = new char [cbc_option.size() + 1];
00797 strcpy (cstr, cbc_option.c_str());
00798 cbc_argv[ 0] = cstr;
00799
00800
00801
00802 cbc_option = "-log=0";
00803 cstr = new char [cbc_option.size() + 1];
00804 strcpy (cstr, cbc_option.c_str());
00805 cbc_argv[ 1] = cstr;
00806
00807
00808
00809 cbc_option = "-solve";
00810 cstr = new char [cbc_option.size() + 1];
00811 strcpy (cstr, cbc_option.c_str());
00812 cbc_argv[ 2] = cstr;
00813
00814
00815 cbc_option = "-quit";
00816 cstr = new char [cbc_option.size() + 1];
00817 strcpy (cstr, cbc_option.c_str());
00818 cbc_argv[ 3] = cstr;
00819
00820 }
00821 int i;
00822
00823
00824 std::cout << "CALLING THE CBC SOLVER CBCMAIN1()" << std::endl;
00825 for(i = 0; i < num_cbc_argv; i++)
00826 {
00827 std::cout << "Cbc Option: " << cbc_argv[ i] << std::endl;
00828 }
00829
00830
00831 CbcMain1( num_cbc_argv, cbc_argv, model);
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 for(i = 0; i < num_cbc_argv; i++)
00851 {
00852 delete[] cbc_argv[ i];
00853 cbc_argv[i] = NULL;
00854 }
00855 if( num_cbc_argv > 0)
00856 {
00857 delete[] cbc_argv;
00858 cbc_argv = NULL;
00859 num_cbc_argv = 0;
00860 }
00861
00862
00863
00864 cpuTime = CoinCpuTime() - start;
00865
00866
00867 OsiSolverInterface *solver = model.solver();
00868 if(osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00869 {
00870 writeResult( &model);
00871 }
00872 else
00873 {
00874 writeResult( solver);
00875 }
00876 }
00877 else
00878 {
00879
00880 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00881 {
00882 osiSolver->branchAndBound();
00883 }
00884 else
00885 {
00886 osiSolver->initialSolve();
00887 }
00888 cpuTime = CoinCpuTime() - start;
00889
00890 writeResult( osiSolver);
00891 }
00892
00893
00894 }
00895 catch(CoinError e)
00896 {
00897 std::string errmsg;
00898 errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "
00899 + e.methodName() + " in class " + e.className();
00900 throw ErrorClass( errmsg );
00901 }
00902
00903 }
00904 catch(const ErrorClass& eclass)
00905 {
00906 osresult->setGeneralMessage( eclass.errormsg);
00907 osresult->setGeneralStatusType( "error");
00908 osrl = osrlwriter->writeOSrL( osresult);
00909 throw ErrorClass( osrl) ;
00910 }
00911 }
00912
00913 std::string CoinSolver::getCoinSolverType(std::string lcl_osol)
00914 {
00915
00916 try
00917 {
00918 if( lcl_osol.find( "clp") != std::string::npos)
00919 {
00920 return "coin_solver_glpk";
00921 }
00922 else
00923 {
00924 if( lcl_osol.find( "cbc") != std::string::npos)
00925 {
00926 return "coin_solver_cpx";
00927 }
00928 else
00929 {
00930 if( lcl_osol.find( "cpx") != std::string::npos)
00931 {
00932 return "coin_solver_clp";
00933 }
00934 else
00935 {
00936 if(lcl_osol.find( "glpk") != std::string::npos)
00937 {
00938 return "";
00939 }
00940 else throw ErrorClass("a supported solver was not defined");
00941 }
00942 }
00943 }
00944 }
00945 catch(const ErrorClass& eclass)
00946 {
00947 osresult->setGeneralMessage( eclass.errormsg);
00948 osresult->setGeneralStatusType( "error");
00949 osrl = osrlwriter->writeOSrL( osresult);
00950 throw ErrorClass( osrl) ;
00951 }
00952 }
00953
00954 void CoinSolver::dataEchoCheck()
00955 {
00956 int i;
00957
00958 cout << "This is problem: " << osinstance->getInstanceName() << endl;
00959 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
00960 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
00961 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00962 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00963
00964
00965 if(osinstance->getVariableNumber() > 0)
00966 {
00967 for(i = 0; i < osinstance->getVariableNumber(); i++)
00968 {
00969 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
00970 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
00971 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
00972 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
00973 }
00974 }
00975
00976
00977 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0)
00978 {
00979 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
00980 else cout << "problem is a maximization" << endl;
00981 for(i = 0; i < osinstance->getVariableNumber(); i++)
00982 {
00983 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00984 }
00985 }
00986
00987 if(osinstance->getConstraintNumber() > 0)
00988 {
00989 for(i = 0; i < osinstance->getConstraintNumber(); i++)
00990 {
00991 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
00992 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
00993 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
00994 }
00995 }
00996
00997
00998 if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
00999 }
01000
01001
01002
01003 void CoinSolver::writeResult(OsiSolverInterface *solver)
01004 {
01005
01006 double *x = NULL;
01007 double *y = NULL;
01008 double *z = NULL;
01009 int *cbasis = NULL;
01010 int *rbasis = NULL;
01011 int *idx = NULL;
01012 int kount;
01013
01014
01015
01016 std::vector<int> freeVars;
01017 std::vector<int> basicVars;
01018 std::vector<int> nonBasicLower;
01019 std::vector<int> nonBasicUpper;
01020 std::vector<int>::iterator vit;
01021 int **basisIdx;
01022 basisIdx = new int*[ 4];
01023
01024
01025 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
01026 std::string *rcost = NULL;
01027 if( solver->getNumCols() > 0 ) x = new double[solver->getNumCols() ];
01028
01029
01030
01031
01032 if( (solver->getNumCols() > 0) && (sSolverName.find( "vol") == std::string::npos)
01033 && (sSolverName.find( "symphony") == std::string::npos) &&
01034 (sSolverName.find( "dylp") == std::string::npos) &&
01035 (sSolverName.find( "glpk") == std::string::npos) )
01036 cbasis = new int[solver->getNumCols() ];
01037
01038 if( (osinstance->getConstraintNumber() > 0) && (sSolverName.find( "vol") == std::string::npos)
01039 && (sSolverName.find( "symphony") == std::string::npos) &&
01040 (sSolverName.find( "dylp") == std::string::npos) &&
01041 (sSolverName.find( "glpk") == std::string::npos) )
01042 rbasis = new int[solver->getNumRows() ];
01043
01044
01045 if( solver->getNumRows() > 0 ) y = new double[solver->getNumRows() ];
01046 if( solver->getNumCols() > 0 ) idx = new int[ solver->getNumCols() ];
01047 z = new double[1];
01048 if( solver->getNumCols() > 0 ) rcost = new std::string[ solver->getNumCols()];
01049 int numberOfVar = solver->getNumCols();
01050 int numberOfCon = solver->getNumRows();
01051 int solIdx = 0;
01052 int i = 0;
01053 int numberOfOtherVariableResults = 1;
01054 int otherIdx = 0;
01055 std::string description = "";
01056
01057 try
01058 {
01059
01060 osresult->setGeneralStatusType("normal");
01061 osresult->setTime(cpuTime);
01062 osresult->setServiceName( OSgetVersionInfo() );
01063 osresult->setSolverInvoked( "COIN-OR " + sSolverName );
01064 if (solver->isProvenOptimal() == true)
01065 {
01066 osresult->setSolutionStatus(solIdx, "optimal", description);
01067 if( (sSolverName.find( "vol") == std::string::npos) &&
01068 (sSolverName.find( "symphony") == std::string::npos) &&
01069 (sSolverName.find( "dylp") == std::string::npos) &&
01070 (sSolverName.find( "glpk") == std::string::npos) )
01071 {
01072 solver->getBasisStatus( cbasis, rbasis);
01073 }
01074
01075 }
01076 else
01077 {
01078 if(solver->isProvenPrimalInfeasible() == true)
01079 osresult->setSolutionStatus(solIdx, "infeasible", "the problem is primal infeasible");
01080 else
01081 {
01082 if(solver->isProvenDualInfeasible() == true)
01083 osresult->setSolutionStatus(solIdx, "unbounded", "the problem is unbounded");
01084 else
01085 {
01086 if(solver->isPrimalObjectiveLimitReached() == true)
01087 {
01088 osresult->setSolutionStatus(solIdx, "other", "primal objective limit reached");
01089 if( (sSolverName.find( "vol") == std::string::npos) &&
01090 (sSolverName.find( "symphony") == std::string::npos) &&
01091 (sSolverName.find( "dylp") == std::string::npos) &&
01092 (sSolverName.find( "glpk") == std::string::npos) )
01093 {
01094 solver->getBasisStatus( cbasis, rbasis);
01095 }
01096 }
01097 else
01098 {
01099 if(solver->isDualObjectiveLimitReached() == true)
01100 {
01101 osresult->setSolutionStatus(solIdx, "other", "dual objective limit reached");
01102 if( (sSolverName.find( "vol") == std::string::npos) &&
01103 (sSolverName.find( "symphony") == std::string::npos) &&
01104 (sSolverName.find( "dylp") == std::string::npos) &&
01105 (sSolverName.find( "glpk") == std::string::npos) )
01106 {
01107 solver->getBasisStatus( cbasis, rbasis);
01108 }
01109 }
01110 else
01111 {
01112 if(solver->isIterationLimitReached() == true)
01113 {
01114 osresult->setSolutionStatus(solIdx, "other", "iteration limit reached");
01115 if( (sSolverName.find( "vol") == std::string::npos) &&
01116 (sSolverName.find( "symphony") == std::string::npos) &&
01117 (sSolverName.find( "dylp") == std::string::npos) &&
01118 (sSolverName.find( "glpk") == std::string::npos) )
01119 {
01120 solver->getBasisStatus( cbasis, rbasis);
01121 }
01122 }
01123 else
01124 {
01125 if(solver->isAbandoned() == true)
01126 osresult->setSolutionStatus(solIdx, "other", "there are numerical difficulties");
01127 if( solver->getNumCols() == 0) osresult->setSolutionMessage(solIdx, "Warning: this problem has zero decision variables!");
01128 else
01129 osresult->setSolutionStatus(solIdx, "other", description);
01130 }
01131 }
01132 }
01133 }
01134 }
01135 }
01136
01137
01138
01139
01140
01141 *(z + 0) = solver->getObjValue();
01142
01143 osresult->setObjectiveValuesDense(solIdx, z);
01144
01145
01146
01147 for(i=0; i < numberOfVar; i++)
01148 {
01149
01150 *(x + i) = solver->getColSolution()[i];
01151 *(idx + i) = i;
01152
01153
01154 if(cbasis != NULL)
01155 {
01156
01157
01158 switch (cbasis[ i] )
01159 {
01160 case 0:
01161 {
01162
01163 freeVars.push_back( i);
01164 break;
01165 }
01166
01167 case 1:
01168 {
01169
01170 basicVars.push_back( i);
01171 break;
01172 }
01173
01174 case 2:
01175 {
01176
01177 nonBasicUpper.push_back( i );
01178 break;
01179 }
01180
01181 case 3:
01182 {
01183
01184 nonBasicLower.push_back( i) ;
01185 break;
01186 }
01187 default:
01188 throw ErrorClass("unknown result from Osi getBasisStatus when getting variable basis status");
01189
01190 }
01191
01192 }
01193
01194 }
01195
01196
01197 if(freeVars.size() > 0)
01198 {
01199
01200 kount = 0;
01201
01202 basisIdx[ 0] = new int[ freeVars.size()];
01203
01204 for(vit = freeVars.begin(); vit < freeVars.end(); vit++)
01205 {
01206
01207 basisIdx[0][ kount++] = *vit;
01208
01209
01210 }
01211
01212 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_isFree, basisIdx[ 0], kount);
01213 delete[] basisIdx[ 0];
01214 freeVars.clear();
01215
01216 }
01217
01218
01219
01220 if(basicVars.size() > 0)
01221 {
01222
01223 kount = 0;
01224
01225 basisIdx[ 1] = new int[ basicVars.size()];
01226
01227 for(vit = basicVars.begin(); vit < basicVars.end(); vit++)
01228 {
01229
01230 basisIdx[1][ kount++] = *vit;
01231
01232
01233 }
01234
01235 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_basic, basisIdx[ 1], kount);
01236 delete[] basisIdx[ 1];
01237 basicVars.clear();
01238
01239 }
01240
01241
01242
01243 if(nonBasicUpper.size() > 0)
01244 {
01245
01246 kount = 0;
01247
01248 basisIdx[ 2] = new int[ nonBasicUpper.size()];
01249
01250 for(vit = nonBasicUpper.begin(); vit < nonBasicUpper.end(); vit++)
01251 {
01252
01253 basisIdx[2][ kount++] = *vit;
01254
01255
01256 }
01257
01258 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atUpper, basisIdx[ 2], kount);
01259 delete[] basisIdx[ 2];
01260 nonBasicUpper.clear();
01261
01262 }
01263
01264
01265 if(nonBasicLower.size() > 0)
01266 {
01267
01268 kount = 0;
01269
01270 basisIdx[ 3] = new int[ nonBasicLower.size()];
01271
01272 for(vit = nonBasicLower.begin(); vit < nonBasicLower.end(); vit++)
01273 {
01274
01275 basisIdx[3][ kount++] = *vit;
01276
01277
01278 }
01279
01280 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_variables, ENUM_BASIS_STATUS_atLower, basisIdx[ 3], kount);
01281 delete[] basisIdx[ 3];
01282 nonBasicLower.clear();
01283
01284 }
01285
01286
01287 osresult->setPrimalVariableValuesDense(solIdx, x);
01288
01289 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0)
01290 {
01291
01292
01293
01294
01295
01296 for(i = 0; i < numberOfCon; i++)
01297 {
01298
01299 *(y + i) = solver->getRowPrice()[ i];
01300
01301
01302
01303
01304 if(rbasis != NULL)
01305 {
01306 switch (rbasis[ i] )
01307 {
01308 case 0:
01309 {
01310
01311 freeVars.push_back( i);
01312 break;
01313 }
01314
01315 case 1:
01316
01317 {
01318
01319 basicVars.push_back( i);
01320 break;
01321 }
01322
01323 case 2:
01324 {
01325
01326 nonBasicUpper.push_back( i );
01327 break;
01328 }
01329
01330 case 3:
01331 {
01332
01333 nonBasicLower.push_back( i) ;
01334 break;
01335 }
01336 default:
01337 throw ErrorClass("unknown result from Osi getBasisStatus when getting row basis status");
01338
01339 }
01340
01341 }
01342
01343
01344 }
01345
01346 osresult->setDualVariableValuesDense(solIdx, y);
01347
01348
01349
01350
01351
01352 if(freeVars.size() > 0)
01353 {
01354
01355 kount = 0;
01356
01357 basisIdx[ 0] = new int[ freeVars.size()];
01358
01359 for(vit = freeVars.begin(); vit < freeVars.end(); vit++)
01360 {
01361
01362 basisIdx[0][ kount++] = *vit;
01363
01364
01365 }
01366
01367 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_isFree, basisIdx[ 0], kount);
01368 delete[] basisIdx[ 0];
01369 freeVars.clear();
01370
01371 }
01372
01373
01374
01375 if(basicVars.size() > 0)
01376 {
01377
01378 kount = 0;
01379
01380 basisIdx[ 1] = new int[ basicVars.size()];
01381
01382 for(vit = basicVars.begin(); vit < basicVars.end(); vit++)
01383 {
01384
01385 basisIdx[1][ kount++] = *vit;
01386
01387
01388 }
01389
01390 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_basic, basisIdx[ 1], kount);
01391 delete[] basisIdx[ 1];
01392 basicVars.clear();
01393
01394 }
01395
01396
01397
01398 if(nonBasicUpper.size() > 0)
01399 {
01400
01401 kount = 0;
01402
01403 basisIdx[ 2] = new int[ nonBasicUpper.size()];
01404
01405 for(vit = nonBasicUpper.begin(); vit < nonBasicUpper.end(); vit++)
01406 {
01407
01408 basisIdx[2][ kount++] = *vit;
01409
01410
01411 }
01412
01413 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atUpper, basisIdx[ 2], kount);
01414 delete[] basisIdx[ 2];
01415 nonBasicUpper.clear();
01416
01417 }
01418
01419
01420 if(nonBasicLower.size() > 0)
01421 {
01422
01423 kount = 0;
01424
01425 basisIdx[ 3] = new int[ nonBasicLower.size()];
01426
01427 for(vit = nonBasicLower.begin(); vit < nonBasicLower.end(); vit++)
01428 {
01429
01430 basisIdx[3][ kount++] = *vit;
01431
01432
01433 }
01434
01435 osresult->setBasisStatus(0, ENUM_PROBLEM_COMPONENT_constraints, ENUM_BASIS_STATUS_atLower, basisIdx[ 3], kount);
01436 delete[] basisIdx[ 3];
01437 nonBasicLower.clear();
01438
01439 }
01440
01441
01442
01443 }
01444
01445
01446
01447
01448 if( sSolverName.find( "symphony") == std::string::npos && osinstance->getNumberOfIntegerVariables() == 0 && osinstance->getNumberOfBinaryVariables() == 0)
01449 {
01450
01451 if(numOfIntVars <= 0)
01452 {
01453 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01454 for(i=0; i < numberOfVar; i++)
01455 {
01456 rcost[ i] = os_dtoa_format( solver->getReducedCost()[ i]);
01457 }
01458 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx, rcost, solver->getNumCols());
01459
01460 }
01461 }
01462
01463
01464 osrl = osrlwriter->writeOSrL( osresult);
01465
01466
01467 if(solver->getNumRows() > 0)
01468 {
01469
01470 delete[] y;
01471 y = NULL;
01472 if( (sSolverName.find( "vol") == std::string::npos) &&
01473 (sSolverName.find( "symphony") == std::string::npos) &&
01474 (sSolverName.find( "glpk") == std::string::npos) ) delete[] rbasis;
01475 rbasis = NULL;
01476
01477
01478
01479 }
01480
01481 delete[] z;
01482 z = NULL;
01483
01484 delete[] basisIdx;
01485 basisIdx = NULL;
01486
01487 if(solver->getNumCols() > 0)
01488 {
01489
01490 if( (sSolverName.find( "vol") == std::string::npos) &&
01491 (sSolverName.find( "symphony") == std::string::npos) &&
01492 (sSolverName.find( "glpk") == std::string::npos) ) delete[] cbasis;
01493 cbasis = NULL;
01494
01495 delete[] x;
01496 x = NULL;
01497 delete[] rcost;
01498 rcost = NULL;
01499 delete[] idx;
01500 idx = NULL;
01501 }
01502
01503 }
01504
01505 catch(const ErrorClass& eclass)
01506 {
01507
01508
01509 if(solver->getNumRows() > 0)
01510 {
01511
01512 delete[] y;
01513 y = NULL;
01514 if( (sSolverName.find( "vol") == std::string::npos) &&
01515 (sSolverName.find( "symphony") == std::string::npos) &&
01516 (sSolverName.find( "glpk") == std::string::npos) ) delete[] rbasis;
01517 rbasis = NULL;
01518
01519
01520
01521 }
01522
01523 delete[] z;
01524 z = NULL;
01525
01526 if(solver->getNumCols() > 0)
01527 {
01528 if( (sSolverName.find( "vol") == std::string::npos) &&
01529 (sSolverName.find( "symphony") == std::string::npos) &&
01530 (sSolverName.find( "glpk") == std::string::npos) ) delete[] cbasis;
01531 cbasis = NULL;
01532
01533 delete[] x;
01534 x = NULL;
01535 delete[] rcost;
01536 rcost = NULL;
01537 delete[] idx;
01538 idx = NULL;
01539 }
01540
01541 osresult->setGeneralMessage( eclass.errormsg);
01542 osresult->setGeneralStatusType( "error");
01543 osrl = osrlwriter->writeOSrL( osresult);
01544 throw ErrorClass( osrl) ;
01545 }
01546 }
01547
01548
01549 void CoinSolver::writeResult(CbcModel *model)
01550 {
01551 double *x = NULL;
01552 double *y = NULL;
01553 double *z = NULL;
01554 int *idx = NULL;
01555 std::string *rcost = NULL;
01556
01557 if( model->getNumCols() > 0 ) x = new double[model->getNumCols() ];
01558 if( model->getNumRows() > 0 ) y = new double[model->getNumRows() ];
01559 if( model->getNumCols() > 0 ) idx = new int[ model->getNumCols() ];
01560 z = new double[1];
01561 if( model->getNumCols() > 0 ) rcost = new std::string[ model->getNumCols()];
01562
01563 int numberOfOtherVariableResults = 1;
01564 int otherIdx = 0;
01565 int numberOfVar = model->getNumCols();
01566 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
01567 int i = 0;
01568 int solIdx = 0;
01569 std::string description = "";
01570 osresult->setGeneralStatusType("normal");
01571 osresult->setTime(cpuTime);
01572 osresult->setServiceName( OSgetVersionInfo() );
01573
01574
01575 int numberIntegerInfeasibilities = 0;
01576 int numberObjectInfeasibilities = 0;
01577 bool isFeasible = false;
01578 isFeasible = model->feasibleSolution( numberIntegerInfeasibilities,
01579 numberObjectInfeasibilities);
01580 std::string statusMsg;
01581 if(isFeasible == true)
01582 {
01583 statusMsg = "feasible";
01584 }
01585 else
01586 {
01587 statusMsg = "infeasible";
01588 }
01589
01590
01591 if (model->isProvenOptimal() == true )
01592 {
01593 osresult->setSolutionStatus(solIdx, "optimal", description);
01594 }
01595 else
01596 {
01597 if(model->isProvenInfeasible() == true)
01598 osresult->setSolutionStatus(solIdx, "infeasible", "the integer program is infeasible");
01599 else
01600 {
01601 if(model->isProvenDualInfeasible() == true)
01602 osresult->setSolutionStatus(solIdx, "infeasible", "the continuous relaxation is dual infeasible");
01603 else
01604 {
01605 if(model->isContinuousUnbounded() == true)
01606 osresult->setSolutionStatus(solIdx, statusMsg, "the continuous relaxation is unbounded");
01607 else
01608 {
01609 if(model->isNodeLimitReached() == true)
01610 osresult->setSolutionStatus(solIdx, statusMsg, "node limit reached");
01611 else
01612 {
01613 if(model->isSecondsLimitReached() == true)
01614 osresult->setSolutionStatus(solIdx, statusMsg, "time limit reached");
01615 else
01616 {
01617 if(model->isSolutionLimitReached() == true)
01618 osresult->setSolutionStatus(solIdx, statusMsg, "solution limit reached");
01619 else
01620 {
01621 if(model->isAbandoned() == true)
01622 osresult->setSolutionStatus(solIdx, statusMsg, "there are numerical difficulties");
01623 else
01624 osresult->setSolutionStatus(solIdx, statusMsg,"unknown");
01625 }
01626 }
01627 }
01628 }
01629 }
01630 }
01631 }
01632
01633
01634 if(numOfIntVars > 0) *(z + 0) = model->getObjValue();
01635 osresult->setObjectiveValuesDense(solIdx, z);
01636 for(i=0; i < model->getNumCols(); i++)
01637 {
01638 *(x + i) = model->getColSolution()[i];
01639 *(idx + i) = i;
01640 }
01641 osresult->setPrimalVariableValuesDense(solIdx, x);
01642 for(i=0; i < model->getNumRows(); i++)
01643 {
01644 *(y + i) = model->getRowPrice()[ i];
01645 }
01646 if(numOfIntVars <= 0) osresult->setDualVariableValuesDense(solIdx, y);
01647
01648
01649 if(numOfIntVars <= 0)
01650 {
01651 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResults);
01652 for(i=0; i < numberOfVar; i++)
01653 {
01654 rcost[ i] = os_dtoa_format( model->getReducedCost()[ i]);
01655 }
01656 osresult->setAnOtherVariableResultSparse(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", idx, rcost, model->getNumCols());
01657 }
01658
01659 osrl = osrlwriter->writeOSrL( osresult);
01660
01661 if(model->getNumCols() > 0) delete[] x;
01662 x = NULL;
01663 if(model->getNumRows() > 0) delete[] y;
01664 y = NULL;
01665 delete[] z;
01666 z = NULL;
01667 if(model->getNumCols() > 0)
01668 {
01669 delete[] rcost;
01670 rcost = NULL;
01671 delete[] idx;
01672 idx = NULL;
01673 }
01674 }
01675
01676