00001
00016 #include "OSLindoSolver.h"
00017 #include "OSiLReader.h"
00018 #include "OSInstance.h"
00019 #include "OSFileUtil.h"
00020 #include "OSOutput.h"
00021 #include "OSErrorClass.h"
00022
00023 #include "OSDataStructures.h"
00024 #include "OSParameters.h"
00025 #include "OSMathUtil.h"
00026
00027 #include "CoinTime.hpp"
00028
00029
00030 #ifdef HAVE_CTIME
00031 # include <ctime>
00032 #else
00033 # ifdef HAVE_TIME_H
00034 # include <time.h>
00035 # else
00036 # error "don't have header file for time"
00037 # endif
00038 #endif
00039 #include <iostream>
00040 #include <sstream>
00041 #include<vector>
00042 #include <map>
00043
00044 using std::cout;
00045 using std::endl;
00046 using std::ostringstream;
00047
00048 #define DEBUG
00049 #ifndef __LINDOI_H__
00050 #define __LINDOI_H__
00051
00052 #ifdef __cplusplus
00053 extern "C" {
00054 #endif
00055
00056 int CALLTYPE LSwriteMPIFile(pLSmodel pModel, char *pszFname);
00057
00058 #ifdef __cplusplus
00059 }
00060 #endif
00061
00062 #endif
00063
00064 #define LINDO_OP_CODE_CONVERSION \
00065 std::map<int, int> nlNodeIdxLindo;\
00066 nlNodeIdxLindo[OS_PLUS] = EP_PLUS; \
00067 nlNodeIdxLindo[OS_SUM] = EP_SUM; \
00068 nlNodeIdxLindo[OS_MINUS] = EP_MINUS; \
00069 nlNodeIdxLindo[OS_NEGATE] = EP_NEGATE; \
00070 nlNodeIdxLindo[OS_TIMES] = EP_MULTIPLY; \
00071 nlNodeIdxLindo[OS_DIVIDE] = EP_DIVIDE; \
00072 nlNodeIdxLindo[OS_POWER] = EP_POWER; \
00073 nlNodeIdxLindo[OS_SQRT] = EP_SQRT; \
00074 nlNodeIdxLindo[OS_LN] = EP_LN; \
00075 nlNodeIdxLindo[OS_EXP] = EP_EXP; \
00076 nlNodeIdxLindo[OS_NUMBER] = EP_PUSH_NUM; \
00077 nlNodeIdxLindo[OS_VARIABLE] = EP_PUSH_VAR;\
00078 nlNodeIdxLindo[OS_IF] = EP_IF; \
00079 nlNodeIdxLindo[OS_ABS] = EP_ABS; \
00080 nlNodeIdxLindo[OS_MAX] = EP_MAX; \
00081 nlNodeIdxLindo[OS_MIN] = EP_MIN; \
00082 nlNodeIdxLindo[OS_SQUARE] = EP_SQR; \
00083 nlNodeIdxLindo[OS_SIN] = EP_SIN; \
00084 nlNodeIdxLindo[OS_COS] = EP_COS;
00085
00086 LindoSolver::LindoSolver():
00087 m_osilreader( NULL),
00088 pEnv_( NULL),
00089 pModel_( NULL),
00090 m_miSlackIdx( NULL),
00091 m_iNumberNewSlacks( 0),
00092 m_mdRhsValue( NULL),
00093 m_mcRowType( NULL),
00094 m_mdVarLB( NULL),
00095 m_mdVarUB( NULL),
00096 m_mdConLB( NULL),
00097 m_mdConUB( NULL),
00098 m_mmcVarName( NULL),
00099 m_msVarName( NULL),
00100 m_msConName( NULL),
00101 m_mcVarType( NULL),
00102 m_mdObjConstant( 0),
00103 osrlwriter( NULL),
00104 cpuTime( 0)
00105
00106 {
00107 #ifndef NDEBUG
00108 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "Lindo constructor called\n");
00109 #endif
00110 osrlwriter = new OSrLWriter();
00111 }
00112
00113 LindoSolver::~LindoSolver()
00114 {
00115 #ifndef NDEBUG
00116 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "Lindo destructor called\n");
00117 #endif
00118
00119
00120
00121 delete[] m_mmcVarName ;
00122
00123 m_mdConLB = NULL;
00124 m_mdConUB = NULL;
00125 m_msVarName = NULL;
00126 m_mcVarType = NULL;
00127 m_mcRowType = NULL;
00128 m_msConName = NULL;
00129 #ifndef NDEBUG
00130 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "Delete LSdelete\n");
00131 #endif
00132 LSdeleteEnv(&pEnv_);
00133 delete[] m_miSlackIdx;
00134 m_miSlackIdx = NULL;
00135 delete[] m_mdRhsValue;
00136 m_mdRhsValue = NULL;
00137 delete osrlwriter;
00138 osrlwriter = NULL;
00139 delete osresult;
00140 osresult = NULL;
00141 if(m_osilreader != NULL) delete m_osilreader;
00142 m_osilreader = NULL;
00143 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "Lindo Solver garbage collection done\n");
00144
00145 }
00146
00147
00148 void LindoSolver::buildSolverInstance() throw (ErrorClass)
00149 {
00150 try
00151 {
00152 osresult = new OSResult();
00153 if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
00154 OSiLReader* osilreader = NULL;
00155 bool newOSiLReader = false;
00156 if(osinstance == NULL)
00157 {
00158 osilreader = new OSiLReader();
00159 osinstance = osilreader->readOSiL( osil);
00160 newOSiLReader = true;
00161
00162 }
00163
00164 OSiLWriter osilwriter;
00165
00166 if (osinstance->instanceData->constraints->numberOfConstraints <= 0)
00167 {
00168 #ifndef NDEBUG
00169 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00170 "HERE I AM 1 !!!!!!!!!!!!!!!!!!!\n");
00171 #endif
00172 osinstance->setConstraintNumber(1);
00173 osinstance->addConstraint(0, "dummyConstraint", 0, 0, 0);
00174 #ifndef NDEBUG
00175 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00176 "HERE I AM 2 !!!!!!!!!!!!!!!!!!!\n");
00177 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug,
00178 osilwriter.writeOSiL( osinstance));
00179 #endif
00180 }
00181 if(osinstance->getVariableNumber() < 0)throw ErrorClass("Cannot have a negative number of decision variables");
00182 #ifndef NDEBUG
00183 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00184 "Start process variables !!!!!!!!!\n");
00185 #endif
00186 if( !processVariables() ) throw ErrorClass("failed processing variables");
00187 #ifndef NDEBUG
00188 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00189 "Finish process variables !!!!!!!!!\n");
00190 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00191 "Start process constraints !!!!!!!!!\n");
00192 #endif
00193 if( !processConstraints() ) throw ErrorClass("failed processing constraints");
00194 #ifndef NDEBUG
00195 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00196 "Finish process constraints !!!!!!!!!\n");
00197 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00198 "Start generateLindoModel() !!!!!!!!!\n");
00199 #endif
00200 if( !generateLindoModel()) throw ErrorClass("failed generating Lindo model");
00201 #ifndef NDEBUG
00202 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00203 "Finish generateLindoModel() !!!!!!!!!\n");
00204 #endif
00205 if(m_iNumberNewSlacks > 0 && !addSlackVars()) throw ErrorClass("failed adding slack variables");
00206 if( (osinstance->getNumberOfNonlinearExpressions() > 0 || osinstance->getNumberOfQuadraticTerms() > 0)
00207 && !processNonlinearExpressions()) throw ErrorClass("failed adding nonlinear terms");
00208 this->bCallbuildSolverInstance = true ;
00209
00210 }
00211 catch(const ErrorClass& eclass)
00212 {
00213 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
00214 osresult->setGeneralMessage( eclass.errormsg);
00215 osresult->setGeneralStatusType( "error");
00216 osrl = osrlwriter->writeOSrL( osresult);
00217 throw ErrorClass( osrl) ;
00218 }
00219 }
00220
00221
00222
00223 void LindoSolver::setSolverOptions() throw (ErrorClass)
00224 {
00225 try
00226 {
00227
00228 }
00229 catch(const ErrorClass& eclass)
00230 {
00231 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
00232 osresult->setGeneralMessage( eclass.errormsg);
00233 osresult->setGeneralStatusType( "error");
00234 osrl = osrlwriter->writeOSrL( osresult);
00235 throw ErrorClass( osrl) ;
00236 }
00237 }
00238
00239
00240 void LindoSolver::solve()
00241 {
00242 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00243 try
00244 {
00245 double start = CoinCpuTime();
00246 if( optimize() != true) throw ErrorClass("problem optimizing model");
00247 cpuTime = CoinCpuTime() - start;
00248 osresult->setGeneralStatusType("normal");
00249 osresult->setTime(cpuTime);
00250 osrl = osrlwriter->writeOSrL( osresult);
00251 }
00252 catch(const ErrorClass& eclass)
00253 {
00254 osresult->setGeneralMessage( eclass.errormsg);
00255 osresult->setGeneralStatusType( "error");
00256 osrl = osrlwriter->writeOSrL( osresult);
00257 throw ErrorClass( osrl) ;
00258 }
00259 }
00260
00261 bool LindoSolver::processConstraints()
00262 {
00263 int i;
00264 m_iNumberNewSlacks = 0;
00265 try
00266 {
00267
00268
00269 m_mdConLB = osinstance->getConstraintLowerBounds();
00270 m_mdConUB = osinstance->getConstraintUpperBounds();
00271 m_msConName = osinstance->getConstraintNames();
00272 m_mdRhsValue = new double[ osinstance->getConstraintNumber()];
00273 m_miSlackIdx = new int[ osinstance->getConstraintNumber()];
00274 m_mcRowType = osinstance->getConstraintTypes();
00275
00276 for(i = 0; i < osinstance->getConstraintNumber(); i++)
00277 {
00278 switch( m_mcRowType[ i] )
00279 {
00280 case 'E':
00281 m_mdRhsValue[ i] = m_mdConUB[ i];
00282
00283
00284 break;
00285 case 'L':
00286 m_mdRhsValue[ i] = m_mdConUB[ i];
00287 break;
00288 case 'G':
00289 m_mdRhsValue[ i] = m_mdConLB[ i];
00290 break;
00291 case 'U':
00292 throw ErrorClass("LINDO cannot handle unbounded constraints");
00293 break;
00294 case 'R':
00295
00296 m_mdRhsValue[ i] = m_mdConUB[ i] ;
00297 m_mcRowType[ i] = 'E';
00298 m_miSlackIdx[ m_iNumberNewSlacks] = i;
00299 m_iNumberNewSlacks++;
00300 break;
00301 }
00302 }
00303 return true;
00304 }
00305 catch(const ErrorClass& eclass)
00306 {
00307 osresult->setGeneralMessage( eclass.errormsg);
00308 osresult->setGeneralStatusType( "error");
00309 osrl = osrlwriter->writeOSrL( osresult);
00310 throw ;
00311 }
00312 }
00313
00314 bool LindoSolver::addSlackVars()
00315 {
00316 std::ostringstream outStr;
00317
00318
00319
00320
00321
00322 if(m_iNumberNewSlacks <= 0) return false;
00323 int i;
00324 ostringstream varName;
00325 char* p;
00326 std::string tmpstring;
00327 char* pachVartypes = new char[m_iNumberNewSlacks];
00328 char** paszVarnames = new char*[m_iNumberNewSlacks];
00329 int* paiAcols = new int[m_iNumberNewSlacks + 1];
00330 int* pacAcols = NULL;
00331 double* padAcoef = new double[m_iNumberNewSlacks];
00332 int* paiArows = new int[m_iNumberNewSlacks];
00333 double* padC = new double[m_iNumberNewSlacks];
00334 double* padL = NULL;
00335 double* padU = new double[m_iNumberNewSlacks];
00336 for(i = 0; i < m_iNumberNewSlacks; i++)
00337 {
00338 pachVartypes[ i] = 'C';
00339 varName << "xyzabc_" ;
00340 varName << i ;
00341 varName << '\0';
00342 tmpstring = varName.str();
00343 p = new char[tmpstring.size() + 1];
00344 strcpy(p, tmpstring.c_str());
00345 char ch;
00346 ch = ' ';
00347
00348 if( m_iNumberNewSlacks == 1) paszVarnames[i] = &ch;
00349 else paszVarnames[i] = p;
00350 varName << "";
00351 paiAcols[ i] = i;
00352 padAcoef[ i] = 1.0;
00353 paiArows[ i] = m_miSlackIdx[ i];
00354 padC[ i] = 0.0;
00355 padU[ i] = m_mdConUB[ m_miSlackIdx[ i]] - m_mdConLB[ m_miSlackIdx[ i]];
00356 if(padU[ i] - padC[i]< 0) return false;
00357 }
00358 paiAcols[ m_iNumberNewSlacks] = m_iNumberNewSlacks;
00359 #ifndef NDEBUG
00360 outStr.str("");
00361 outStr.clear();
00362 outStr << "The number of new slack variables is: " << m_iNumberNewSlacks << endl;
00363 for(i = 0; i < m_iNumberNewSlacks; i++)
00364 {
00365 outStr << paszVarnames[ i] << endl;
00366 }
00367 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00368 #endif
00369
00370 if(!LSaddVariables(pModel_, m_iNumberNewSlacks, pachVartypes, paszVarnames, paiAcols,
00371 pacAcols, padAcoef, paiArows, padC, padL, padU))
00372 {
00373 if(m_iNumberNewSlacks > 0)
00374 {
00375
00376 delete[] paiAcols;
00377 delete[] padAcoef;
00378 delete[] paiArows;
00379 delete[] padC;
00380 delete[] padU;
00381
00382
00383 if( m_iNumberNewSlacks == 1)
00384 {
00385 delete paszVarnames;
00386 delete pachVartypes;
00387 }
00388 else
00389 {
00390 for(i = 0; i < m_iNumberNewSlacks; i++) delete[] paszVarnames[i];
00391 delete[] paszVarnames;
00392 delete[] pachVartypes;
00393 }
00394 }
00395 return true;
00396 }
00397 else
00398 {
00399 return false;
00400 }
00401 }
00402
00403
00404 bool LindoSolver::processVariables()
00405 {
00406 int i;
00407 try
00408 {
00409 m_mcVarType = osinstance->getVariableTypes();
00410 m_mdVarLB = osinstance->getVariableLowerBounds();
00411 m_mdVarUB = osinstance->getVariableUpperBounds();
00412 m_mmcVarName = new char*[ osinstance->getVariableNumber()];
00413 for(i = 0; i < osinstance->getVariableNumber(); i++)
00414 {
00415 m_mmcVarName[i] = &osinstance->getVariableNames()[ i][0];
00416 }
00417
00418 for(i = 0; i < osinstance->getVariableNumber() ; i++)
00419 {
00420 if( osinstance->getVariableTypes()[ i] == 'B')
00421 {
00422 m_mdVarUB[ i] = 1.0;
00423 }
00424 }
00425
00426 return true;
00427 }
00428 catch(const ErrorClass& eclass)
00429 {
00430 osresult->setGeneralMessage( eclass.errormsg);
00431 osresult->setGeneralStatusType( "error");
00432 osrl = osrlwriter->writeOSrL( osresult);
00433 throw ;
00434 }
00435 }
00436
00437
00438
00439 bool LindoSolver::generateLindoModel()
00440 {
00441 std::ostringstream outStr;
00442
00443
00444
00445
00446
00447
00448 char *MY_LICENSE_KEY = NULL;
00449 MY_LICENSE_KEY = getenv( "LINDOAPI_LICENSE_FILE");
00450 try
00451 {
00452 pEnv_ = LScreateEnv ( &m_iLindoErrorCode, MY_LICENSE_KEY);
00453 lindoAPIErrorCheck("There was an Error Creating the LINDO environment");
00454
00455 pModel_ = LScreateModel ( pEnv_, &m_iLindoErrorCode);
00456 lindoAPIErrorCheck("There was an Error Creating the LINDO Model");
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 int *colLength = NULL;
00476
00477 if(osinstance->getLinearConstraintCoefficientNumber() <= 0)
00478 {
00479 outStr.str("");
00480 outStr.clear();
00481 outStr << "LinearConstraintCoefficientNumber = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
00482 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
00483
00484
00485 int iNumFakeNonz = 1;
00486
00487 int *paiArrayIdx;
00488 paiArrayIdx = new int[ 1];
00489 paiArrayIdx[ 0] = 0;
00490
00491 double *padValArray;
00492 padValArray = new double[ 1];
00493 padValArray[0] = 0;
00494
00495 int *paiArrayBeg;
00496 paiArrayBeg = new int[osinstance->getVariableNumber() + 1];
00497 paiArrayBeg[0] = 0;
00498 for(int kl = 1; kl <= osinstance->getVariableNumber(); kl++)
00499 {
00500 paiArrayBeg[kl] = 1;
00501 }
00502
00503
00504 m_iLindoErrorCode = LSloadLPData( pModel_, osinstance->getConstraintNumber(), osinstance->getVariableNumber(),
00505 ( osinstance->getObjectiveMaxOrMins()[0] == "min")?LS_MIN:LS_MAX ,
00506 osinstance->getObjectiveConstants()[0],
00507 osinstance->getDenseObjectiveCoefficients()[0],
00508 m_mdRhsValue, m_mcRowType,
00509 iNumFakeNonz,
00510 paiArrayBeg,
00511 colLength, padValArray,
00512 paiArrayIdx,
00513 m_mdVarLB, m_mdVarUB);
00514 lindoAPIErrorCheck("Error with LSloadLPData when the number of nonzeros is 0");
00515 }
00516 else
00517 {
00518 m_iLindoErrorCode = LSloadLPData( pModel_, osinstance->getConstraintNumber(), osinstance->getVariableNumber(),
00519 ( osinstance->getObjectiveMaxOrMins()[0] == "min")?LS_MIN:LS_MAX ,
00520 osinstance->getObjectiveConstants()[0], osinstance->getDenseObjectiveCoefficients()[0], m_mdRhsValue, m_mcRowType,
00521 osinstance->getLinearConstraintCoefficientNumber(),
00522 osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts,
00523 colLength, osinstance->getLinearConstraintCoefficientsInColumnMajor()->values,
00524 osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes,
00525 m_mdVarLB, m_mdVarUB);
00526 lindoAPIErrorCheck("Error with LSloadLPData when the number of nonzeros is greater than 0");
00527 }
00528 m_iLindoErrorCode = LSloadVarType(pModel_, m_mcVarType);
00529 lindoAPIErrorCheck("There was an error loading the Lindo Variable Types");
00530 return true;
00531 }
00532 catch( const ErrorClass& eclass)
00533 {
00534 osresult->setGeneralMessage( eclass.errormsg);
00535 osresult->setGeneralStatusType( "error");
00536 osrl = osrlwriter->writeOSrL( osresult);
00537 throw ;
00538 }
00539 }
00540
00541
00542 bool LindoSolver::optimize()
00543 {
00544 double *x, *y, *z;
00545 int solIdx = 0;
00546 ostringstream outStr;
00547 std::string *srcost;
00548 bool isNonlinear = false;
00549 double *drcost;
00550 int nSolStatus;
00551 std::string description = "";
00552
00553 if(osresult->setSolverInvoked( "LINDO Systems, Inc. Lindo API") != true)
00554 throw ErrorClass("OSResult error: setSolverInvoked");
00555 if(osresult->setServiceName( OSgetVersionInfo()) != true)
00556 throw ErrorClass("OSResult error: setServiceName");
00557
00558 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00559 throw ErrorClass("OSResult error: setInstanceName");
00560
00561
00562
00563
00564 if(osinstance->getNumberOfNonlinearObjectives() > 0 || osinstance->getNumberOfNonlinearConstraints() > 0) isNonlinear = true;
00565 try
00566 {
00567 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("LINDO NEEDS AN OBJECTIVE FUNCTION");
00568
00569 if( isNonlinear == true )
00570 {
00571
00572 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00573 "We are using the LINDO Global Optimizer\n");
00574 m_iLindoErrorCode = LSsolveGOP(pModel_, &nSolStatus) ;
00575 lindoAPIErrorCheck("There was an ERROR in the call to the Optimizer solver");
00576 LSgetInfo (pModel_, LS_IINFO_GOP_STATUS, &nSolStatus);
00577 }
00578 else
00579 {
00580 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00581 "We are using the LINDO LSsolveMIP Optimizer\n");
00582 m_iLindoErrorCode = LSsolveMIP( pModel_, &nSolStatus);
00583 lindoAPIErrorCheck("There was an ERROR in the call to the MIP solver");
00584 }
00585
00586 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00587 throw ErrorClass("OSResult error: setVariableNumer");
00588 if(osresult->setObjectiveNumber( 1) != true)
00589 throw ErrorClass("OSResult error: setObjectiveNumber");
00590 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00591 throw ErrorClass("OSResult error: setConstraintNumber");
00592 if(osresult->setSolutionNumber( 1) != true)
00593 throw ErrorClass("OSResult error: setSolutionNumer");
00594 outStr.str("");
00595 outStr.clear();
00596 outStr << "Solution Status = " << nSolStatus << endl;
00597 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00598
00599 osresult->setGeneralStatusType("normal");
00600 osresult->setSolutionStatus(solIdx, "optimal", description);
00601 x = new double[ osinstance->getVariableNumber() + m_iNumberNewSlacks];
00602 srcost = new std::string[ osinstance->getVariableNumber() + m_iNumberNewSlacks];
00603 drcost = new double[ osinstance->getVariableNumber() + m_iNumberNewSlacks];
00604 for(int i = 0; i < osinstance->getVariableNumber() + m_iNumberNewSlacks; i++)
00605 {
00606 drcost[i] = 0.0;
00607 srcost[i] = "";
00608 }
00609 y = new double[ osinstance->getConstraintNumber() ];
00610 z = new double[1];
00611 switch( nSolStatus)
00612 {
00613 case 1:
00614
00615 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "case 1\n");
00616 case 8:
00617
00618 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "case 8\n");
00619 case 2:
00620 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "case 2\n");
00621
00622
00623 if( (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0 )
00624 || (isNonlinear == false) )
00625 {
00626 m_iLindoErrorCode = LSgetMIPPrimalSolution( pModel_, x);
00627 lindoAPIErrorCheck("Error trying to obtain primal solution with integer variables present");
00628 }
00629
00630 else
00631 {
00632 m_iLindoErrorCode = LSgetPrimalSolution( pModel_, x);
00633 lindoAPIErrorCheck("Error trying to obtain primal solution with NO integer variables present");
00634 }
00635 osresult->setPrimalVariableValuesDense(solIdx, x);
00636
00637 if( (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00638 || (isNonlinear == false) )
00639 {
00640 m_iLindoErrorCode = LSgetMIPDualSolution( pModel_, y);
00641 lindoAPIErrorCheck("Error trying to obtain dual solution with integer variables present");
00642 }
00643 else
00644 {
00645 m_iLindoErrorCode = LSgetDualSolution( pModel_, y);
00646 lindoAPIErrorCheck("Error trying to obtain dual solution with NO integer variables present");
00647 }
00648 osresult->setDualVariableValuesDense(solIdx, y);
00649
00650 if( ( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00651 || (isNonlinear == false ) )
00652 {
00653
00654
00655 }
00656 else
00657 {
00658 m_iLindoErrorCode = LSgetReducedCosts( pModel_, drcost);
00659 lindoAPIErrorCheck("Error trying to obtain the reduced costs with NO integer variables present");;
00660 }
00661
00662 {
00663 int numberOfOtherVariableResult = 1;
00664 int otherIdx = 0;
00665
00666 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResult);
00667 for(int i = 0; i < osinstance->getVariableNumber() + m_iNumberNewSlacks; i++)
00668 {
00669 outStr << drcost[i];
00670 srcost[ i] = outStr.str();
00671 outStr.str("");
00672 }
00673 osresult->setAnOtherVariableResultDense(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", srcost);
00674
00675 if( ( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00676 || (isNonlinear == false ) )
00677 {
00678 m_iLindoErrorCode = LSgetInfo( pModel_, LS_DINFO_MIP_OBJ, &z[0]);
00679 lindoAPIErrorCheck("Error trying to obtain optimal objective value with integer variables present");
00680 }
00681 else
00682 {
00683 LSgetInfo( pModel_, LS_DINFO_GOP_OBJ, &z[0]);
00684 lindoAPIErrorCheck("Error trying to obtain optimal objective value with NO integer variables present");
00685 }
00686 osresult->setObjectiveValuesDense(solIdx, z);
00687 }
00688 break;
00689 case 3:
00690 osresult->setSolutionStatus(solIdx, "infeasible", description);
00691 break;
00692 case 4:
00693 osresult->setSolutionStatus(solIdx, "unbounded", description);
00694 break;
00695 default:
00696 osresult->setSolutionStatus(solIdx, "other", description);
00697 }
00698
00699 delete[] x;
00700 delete[] y;
00701 delete[] z;
00702 delete[] srcost;
00703 delete[] drcost;
00704 return true;
00705 }
00706 catch(const ErrorClass& eclass)
00707 {
00708
00709 osresult->setGeneralMessage( eclass.errormsg);
00710 osresult->setGeneralStatusType( "error");
00711 osrl = osrlwriter->writeOSrL( osresult);
00712 throw ;
00713 }
00714 }
00715
00716
00717 bool LindoSolver::processQuadraticTerms()
00718 {
00719 int nQCnnz = osinstance->getNumberOfQuadraticTerms();
00720 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00721 "WE ARE PROCESSING QUADRATIC TERMS\n");
00722 try
00723 {
00724 if(nQCnnz <= 0)return false;
00725 std::map<std::string, double> mapQuadraticAdjustMap;
00726 std::map<std::string, double>::iterator mapPointer;
00727
00728 int i;
00729 int iVarOneIndex, iVarTwoIndex;
00730 int iRowIndex;
00731 std::string sKey;
00732 double dValue;
00733
00734 int iStringPostionOne, iStringPostionTwo;
00735
00736 int* paiQCrows = osinstance->getQuadraticTerms()->rowIndexes;
00737 int* paiQCcols1 = osinstance->getQuadraticTerms()->varOneIndexes;
00738 int* paiQCcols2 = osinstance->getQuadraticTerms()->varTwoIndexes;
00739 double* padQCcoef = osinstance->getQuadraticTerms()->coefficients;
00740 std::ostringstream ostrRow, ostr1, ostr2;
00741 std::string sIndexRow, sIndex1, sIndex2;
00742
00743 for ( i = 0; i < nQCnnz; i++)
00744 {
00745 iRowIndex = paiQCrows[i];
00746
00747 if (iRowIndex >= -1)
00748 {
00749 iVarOneIndex = (paiQCcols1[i] >= paiQCcols2[i])?paiQCcols2[i]:paiQCcols1[i];
00750 iVarTwoIndex = (paiQCcols1[i] <= paiQCcols2[i])?paiQCcols2[i]:paiQCcols1[i];
00751 ostrRow << iRowIndex;
00752 ostr2<<iVarTwoIndex;
00753 ostr1<<iVarOneIndex;
00754 sIndexRow = ostrRow.str();
00755 sIndex2 = ostr2.str();
00756 sIndex1 = ostr1.str();
00757
00758 ostrRow.str("");
00759 ostr2.str("");
00760 ostr1.str("");
00761
00762 sKey = sIndexRow + "," + sIndex1 + "," + sIndex2;
00763
00764 mapPointer = mapQuadraticAdjustMap.find(sKey);
00765 if (mapPointer != mapQuadraticAdjustMap.end())
00766 {
00767 dValue = mapPointer->second;
00768 dValue += padQCcoef[i];
00769 mapQuadraticAdjustMap[sKey] = dValue;
00770 }
00771 else
00772 {
00773 mapQuadraticAdjustMap[sKey] = padQCcoef[i];
00774 }
00775 }
00776 }
00777
00778 int iNumberOfQuadraticTerms = 0;
00779 for (mapPointer = mapQuadraticAdjustMap.begin(); mapPointer != mapQuadraticAdjustMap.end(); ++mapPointer)
00780 {
00781 sKey = mapPointer->first;
00782 dValue = mapPointer->second;
00783 iStringPostionOne = sKey.find_first_of(',');
00784 iStringPostionTwo = sKey.find_last_of(',');
00785
00786 iRowIndex = atoi(sKey.substr(0, iStringPostionOne).c_str());
00787 iVarOneIndex = atoi(sKey.substr(iStringPostionOne + 1, iStringPostionTwo).c_str());
00788 iVarTwoIndex = atoi(sKey.substr(iStringPostionTwo + 1).c_str());
00789
00790 if ( iVarOneIndex == iVarTwoIndex)
00791 {
00792 dValue *= 2;
00793 }
00794
00795 paiQCrows[iNumberOfQuadraticTerms] = iRowIndex;
00796 paiQCcols1[iNumberOfQuadraticTerms] = iVarOneIndex;
00797 paiQCcols2[iNumberOfQuadraticTerms] = iVarTwoIndex;
00798
00799 padQCcoef[iNumberOfQuadraticTerms] = dValue ;
00800 iNumberOfQuadraticTerms ++;
00801 }
00802
00803 if(!LSloadQCData(pModel_, nQCnnz, paiQCrows, paiQCcols1,
00804 paiQCcols2, padQCcoef)) return true;
00805 else return false;
00806 }
00807 catch(const ErrorClass& eclass)
00808 {
00809 osresult->setGeneralMessage( eclass.errormsg);
00810 osresult->setGeneralStatusType( "error");
00811 osrl = osrlwriter->writeOSrL( osresult);
00812 throw ;
00813 }
00814 }
00815
00816
00817
00818 bool LindoSolver::processNonlinearExpressions()
00819 {
00820 std::ostringstream outStr;
00821
00822 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00823 "PROCESS NONLINEAR TERMS\n");
00824 osinstance->initializeNonLinearStructures( );
00825
00826 outStr.str("");
00827 outStr.clear();
00828 outStr << "The number of objectives with nonlinear terms is: "
00829 << osinstance->getNumberOfNonlinearObjectives() << endl;
00830 outStr << "The number of constraints with nonlinear terms is: "
00831 << osinstance->getNumberOfNonlinearConstraints() << endl << endl << endl;
00832 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
00833
00834
00835
00836 LINDO_OP_CODE_CONVERSION;
00842 std::map<double, int> mapNewNumber;
00843
00845 std::map<double, int>::iterator pos;
00846
00852 std::vector<int> insList;
00853
00854
00860 std::map<int, OSExpressionTree*> allExpTrees;
00861
00867 std::vector<OSnLNode*> postFixVec;
00868
00870 std::map<int, OSExpressionTree*>::iterator posTree;
00871
00881 int *piObjSense = NULL;
00882
00886 double *padVarLowerBounds = NULL;
00887
00891 double *padVarUpperBounds = NULL;
00892
00894 double *padVarval = NULL;
00895
00899 char *pachVarType = NULL;
00900
00903 char *pachConType = NULL;
00904
00906 int iNumNonlinearNonz = 0;
00907
00909 double *padNonlinearNonz = NULL;
00910
00912 int iNumberOfNonlinearConstraints = osinstance->getNumberOfNonlinearConstraints();
00913
00917 int *paiConsBegin = NULL;
00918 if(iNumberOfNonlinearConstraints > 0) paiConsBegin = new int[ iNumberOfNonlinearConstraints];
00919
00923 int *paiConsLength = NULL;
00924 if(iNumberOfNonlinearConstraints > 0) paiConsLength = new int[ iNumberOfNonlinearConstraints];
00925
00927 int iNumberOfNonlinearObjectives = osinstance->getNumberOfNonlinearObjectives();
00928
00932 int *paiObjsBegin = NULL;
00933 if(iNumberOfNonlinearObjectives > 0) paiObjsBegin = new int[ iNumberOfNonlinearObjectives];
00934
00938 int *paiObjsLength = NULL;
00939 if(iNumberOfNonlinearObjectives > 0) paiObjsLength = new int[ iNumberOfNonlinearObjectives];
00940
00941
00947 int iNumberOfNewVariables = 0;
00948
00950 int *paiInsList;
00951
00953 int iInstListLength = 0;
00954
00956 int *paiNonlinearConIndex = NULL;
00957 if(iNumberOfNonlinearConstraints > 0) paiNonlinearConIndex = new int[ iNumberOfNonlinearConstraints];
00958
00959
00960 try
00961 {
00962 int i;
00963
00964 int iCountObjs = 0;
00965 int iCountCons = 0;
00966
00967 allExpTrees = osinstance->getAllNonlinearExpressionTreesMod();
00968
00969 for(posTree = allExpTrees.begin(); posTree != allExpTrees.end(); ++posTree)
00970 {
00971 outStr.str("");
00972 outStr.clear();
00973 outStr << "HERE IS EXPRESSION TREE " << posTree->first << endl;
00974 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
00975
00976 postFixVec = posTree->second->m_treeRoot->getPostfixFromExpressionTree();
00977 int iVecSize = postFixVec.size();
00978 int iNodeID;
00979 if(iVecSize > 0)
00980 {
00981 for(i = 0; i < iVecSize; i++)
00982 {
00983 iNodeID = postFixVec[i]->inodeInt;
00984 switch (iNodeID)
00985 {
00986 case OS_SUM:
00987 insList.push_back( nlNodeIdxLindo[ OS_SUM] );
00988 insList.push_back( postFixVec[i]->inumberOfChildren);
00989 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "PUSH BACK A SUM\n");
00990 break;
00991 case OS_MAX:
00992 insList.push_back( nlNodeIdxLindo[ OS_MAX] );
00993 insList.push_back( postFixVec[i]->inumberOfChildren);
00994 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "PUSH BACK A MAX\n");
00995 break;
00996 case OS_PRODUCT:
00997 throw ErrorClass("Error: OS_PRODUCT operator not supported by Lindo");
00998 break;
00999 case OS_NUMBER:
01000 OSnLNodeNumber *numNode;
01001 insList.push_back( EP_PUSH_NUM );
01002 numNode = (OSnLNodeNumber*)postFixVec[i];
01003 pos = mapNewNumber.find( numNode->value);
01004 if(pos == mapNewNumber.end() )
01005 {
01006 outStr.str("");
01007 outStr.clear();
01008 outStr << "FOUND A NEW NUMBER " << numNode->value << endl;
01009 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01010 insList.push_back( iNumNonlinearNonz);
01011 mapNewNumber[ numNode->value] = iNumNonlinearNonz++;
01012 }
01013 else insList.push_back( pos->second);
01014 break;
01015 case OS_VARIABLE:
01016 OSnLNodeVariable *varNode;
01017 insList.push_back( EP_PUSH_VAR );
01018 varNode = (OSnLNodeVariable*)postFixVec[i];
01019 insList.push_back( varNode->idx );
01020
01021
01022 if(varNode->coef != 1)
01023 {
01024
01025 insList.push_back( EP_PUSH_NUM );
01026 pos = mapNewNumber.find( varNode->coef);
01027 if(pos == mapNewNumber.end() )
01028 {
01029 outStr.str("");
01030 outStr.clear();
01031 outStr << "FOUND A NEW NUMBER " << varNode->coef << endl;
01032 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01033 insList.push_back( iNumNonlinearNonz);
01034 mapNewNumber[ varNode->coef] = iNumNonlinearNonz++;
01035 }
01036 else insList.push_back( pos->second);
01037 insList.push_back( EP_MULTIPLY);
01038 }
01039 break;
01040 default:
01041 insList.push_back( nlNodeIdxLindo[iNodeID] );
01042 break;
01043 }
01044 }
01045
01046 if(posTree->first < 0)
01047 {
01048
01049
01050 paiObjsBegin[ iCountObjs] = iInstListLength;
01051 paiObjsLength[ iCountObjs] = insList.size() - iInstListLength;
01052 iInstListLength = insList.size();
01053 iCountObjs++;
01054 }
01055 else
01056 {
01057
01058 paiConsBegin[ iCountCons] = iInstListLength;
01059 paiConsLength[ iCountCons] = insList.size() - iInstListLength;
01060 paiNonlinearConIndex[ iCountCons] = posTree->first;
01061 outStr.str("");
01062 outStr.clear();
01063 outStr << "CONSTRAINT ILIST LENGTH = " << iInstListLength << endl;
01064 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01065 iInstListLength = insList.size();
01066 iCountCons++;
01067 }
01068 }
01069 postFixVec.clear();
01070 }
01071
01072 padNonlinearNonz = new double[ iNumNonlinearNonz];
01073 outStr.str("");
01074 outStr.clear();
01075 for(pos = mapNewNumber.begin(); pos != mapNewNumber.end(); ++pos)
01076 {
01077 padNonlinearNonz[ pos->second] = pos->first;
01078 outStr << "INDEX = " << pos->second << " NUMBER = " << pos->first << endl;
01079 }
01080 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01081
01082 paiInsList = new int[ iInstListLength];
01083 copy(insList.begin(), insList.end(), paiInsList);
01084
01085
01086
01087 int nLinearz, nAutoDeriv;
01088
01089
01090 nLinearz = 1;
01091 m_iLindoErrorCode = LSsetModelIntParameter (pModel_,
01092 LS_IPARAM_NLP_LINEARZ, nLinearz);
01093 lindoAPIErrorCheck("Error trying to set the LS_IPARAM_NLP_LINEARZ parameter");
01094
01095
01096
01097
01098 nAutoDeriv = 1;
01099 m_iLindoErrorCode = LSsetModelIntParameter (pModel_,
01100 LS_IPARAM_NLP_AUTODERIV, nAutoDeriv);
01101 lindoAPIErrorCheck("Error trying to set the LS_IPARAM_NLP_AUTODERIV parameter");
01102 #ifndef NDEBUG
01103 outStr.str("");
01104 outStr.clear();
01105 outStr << "iNumberOfNonlinearConstraints= " << iNumberOfNonlinearConstraints << std::endl;
01106 outStr << "iNumberOfNonlinearObjectives= " << iNumberOfNonlinearObjectives << std::endl;
01107 outStr << "iNumberOfNewVariables = " << iNumberOfNewVariables << std::endl;
01108 outStr << "iNumNonlinearNonz = " << iNumNonlinearNonz << std::endl;
01109 outStr << "piObjSense = " << "NULL" << std::endl ;
01110 outStr << "pachConType = " << "NULL" << std::endl ;
01111 outStr << "pachVarType = " << "NULL" << std::endl ;
01112 int kl;
01113 outStr << "Here is the instruction list" << std::endl;
01114 for(kl = 0; kl < iInstListLength; kl++)
01115 {
01116 outStr << "instruction list num " << paiInsList[ kl] << endl;
01117 }
01118 outStr << "Number of terms in instruction list " << iInstListLength << std::endl;
01119 outStr << "Here are the constraint indices " << std::endl;
01120 for(kl = 0; kl < iNumberOfNonlinearConstraints; kl++)
01121 {
01122 outStr << "con idx " << paiNonlinearConIndex[ kl] << endl;
01123 }
01124 outStr << "Here come the nonlinear nonzeros " << std::endl;
01125 for(kl = 0; kl < iNumNonlinearNonz; kl++)
01126 {
01127 outStr << "nonz value = " << padNonlinearNonz[ kl] << endl;
01128 }
01129 outStr << "padVarval = " << "NULL" << std::endl ;
01130 for(kl = 0; kl < iNumberOfNonlinearObjectives; kl++)
01131 {
01132 outStr << "obj inst begin = " << paiObjsBegin[ kl] << endl;
01133 }
01134 for(kl = 0; kl < iNumberOfNonlinearObjectives; kl++)
01135 {
01136 outStr << "obj inst list length = " << paiObjsLength[ kl] << endl;
01137 }
01138 for(kl = 0; kl < iNumberOfNonlinearConstraints; kl++)
01139 {
01140 outStr << "constraint inst begin = " << paiConsBegin[ kl] << endl;
01141 }
01142 for(kl = 0; kl < iNumberOfNonlinearConstraints; kl++)
01143 {
01144 outStr << "constraints inst list length = " << paiConsLength[ kl] << endl;
01145 }
01146 outStr << "padVarLowerBounds = " << "NULL" << std::endl ;
01147 outStr << "padUpperBounds = " << "NULL" << std::endl ;
01148 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
01149 #endif
01150 m_iLindoErrorCode = LSaddInstruct (pModel_, iNumberOfNonlinearConstraints,
01151 iNumberOfNonlinearObjectives, iNumberOfNewVariables, iNumNonlinearNonz,
01152 piObjSense, pachConType, pachVarType, paiInsList, iInstListLength, paiNonlinearConIndex,
01153 padNonlinearNonz, padVarval, paiObjsBegin, paiObjsLength, paiConsBegin,
01154 paiConsLength, padVarLowerBounds, padVarUpperBounds);
01155 lindoAPIErrorCheck("Error trying to call LSaddInstruct");
01156
01157
01158
01159 if( iNumberOfNonlinearConstraints > 0) delete[] paiConsBegin;
01160 if( iNumberOfNonlinearConstraints > 0) delete[] paiConsLength;
01161 if( iNumberOfNonlinearObjectives > 0) delete[] paiObjsBegin;
01162 if( iNumberOfNonlinearObjectives > 0) delete[] paiObjsLength;
01163 if( iNumberOfNonlinearConstraints > 0) delete[] paiNonlinearConIndex;
01164 if( iNumNonlinearNonz > 0) delete[] padNonlinearNonz;
01165 if( iInstListLength > 0) delete[] paiInsList;
01166 mapNewNumber.clear();
01167
01168 allExpTrees.clear();
01169
01170 insList.clear();
01171
01172 postFixVec.clear();
01173
01174 return true;
01175 }
01176 catch(const ErrorClass& eclass)
01177 {
01178 osresult->setGeneralMessage( eclass.errormsg);
01179 osresult->setGeneralStatusType( "error");
01180 osrl = osrlwriter->writeOSrL( osresult);
01181 throw ;
01182 }
01183 }
01184
01185
01186
01187 void LindoSolver::dataEchoCheck()
01188 {
01189 int i;
01190 std::ostringstream outStr;
01191
01192
01193 outStr << "This is problem: " << osinstance->getInstanceName() << endl;
01194 outStr << "The problem source is: " << osinstance->getInstanceSource() << endl;
01195 outStr << "The problem description is: " << osinstance->getInstanceDescription() << endl;
01196 outStr << "number of variables = " << osinstance->getVariableNumber() << endl;
01197 outStr << "number of Rows = " << osinstance->getConstraintNumber() << endl;
01198
01199
01200 if(osinstance->getVariableNumber() > 0)
01201 {
01202 for(i = 0; i < osinstance->getVariableNumber(); i++)
01203 {
01204 if(osinstance->getVariableNames() != NULL) outStr << "variable Names " << osinstance->getVariableNames()[ i] << endl;
01205 if(osinstance->getVariableTypes() != NULL) outStr << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
01206 if(osinstance->getVariableLowerBounds() != NULL) outStr << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
01207 if(osinstance->getVariableUpperBounds() != NULL) outStr << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
01208 }
01209 }
01210
01211
01212 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0)
01213 {
01214 if( osinstance->getObjectiveMaxOrMins()[0] == "min") outStr << "problem is a minimization" << endl;
01215 else outStr << "problem is a maximization" << endl;
01216 for(i = 0; i < osinstance->getVariableNumber(); i++)
01217 {
01218 outStr << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
01219 }
01220 }
01221
01222 if(osinstance->getConstraintNumber() > 0)
01223 {
01224 for(i = 0; i < osinstance->getConstraintNumber(); i++)
01225 {
01226 if(osinstance->getConstraintNames() != NULL) outStr << "row name = " << osinstance->getConstraintNames()[i] << endl;
01227 if(osinstance->getConstraintLowerBounds() != NULL) outStr << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
01228 if(osinstance->getConstraintUpperBounds() != NULL) outStr << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
01229 }
01230 }
01231
01232
01233 outStr << endl;
01234 outStr << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
01235 if(osinstance->getLinearConstraintCoefficientNumber() > 0)
01236 {
01237 for(i = 0; i <= osinstance->getVariableNumber(); i++)
01238 {
01239 outStr << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
01240 }
01241 outStr << endl;
01242 for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++)
01243 {
01244 outStr << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
01245 outStr << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
01246 }
01247 }
01248
01249 outStr << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
01250 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++)
01251 {
01252 outStr << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
01253 outStr << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
01254 outStr << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
01255 outStr << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
01256 }
01257 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
01258
01259 }
01260
01261 void LindoSolver::lindoAPIErrorCheck(std::string errormsg)
01262 {
01263 try
01264 {
01265 ostringstream outStr;
01266 std::string error = errormsg;
01267 char lindoerrormsg[LS_MAX_ERROR_MESSAGE_LENGTH];
01268 if(m_iLindoErrorCode != 0)
01269 {
01270 outStr << endl;
01271 error = "LINDO ERROR: "+ error;
01272 outStr << error << endl;
01273 outStr << "LINDO ERROR NUMBER: " << m_iLindoErrorCode << endl;
01274 if( pEnv_ != NULL) LSgetErrorMessage(pEnv_, m_iLindoErrorCode, lindoerrormsg);
01275 error = lindoerrormsg;
01276 outStr << "LINDO ERROR MESSAGE: " << error;
01277 outStr << endl;
01278 error = outStr.str();
01279 throw ErrorClass( error);
01280 }
01281 }
01282 catch(const ErrorClass& eclass)
01283 {
01284 throw ErrorClass( eclass.errormsg);
01285 }
01286 }
01287
01288
01289
01290
01291
01292