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