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