00001
00020 #define DEBUG
00021
00022 #include "OSCoinSolver.h"
00023 #include "OSInstance.h"
00024 #include "OSFileUtil.h"
00025 #include "CglPreProcess.hpp"
00026
00027 #include <iostream>
00028 #ifdef HAVE_CTIME
00029 # include <ctime>
00030 #else
00031 # ifdef HAVE_TIME_H
00032 # include <time.h>
00033 # else
00034 # error "don't have header file for time"
00035 # endif
00036 #endif
00037 using std::cout;
00038 using std::endl;
00039 using std::ostringstream;
00040
00041
00042 CoinSolver::CoinSolver() :
00043 osiSolver(NULL),
00044 m_osilreader(NULL),
00045 m_CoinPackedMatrix(NULL)
00046 {
00047 osrlwriter = new OSrLWriter();
00048 }
00049
00050 CoinSolver::~CoinSolver() {
00051 #ifdef DEBUG
00052 cout << "inside CoinSolver destructor" << endl;
00053 #endif
00054 cout << "inside CoinSolver destructor" << endl;
00055 if(m_osilreader != NULL) delete m_osilreader;
00056 m_osilreader = NULL;
00057 delete m_CoinPackedMatrix;
00058 m_CoinPackedMatrix = NULL;
00059 delete osiSolver;
00060 if(osiSolver != NULL) osiSolver = NULL;
00061 delete osrlwriter;
00062 osrlwriter = NULL;
00063 delete osresult;
00064 osresult = NULL;
00065 cout << "leaving CoinSolver destructor" << endl;
00066 }
00067
00068
00069 void CoinSolver::buildSolverInstance() throw (ErrorClass) {
00070 try{
00071 osresult = new OSResult();
00072 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00073 clock_t start, finish;
00074 double duration;
00075 start = clock();
00076 if(osinstance == NULL){
00077 m_osilreader = new OSiLReader();
00078 osinstance = m_osilreader->readOSiL( osil);
00079 }
00080 finish = clock();
00081 duration = (double) (finish - start) / CLOCKS_PER_SEC;
00082 cout << "Parsing took (seconds): "<< duration << endl;
00083 cout << "Start Solve with a Coin Solver" << endl;
00084
00085 bool solverIsDefined = false;
00086 std::cout << "SOLVER NAME = " << sSolverName << std::endl;
00087 if( sSolverName.find("clp") != std::string::npos){
00088 solverIsDefined = true;
00089 osiSolver = new OsiClpSolverInterface();
00090 }
00091 else{
00092 if( sSolverName.find("vol") != std::string::npos){
00093 #ifdef COIN_HAS_VOL
00094 solverIsDefined = true;
00095 osiSolver = new OsiVolSolverInterface();
00096 #endif
00097 }
00098 else{
00099 if( sSolverName.find( "cplex") != std::string::npos){
00100 #ifdef COIN_HAS_CPX
00101 solverIsDefined = true;
00102 osiSolver = new OsiCpxSolverInterface();
00103 #endif
00104 }
00105 else{
00106 if(sSolverName.find( "glpk") != std::string::npos){
00107 #ifdef COIN_HAS_GLPK
00108 solverIsDefined = true;
00109 osiSolver = new OsiGlpkSolverInterface();
00110 #endif
00111 }
00112 else{
00113 if(sSolverName.find( "dylp") != std::string::npos){
00114 #ifdef COIN_HAS_DYLP
00115 solverIsDefined = true;
00116 osiSolver = new OsiDylpSolverInterface();
00117 #endif
00118 }
00119 else{
00120 if( sSolverName.find( "symphony") != std::string::npos) {
00121 #ifdef COIN_HAS_SYMPHONY
00122 solverIsDefined = true;
00123 osiSolver = new OsiSymSolverInterface();
00124 #endif
00125 }
00126 else{
00127
00128 solverIsDefined = true;
00129 osiSolver = new OsiCbcSolverInterface();
00130 }
00131 }
00132 }
00133 }
00134 }
00135 }
00136
00137
00138 if(solverIsDefined == false) throw ErrorClass("a supported solver was not defined");
00139 if(osinstance->getConstraintNumber() <= 0)throw ErrorClass("Coin solver Needs Constraints");
00140 if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Coin solver requires decision variables");
00141 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Coin solver needs an objective function");
00142 if(osinstance->getLinearConstraintCoefficientNumber() <= 0) throw ErrorClass("Coin solver needs linear constraints");
00143 if(!setCoinPackedMatrix() ) throw ErrorClass("Problem generating coin packed matrix");
00144 osiSolver->loadProblem(*m_CoinPackedMatrix, osinstance->getVariableLowerBounds(),
00145 osinstance->getVariableUpperBounds(),
00146 osinstance->getDenseObjectiveCoefficients()[0],
00147 osinstance->getConstraintLowerBounds(), osinstance->getConstraintUpperBounds()
00148 );
00149
00150 if(osinstance->getObjectiveNumber() == 0) throw ErrorClass("there is no objective function");
00151 if( osinstance->getObjectiveMaxOrMins()[0] == "min") osiSolver->setObjSense(1.0);
00152 else osiSolver->setObjSense(-1.0);
00153
00154 int *intIndex = NULL;
00155 int i = 0;
00156 int k = 0;
00157 char *varType;
00158 int numOfIntVars = osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables();
00159 if(numOfIntVars > 0) {
00160 intIndex = new int[ numOfIntVars];
00161 varType = osinstance->getVariableTypes();
00162 for(i = 0; i < osinstance->getVariableNumber(); i++){
00163 if( (varType[i] == 'B') || (varType[i]) == 'I' ) {
00164 intIndex[k++] = i;
00165 }
00166 }
00167 osiSolver->setInteger( intIndex, numOfIntVars);
00168 }
00169 if(numOfIntVars > 0){
00170 delete[] intIndex;
00171 intIndex = NULL;
00172 }
00173 bCallbuildSolverInstance = true;
00174 }
00175 catch(const ErrorClass& eclass){
00176 std::cout << "THERE IS AN ERROR" << std::endl;
00177 osresult->setGeneralMessage( eclass.errormsg);
00178 osresult->setGeneralStatusType( "error");
00179 osrl = osrlwriter->writeOSrL( osresult);
00180 throw ErrorClass( osrl) ;
00181 }
00182 }
00183
00184
00185 bool CoinSolver::setCoinPackedMatrix(){
00186 bool columnMajor = osinstance->getLinearConstraintCoefficientMajor();
00187 try{
00188 int maxGap = 0;
00189 m_CoinPackedMatrix = new CoinPackedMatrix(
00190 columnMajor,
00191 columnMajor? osinstance->getConstraintNumber() : osinstance->getVariableNumber(),
00192 columnMajor? osinstance->getVariableNumber() : osinstance->getConstraintNumber(),
00193 osinstance->getLinearConstraintCoefficientNumber(),
00194 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->values : osinstance->getLinearConstraintCoefficientsInRowMajor()->values,
00195 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes : osinstance->getLinearConstraintCoefficientsInRowMajor()->indexes,
00196 columnMajor? osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts : osinstance->getLinearConstraintCoefficientsInRowMajor()->starts,
00197 0, 0, maxGap );
00198
00199 return true;
00200 }
00201 catch(const ErrorClass& eclass){
00202 osresult->setGeneralMessage( eclass.errormsg);
00203 osresult->setGeneralStatusType( "error");
00204 osrl = osrlwriter->writeOSrL( osresult);
00205 throw ;
00206 }
00207 }
00208
00209 void CoinSolver::solve() throw (ErrorClass) {
00210
00211 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00212
00213 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00214
00215 if( sSolverName.find("clp") != std::string::npos) throw ErrorClass( "Clp cannot do integer programming");
00216 if( sSolverName.find("vol") != std::string::npos) throw ErrorClass( "Vol cannot do integer programming");
00217 if( sSolverName.find("dylp") != std::string::npos) throw ErrorClass( "DyLP cannot do integer programming");
00218 if( sSolverName.find("ipopt") != std::string::npos) throw ErrorClass( "Ipopt cannot do integer programming");
00219 }
00220 if( (osinstance->getNumberOfNonlinearExpressions() > 0)
00221 || (osinstance->getNumberOfQuadraticTerms() > 0) ){
00222 throw ErrorClass( "This COIN-OR Solver is not configured for nonlinear programming");
00223 }
00224
00225 double *x = NULL;
00226 double *y = NULL;
00227 double *z = NULL;
00228 int i = 0;
00229 std::string *rcost = NULL;
00230
00231 if(osresult->setServiceName("Solved with Coin Solver: " + sSolverName) != true)
00232 throw ErrorClass("OSResult error: setServiceName");
00233 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00234 throw ErrorClass("OSResult error: setInstanceName");
00235
00236
00237
00238
00239
00240 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00241 throw ErrorClass("OSResult error: setVariableNumer");
00242 if(osresult->setObjectiveNumber( 1) != true)
00243 throw ErrorClass("OSResult error: setObjectiveNumber");
00244 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00245 throw ErrorClass("OSResult error: setConstraintNumber");
00246 if(osresult->setSolutionNumber( 1) != true)
00247 throw ErrorClass("OSResult error: setSolutionNumer");
00248
00249 try{
00250 osiSolver->setDblParam(OsiObjOffset, osinstance->getObjectiveConstants()[0]);
00251
00252 #ifdef COIN_HAS_SYMPHONY
00253
00254 if( sSolverName.find( "symphony") != std::string::npos) {
00255 OsiSymSolverInterface * si =
00256 dynamic_cast<OsiSymSolverInterface *>(osiSolver) ;
00257 std::string num_proc = "";
00258 string::size_type pos1 = this->osol.find("num_proc");
00259 string::size_type pos2;
00260 if(pos1 != std::string::npos){
00261
00262 pos1 = osol.find(">", pos1 + 1);
00263 if(pos1 != std::string::npos){
00264
00265 pos2 = osol.find( "</other", pos1 + 1);
00266 if( pos2 != std::string::npos){
00267
00268 num_proc = osol.substr( pos1 + 1, pos2 - pos1 - 1);
00269 }
00270 }
00271 }
00272
00273 if(num_proc.size() > 0) si->setSymParam("max_active_nodes", num_proc);
00274 }
00275 #endif
00276
00277
00278
00279
00280 osiSolver->setHintParam(OsiDoScale, false, OsiHintTry);
00281 osiSolver->setHintParam(OsiDoReducePrint, true, OsiHintTry);
00282 OsiSolverInterface *m_OsiSolverPre = NULL;
00283
00284 try{
00285 if( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0){
00286
00287
00288 if( sSolverName.find( "cbc") == std::string::npos) {
00289 osiSolver->branchAndBound();
00290 }
00291 else{
00292
00293
00294
00295
00296 CglPreProcess process;
00297
00298
00299 m_OsiSolverPre = process.preProcess(*osiSolver, false, 10);
00300 if (!osiSolver) {
00301 throw ErrorClass("Pre-processing says infeasible");
00302 } else {
00303 printf("processed model has %d rows and %d columns\n",
00304 m_OsiSolverPre->getNumRows(), m_OsiSolverPre->getNumCols());
00305 }
00306 osiSolver->setHintParam( OsiDoScale, true, OsiHintDo) ;
00307 m_OsiSolverPre->branchAndBound( );
00308 cout << "CALL POSTPROCESS " << endl;
00309 process.postProcess( *m_OsiSolverPre);
00310 cout << "DONE WITH CALL POSTROCESS " << endl;
00311 }
00312 }
00313 else{
00314 osiSolver->initialSolve();
00315 }
00316 }
00317 catch(CoinError e){
00318 std::string errmsg;
00319 errmsg = "Coin Solver Error: " + e.message() + "\n" + " see method "
00320 + e.methodName() + " in class " + e.className();
00321 throw ErrorClass( errmsg );
00322 }
00323 int solIdx = 0;
00324 std::string description = "";
00325 osresult->setGeneralStatusType("success");
00326 if (osiSolver->isProvenOptimal() == true){
00327 osresult->setSolutionStatus(solIdx, "optimal", description);
00328
00329 x = new double[osinstance->getVariableNumber() ];
00330 y = new double[osinstance->getConstraintNumber() ];
00331 z = new double[1];
00332 rcost = new std::string[ osinstance->getVariableNumber()];
00333
00334 *(z + 0) = osiSolver->getObjValue();
00335 osresult->setObjectiveValues(solIdx, z);
00336 for(i=0; i < osinstance->getVariableNumber(); i++){
00337 *(x + i) = osiSolver->getColSolution()[i];
00338 }
00339 osresult->setPrimalVariableValues(solIdx, x);
00340
00341 if( sSolverName.find( "symphony") == std::string::npos){
00342 for(i=0; i < osinstance->getConstraintNumber(); i++){
00343 *(y + i) = osiSolver->getRowPrice()[ i];
00344 }
00345 osresult->setDualVariableValues(solIdx, y);
00346 }
00347
00348
00349
00350
00351 if( sSolverName.find( "symphony") == std::string::npos){
00352 int numberOfOtherVariableResult = 1;
00353 int otherIdx = 0;
00354
00355 osresult->setNumberOfOtherVariableResult(solIdx, numberOfOtherVariableResult);
00356 ostringstream outStr;
00357 int numberOfVar = osinstance->getVariableNumber();
00358 for(i=0; i < numberOfVar; i++){
00359 outStr << osiSolver->getReducedCost()[ i];
00360 rcost[ i] = outStr.str();
00361 outStr.str("");
00362 }
00363 osresult->setAnOtherVariableResult(solIdx, otherIdx, "reduced costs", "the variable reduced costs", rcost);
00364
00365 }
00366 }
00367 else{
00368 if(osiSolver->isProvenPrimalInfeasible() == true)
00369 osresult->setSolutionStatus(solIdx, "infeasible", description);
00370 else
00371 if(osiSolver->isProvenDualInfeasible() == true)
00372 osresult->setSolutionStatus(solIdx, "dualinfeasible", description);
00373 else
00374 osresult->setSolutionStatus(solIdx, "other", description);
00375 }
00376 osrl = osrlwriter->writeOSrL( osresult);
00377 if(osinstance->getVariableNumber() > 0) delete[] x;
00378 x = NULL;
00379 if(osinstance->getConstraintNumber()) delete[] y;
00380 y = NULL;
00381 delete[] z;
00382 z = NULL;
00383 if(osinstance->getVariableNumber() > 0){
00384 delete[] rcost;
00385 rcost = NULL;
00386 }
00387 cout << "DONE WITH COIN SOLVER SOLVE" << endl;
00388 }
00389 catch(const ErrorClass& eclass){
00390 osresult->setGeneralMessage( eclass.errormsg);
00391 osresult->setGeneralStatusType( "error");
00392 osrl = osrlwriter->writeOSrL( osresult);
00393 throw ;
00394 }
00395 }
00396
00397 std::string CoinSolver::getCoinSolverType(std::string lcl_osol){
00398
00399 try{
00400 if( lcl_osol.find( "clp") != std::string::npos){
00401 return "coin_solver_glpk";
00402 }
00403 else{
00404 if( lcl_osol.find( "cbc") != std::string::npos){
00405 return "coin_solver_cpx";
00406 }
00407 else{
00408 if( lcl_osol.find( "cpx") != std::string::npos){
00409 return "coin_solver_clp";
00410 }
00411 else{
00412 if(lcl_osol.find( "glpk") != std::string::npos){
00413 return "";
00414 }
00415 else throw ErrorClass("a supported solver was not defined");
00416 }
00417 }
00418 }
00419 }
00420 catch(const ErrorClass& eclass){
00421 osresult->setGeneralMessage( eclass.errormsg);
00422 osresult->setGeneralStatusType( "error");
00423 osrl = osrlwriter->writeOSrL( osresult);
00424 throw ;
00425 }
00426 }
00427
00428 void CoinSolver::dataEchoCheck(){
00429 int i;
00430
00431 cout << "This is problem: " << osinstance->getInstanceName() << endl;
00432 cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
00433 cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
00434 cout << "number of variables = " << osinstance->getVariableNumber() << endl;
00435 cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
00436
00437
00438 if(osinstance->getVariableNumber() > 0){
00439 for(i = 0; i < osinstance->getVariableNumber(); i++){
00440 if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
00441 if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
00442 if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
00443 if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
00444 }
00445 }
00446
00447
00448 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0){
00449 if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
00450 else cout << "problem is a maximization" << endl;
00451 for(i = 0; i < osinstance->getVariableNumber(); i++){
00452 cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
00453 }
00454 }
00455
00456 if(osinstance->getConstraintNumber() > 0){
00457 for(i = 0; i < osinstance->getConstraintNumber(); i++){
00458 if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
00459 if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
00460 if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
00461 }
00462 }
00463
00464
00465 if(m_CoinPackedMatrix != NULL) m_CoinPackedMatrix->dumpMatrix();
00466 }
00467
00468
00469
00470
00471