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