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