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