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 #endif
00178 }
00179
00180 if(osinstance->getVariableNumber() < 0)throw ErrorClass("Cannot have a negative number of decision variables");
00181 #ifndef NDEBUG
00182 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00183 "Start process variables !!!!!!!!!\n");
00184 #endif
00185 if( !processVariables() ) throw ErrorClass("failed processing variables");
00186 #ifndef NDEBUG
00187 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00188 "Finish process variables !!!!!!!!!\n");
00189 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00190 "Start process constraints !!!!!!!!!\n");
00191 #endif
00192 if( !processConstraints() ) throw ErrorClass("failed processing constraints");
00193 #ifndef NDEBUG
00194 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00195 "Finish process constraints !!!!!!!!!\n");
00196 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00197 "Start generateLindoModel() !!!!!!!!!\n");
00198 #endif
00199 if( !generateLindoModel()) throw ErrorClass("failed generating Lindo model");
00200 #ifndef NDEBUG
00201 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_trace,
00202 "Finish generateLindoModel() !!!!!!!!!\n");
00203 #endif
00204 if(m_iNumberNewSlacks > 0 && !addSlackVars()) throw ErrorClass("failed adding slack variables");
00205 if( (osinstance->getNumberOfNonlinearExpressions() > 0 || osinstance->getNumberOfQuadraticTerms() > 0)
00206 && !processNonlinearExpressions()) throw ErrorClass("failed adding nonlinear terms");
00207 this->bCallbuildSolverInstance = true ;
00208
00209 }
00210 catch(const ErrorClass& eclass)
00211 {
00212 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
00213 osresult->setGeneralMessage( eclass.errormsg);
00214 osresult->setGeneralStatusType( "error");
00215 osrl = osrlwriter->writeOSrL( osresult);
00216 throw ErrorClass( osrl) ;
00217 }
00218 }
00219
00220
00221
00222 void LindoSolver::setSolverOptions() throw (ErrorClass)
00223 {
00224 try
00225 {
00226
00227 }
00228 catch(const ErrorClass& eclass)
00229 {
00230 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
00231 osresult->setGeneralMessage( eclass.errormsg);
00232 osresult->setGeneralStatusType( "error");
00233 osrl = osrlwriter->writeOSrL( osresult);
00234 throw ErrorClass( osrl) ;
00235 }
00236 }
00237
00238
00239 void LindoSolver::solve()
00240 {
00241 if( this->bCallbuildSolverInstance == false) buildSolverInstance();
00242 try
00243 {
00244 double start = CoinCpuTime();
00245 if( optimize() != true) throw ErrorClass("problem optimizing model");
00246 cpuTime = CoinCpuTime() - start;
00247 osresult->setGeneralStatusType("normal");
00248 osresult->setTime(cpuTime);
00249 osrl = osrlwriter->writeOSrL( osresult);
00250 }
00251 catch(const ErrorClass& eclass)
00252 {
00253 osresult->setGeneralMessage( eclass.errormsg);
00254 osresult->setGeneralStatusType( "error");
00255 osrl = osrlwriter->writeOSrL( osresult);
00256
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
00416
00417
00418 m_mmcVarName[i] = &osinstance->getVariableNames()[ i][0];
00419 }
00420
00421 for(i = 0; i < osinstance->getVariableNumber() ; i++)
00422 {
00423 if( osinstance->getVariableTypes()[ i] == 'B')
00424 {
00425 m_mdVarUB[ i] = 1.0;
00426 }
00427 }
00428
00429 return true;
00430 }
00431 catch(const ErrorClass& eclass)
00432 {
00433 osresult->setGeneralMessage( eclass.errormsg);
00434 osresult->setGeneralStatusType( "error");
00435 osrl = osrlwriter->writeOSrL( osresult);
00436 throw ;
00437 }
00438 }
00439
00440
00441
00442 bool LindoSolver::generateLindoModel()
00443 {
00444 std::ostringstream outStr;
00445
00446
00447
00448
00449
00450
00451 char *MY_LICENSE_KEY = NULL;
00452 MY_LICENSE_KEY = getenv( "LINDOAPI_LICENSE_FILE");
00453 try
00454 {
00455 pEnv_ = LScreateEnv ( &m_iLindoErrorCode, MY_LICENSE_KEY);
00456 lindoAPIErrorCheck("There was an Error Creating the LINDO environment");
00457
00458 pModel_ = LScreateModel ( pEnv_, &m_iLindoErrorCode);
00459 lindoAPIErrorCheck("There was an Error Creating the LINDO Model");
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 int *colLength = NULL;
00479
00480 if(osinstance->getLinearConstraintCoefficientNumber() <= 0)
00481 {
00482 outStr.str("");
00483 outStr.clear();
00484 outStr << "LinearConstraintCoefficientNumber = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
00485 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
00486
00487 int iNumFakeNonz = 1;
00488
00489 int *paiArrayIdx;
00490 paiArrayIdx = new int[ 1];
00491 paiArrayIdx[ 0] = 0;
00492
00493 double *padValArray;
00494 padValArray = new double[ 1];
00495 padValArray[0] = 0;
00496
00497 int *paiArrayBeg;
00498 paiArrayBeg = new int[osinstance->getVariableNumber() + 1];
00499 paiArrayBeg[0] = 0;
00500 for(int kl = 1; kl <= osinstance->getVariableNumber(); kl++)
00501 {
00502 paiArrayBeg[kl] = 1;
00503 }
00504
00505
00506 m_iLindoErrorCode = LSloadLPData( pModel_, osinstance->getConstraintNumber(), osinstance->getVariableNumber(),
00507 ( osinstance->getObjectiveMaxOrMins()[0] == "min")?LS_MIN:LS_MAX ,
00508 osinstance->getObjectiveConstants()[0],
00509 osinstance->getDenseObjectiveCoefficients()[0],
00510 m_mdRhsValue, m_mcRowType,
00511 iNumFakeNonz,
00512 paiArrayBeg,
00513 colLength, padValArray,
00514 paiArrayIdx,
00515 m_mdVarLB, m_mdVarUB);
00516 lindoAPIErrorCheck("Error with LSloadLPData when the number of nonzeros is 0");
00517 }
00518 else
00519 {
00520 m_iLindoErrorCode = LSloadLPData( pModel_, osinstance->getConstraintNumber(), osinstance->getVariableNumber(),
00521 ( osinstance->getObjectiveMaxOrMins()[0] == "min")?LS_MIN:LS_MAX ,
00522 osinstance->getObjectiveConstants()[0], osinstance->getDenseObjectiveCoefficients()[0], m_mdRhsValue, m_mcRowType,
00523 osinstance->getLinearConstraintCoefficientNumber(),
00524 osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts,
00525 colLength, osinstance->getLinearConstraintCoefficientsInColumnMajor()->values,
00526 osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes,
00527 m_mdVarLB, m_mdVarUB);
00528 lindoAPIErrorCheck("Error with LSloadLPData when the number of nonzeros is greater than 0");
00529 }
00530 m_iLindoErrorCode = LSloadVarType(pModel_, m_mcVarType);
00531 lindoAPIErrorCheck("There was an error loading the Lindo Variable Types");
00532 return true;
00533 }
00534 catch( const ErrorClass& eclass)
00535 {
00536 osresult->setGeneralMessage( eclass.errormsg);
00537 osresult->setGeneralStatusType( "error");
00538 osrl = osrlwriter->writeOSrL( osresult);
00539 throw ;
00540 }
00541 }
00542
00543
00544 bool LindoSolver::optimize()
00545 {
00546 double *x, *y, *z;
00547 int solIdx = 0;
00548 ostringstream outStr;
00549 std::string *srcost;
00550 bool isNonlinear = false;
00551 double *drcost;
00552 int nSolStatus;
00553 std::string description = "";
00554
00555 if(osresult->setSolverInvoked( "LINDO Systems, Inc. Lindo API") != true)
00556 throw ErrorClass("OSResult error: setSolverInvoked");
00557 if(osresult->setServiceName( OSgetVersionInfo()) != true)
00558 throw ErrorClass("OSResult error: setServiceName");
00559
00560 if(osresult->setInstanceName( osinstance->getInstanceName()) != true)
00561 throw ErrorClass("OSResult error: setInstanceName");
00562
00563
00564
00565
00566 if(osinstance->getNumberOfNonlinearObjectives() > 0 || osinstance->getNumberOfNonlinearConstraints() > 0) isNonlinear = true;
00567 try
00568 {
00569 if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("LINDO NEEDS AN OBJECTIVE FUNCTION");
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 if( isNonlinear == true )
00583 {
00584
00585 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00586 "We are using the LINDO Global Optimizer\n");
00587 m_iLindoErrorCode = LSsolveGOP(pModel_, &nSolStatus) ;
00588 lindoAPIErrorCheck("There was an ERROR in the call to the Optimizer solver");
00589 LSgetInfo (pModel_, LS_IINFO_GOP_STATUS, &nSolStatus);
00590 }
00591 else
00592 {
00593 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00594 "We are using the LINDO LSsolveMIP Optimizer\n");
00595 m_iLindoErrorCode = LSsolveMIP( pModel_, &nSolStatus);
00596 lindoAPIErrorCheck("There was an ERROR in the call to the MIP solver");
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606 if(osresult->setVariableNumber( osinstance->getVariableNumber()) != true)
00607 throw ErrorClass("OSResult error: setVariableNumer");
00608 if(osresult->setObjectiveNumber( 1) != true)
00609 throw ErrorClass("OSResult error: setObjectiveNumber");
00610 if(osresult->setConstraintNumber( osinstance->getConstraintNumber()) != true)
00611 throw ErrorClass("OSResult error: setConstraintNumber");
00612 if(osresult->setSolutionNumber( 1) != true)
00613 throw ErrorClass("OSResult error: setSolutionNumer");
00614 outStr.str("");
00615 outStr.clear();
00616 outStr << "Solution Status = " << nSolStatus << endl;
00617 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
00618
00619 osresult->setGeneralStatusType("normal");
00620 osresult->setSolutionStatus(solIdx, "optimal", description);
00621 x = new double[ osinstance->getVariableNumber() + m_iNumberNewSlacks];
00622 srcost = new std::string[ osinstance->getVariableNumber() + m_iNumberNewSlacks];
00623 drcost = new double[ osinstance->getVariableNumber() + m_iNumberNewSlacks];
00624 for(int i = 0; i < osinstance->getVariableNumber() + m_iNumberNewSlacks; i++)
00625 {
00626 drcost[i] = 0.0;
00627 srcost[i] = "";
00628 }
00629 y = new double[ osinstance->getConstraintNumber() ];
00630 z = new double[1];
00631 switch( nSolStatus)
00632 {
00633 case 1:
00634
00635 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "case 1\n");
00636 case 8:
00637
00638 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "case 8\n");
00639 case 2:
00640 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "case 2\n");
00641
00642
00643 if( (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0 )
00644 || (isNonlinear == false) )
00645 {
00646 m_iLindoErrorCode = LSgetMIPPrimalSolution( pModel_, x);
00647 lindoAPIErrorCheck("Error trying to obtain primal solution with integer variables present");
00648 }
00649 else
00650 {
00651 m_iLindoErrorCode = LSgetPrimalSolution( pModel_, x);
00652 lindoAPIErrorCheck("Error trying to obtain primal solution with NO integer variables present");
00653 }
00654 osresult->setPrimalVariableValuesDense(solIdx, x);
00655
00656 if( (osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00657 || (isNonlinear == false) )
00658 {
00659 m_iLindoErrorCode = LSgetMIPDualSolution( pModel_, y);
00660 lindoAPIErrorCheck("Error trying to obtain dual solution with integer variables present");
00661 }
00662 else
00663 {
00664 m_iLindoErrorCode = LSgetDualSolution( pModel_, y);
00665 lindoAPIErrorCheck("Error trying to obtain dual solution with NO integer variables present");
00666 }
00667 osresult->setDualVariableValuesDense(solIdx, y);
00668
00669 if( ( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00670 || (isNonlinear == false ) )
00671 {
00672
00673
00674 }
00675 else
00676 {
00677 m_iLindoErrorCode = LSgetReducedCosts( pModel_, drcost);
00678 lindoAPIErrorCheck("Error trying to obtain the reduced costs with NO integer variables present");;
00679 }
00680
00681 {
00682 int numberOfOtherVariableResult = 1;
00683 int otherIdx = 0;
00684
00685 osresult->setNumberOfOtherVariableResults(solIdx, numberOfOtherVariableResult);
00686 for(int i = 0; i < osinstance->getVariableNumber() + m_iNumberNewSlacks; i++)
00687 {
00688 outStr << drcost[i];
00689 srcost[ i] = outStr.str();
00690 outStr.str("");
00691 }
00692 osresult->setAnOtherVariableResultDense(solIdx, otherIdx, "reduced costs", "", "the variable reduced costs", srcost);
00693
00694 if( ( osinstance->getNumberOfIntegerVariables() + osinstance->getNumberOfBinaryVariables() > 0)
00695 || (isNonlinear == false ) )
00696 {
00697 m_iLindoErrorCode = LSgetInfo( pModel_, LS_DINFO_MIP_OBJ, &z[0]);
00698 lindoAPIErrorCheck("Error trying to obtain optimal objective value with integer variables present");
00699 }
00700 else
00701 {
00702 LSgetInfo( pModel_, LS_DINFO_GOP_OBJ, &z[0]);
00703 lindoAPIErrorCheck("Error trying to obtain optimal objective value with NO integer variables present");
00704 }
00705 osresult->setObjectiveValuesDense(solIdx, z);
00706 }
00707 break;
00708 case 3:
00709 osresult->setSolutionStatus(solIdx, "infeasible", description);
00710 break;
00711 case 4:
00712 osresult->setSolutionStatus(solIdx, "unbounded", description);
00713 break;
00714 default:
00715 osresult->setSolutionStatus(solIdx, "other", description);
00716 }
00717
00718 delete[] x;
00719 delete[] y;
00720 delete[] z;
00721 delete[] srcost;
00722 delete[] drcost;
00723 return true;
00724 }
00725 catch(const ErrorClass& eclass)
00726 {
00727
00728 osresult->setGeneralMessage( eclass.errormsg);
00729 osresult->setGeneralStatusType( "error");
00730 osrl = osrlwriter->writeOSrL( osresult);
00731 throw ;
00732 }
00733 }
00734
00735
00736 bool LindoSolver::processQuadraticTerms()
00737 {
00738 int nQCnnz = osinstance->getNumberOfQuadraticTerms();
00739 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00740 "WE ARE PROCESSING QUADRATIC TERMS\n");
00741 try
00742 {
00743 if(nQCnnz <= 0)return false;
00744 std::map<std::string, double> mapQuadraticAdjustMap;
00745 std::map<std::string, double>::iterator mapPointer;
00746
00747 int i;
00748 int iVarOneIndex, iVarTwoIndex;
00749 int iRowIndex;
00750 std::string sKey;
00751 double dValue;
00752
00753 int iStringPostionOne, iStringPostionTwo;
00754
00755 int* paiQCrows = osinstance->getQuadraticTerms()->rowIndexes;
00756 int* paiQCcols1 = osinstance->getQuadraticTerms()->varOneIndexes;
00757 int* paiQCcols2 = osinstance->getQuadraticTerms()->varTwoIndexes;
00758 double* padQCcoef = osinstance->getQuadraticTerms()->coefficients;
00759 std::ostringstream ostrRow, ostr1, ostr2;
00760 std::string sIndexRow, sIndex1, sIndex2;
00761
00762 for ( i = 0; i < nQCnnz; i++)
00763 {
00764 iRowIndex = paiQCrows[i];
00765
00766 if (iRowIndex >= -1)
00767 {
00768 iVarOneIndex = (paiQCcols1[i] >= paiQCcols2[i])?paiQCcols2[i]:paiQCcols1[i];
00769 iVarTwoIndex = (paiQCcols1[i] <= paiQCcols2[i])?paiQCcols2[i]:paiQCcols1[i];
00770 ostrRow << iRowIndex;
00771 ostr2<<iVarTwoIndex;
00772 ostr1<<iVarOneIndex;
00773 sIndexRow = ostrRow.str();
00774 sIndex2 = ostr2.str();
00775 sIndex1 = ostr1.str();
00776
00777 ostrRow.str("");
00778 ostr2.str("");
00779 ostr1.str("");
00780
00781 sKey = sIndexRow + "," + sIndex1 + "," + sIndex2;
00782
00783 mapPointer = mapQuadraticAdjustMap.find(sKey);
00784 if (mapPointer != mapQuadraticAdjustMap.end())
00785 {
00786 dValue = mapPointer->second;
00787 dValue += padQCcoef[i];
00788 mapQuadraticAdjustMap[sKey] = dValue;
00789 }
00790 else
00791 {
00792 mapQuadraticAdjustMap[sKey] = padQCcoef[i];
00793 }
00794 }
00795 }
00796
00797 int iNumberOfQuadraticTerms = 0;
00798 for (mapPointer = mapQuadraticAdjustMap.begin(); mapPointer != mapQuadraticAdjustMap.end(); ++mapPointer)
00799 {
00800 sKey = mapPointer->first;
00801 dValue = mapPointer->second;
00802 iStringPostionOne = sKey.find_first_of(',');
00803 iStringPostionTwo = sKey.find_last_of(',');
00804
00805 iRowIndex = atoi(sKey.substr(0, iStringPostionOne).c_str());
00806 iVarOneIndex = atoi(sKey.substr(iStringPostionOne + 1, iStringPostionTwo).c_str());
00807 iVarTwoIndex = atoi(sKey.substr(iStringPostionTwo + 1).c_str());
00808
00809 if ( iVarOneIndex == iVarTwoIndex)
00810 {
00811 dValue *= 2;
00812 }
00813
00814 paiQCrows[iNumberOfQuadraticTerms] = iRowIndex;
00815 paiQCcols1[iNumberOfQuadraticTerms] = iVarOneIndex;
00816 paiQCcols2[iNumberOfQuadraticTerms] = iVarTwoIndex;
00817
00818 padQCcoef[iNumberOfQuadraticTerms] = dValue ;
00819 iNumberOfQuadraticTerms ++;
00820 }
00821
00822 if(!LSloadQCData(pModel_, nQCnnz, paiQCrows, paiQCcols1,
00823 paiQCcols2, padQCcoef)) return true;
00824 else return false;
00825 }
00826 catch(const ErrorClass& eclass)
00827 {
00828 osresult->setGeneralMessage( eclass.errormsg);
00829 osresult->setGeneralStatusType( "error");
00830 osrl = osrlwriter->writeOSrL( osresult);
00831 throw ;
00832 }
00833 }
00834
00835
00836
00837 bool LindoSolver::processNonlinearExpressions()
00838 {
00839 std::ostringstream outStr;
00840
00841 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info,
00842 "PROCESS NONLINEAR TERMS\n");
00843 osinstance->initializeNonLinearStructures( );
00844
00845 outStr.str("");
00846 outStr.clear();
00847 outStr << "The number of objectives with nonlinear terms is: "
00848 << osinstance->getNumberOfNonlinearObjectives() << endl;
00849 outStr << "The number of constraints with nonlinear terms is: "
00850 << osinstance->getNumberOfNonlinearConstraints() << endl << endl << endl;
00851 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
00852
00853
00854
00855 LINDO_OP_CODE_CONVERSION;
00861 std::map<double, int> mapNewNumber;
00862
00864 std::map<double, int>::iterator pos;
00865
00871 std::vector<int> insList;
00872
00873
00879 std::map<int, OSExpressionTree*> allExpTrees;
00880
00886 std::vector<OSnLNode*> postFixVec;
00887
00889 std::map<int, OSExpressionTree*>::iterator posTree;
00890
00900 int *piObjSense = NULL;
00901
00905 double *padVarLowerBounds = NULL;
00906
00910 double *padVarUpperBounds = NULL;
00911
00913 double *padVarval = NULL;
00914
00918 char *pachVarType = NULL;
00919
00922 char *pachConType = NULL;
00923
00925 int iNumNonlinearNonz = 0;
00926
00928 double *padNonlinearNonz = NULL;
00929
00931 int iNumberOfNonlinearConstraints = osinstance->getNumberOfNonlinearConstraints();
00932
00936 int *paiConsBegin = NULL;
00937 if(iNumberOfNonlinearConstraints > 0) paiConsBegin = new int[ iNumberOfNonlinearConstraints];
00938
00942 int *paiConsLength = NULL;
00943 if(iNumberOfNonlinearConstraints > 0) paiConsLength = new int[ iNumberOfNonlinearConstraints];
00944
00946 int iNumberOfNonlinearObjectives = osinstance->getNumberOfNonlinearObjectives();
00947
00951 int *paiObjsBegin = NULL;
00952 if(iNumberOfNonlinearObjectives > 0) paiObjsBegin = new int[ iNumberOfNonlinearObjectives];
00953
00957 int *paiObjsLength = NULL;
00958 if(iNumberOfNonlinearObjectives > 0) paiObjsLength = new int[ iNumberOfNonlinearObjectives];
00959
00960
00966 int iNumberOfNewVariables = 0;
00967
00969 int *paiInsList;
00970
00972 int iInstListLength = 0;
00973
00975 int *paiNonlinearConIndex = NULL;
00976 if(iNumberOfNonlinearConstraints > 0) paiNonlinearConIndex = new int[ iNumberOfNonlinearConstraints];
00977
00978
00979 try
00980 {
00981 int i;
00982
00983 int iCountObjs = 0;
00984 int iCountCons = 0;
00985
00986 allExpTrees = osinstance->getAllNonlinearExpressionTreesMod();
00987
00988 for(posTree = allExpTrees.begin(); posTree != allExpTrees.end(); ++posTree)
00989 {
00990 outStr.str("");
00991 outStr.clear();
00992 outStr << "HERE IS EXPRESSION TREE " << posTree->first << endl;
00993 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
00994
00995 postFixVec = posTree->second->m_treeRoot->getPostfixFromExpressionTree();
00996 int iVecSize = postFixVec.size();
00997 int iNodeID;
00998 if(iVecSize > 0)
00999 {
01000 for(i = 0; i < iVecSize; i++)
01001 {
01002 iNodeID = postFixVec[i]->inodeInt;
01003 switch (iNodeID)
01004 {
01005 case OS_SUM:
01006 insList.push_back( nlNodeIdxLindo[ OS_SUM] );
01007 insList.push_back( postFixVec[i]->inumberOfChildren);
01008 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "PUSH BACK A SUM\n");
01009 break;
01010 case OS_MAX:
01011 insList.push_back( nlNodeIdxLindo[ OS_MAX] );
01012 insList.push_back( postFixVec[i]->inumberOfChildren);
01013 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, "PUSH BACK A MAX\n");
01014 break;
01015 case OS_PRODUCT:
01016 throw ErrorClass("Error: OS_PRODUCT operator not supported by Lindo");
01017 break;
01018 case OS_NUMBER:
01019 OSnLNodeNumber *numNode;
01020 insList.push_back( EP_PUSH_NUM );
01021 numNode = (OSnLNodeNumber*)postFixVec[i];
01022 pos = mapNewNumber.find( numNode->value);
01023 if(pos == mapNewNumber.end() )
01024 {
01025 outStr.str("");
01026 outStr.clear();
01027 outStr << "FOUND A NEW NUMBER " << numNode->value << endl;
01028 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01029 insList.push_back( iNumNonlinearNonz);
01030 mapNewNumber[ numNode->value] = iNumNonlinearNonz++;
01031 }
01032 else insList.push_back( pos->second);
01033 break;
01034 case OS_VARIABLE:
01035 OSnLNodeVariable *varNode;
01036 insList.push_back( EP_PUSH_VAR );
01037 varNode = (OSnLNodeVariable*)postFixVec[i];
01038 insList.push_back( varNode->idx );
01039
01040
01041 if(varNode->coef != 1)
01042 {
01043
01044 insList.push_back( EP_PUSH_NUM );
01045 pos = mapNewNumber.find( varNode->coef);
01046 if(pos == mapNewNumber.end() )
01047 {
01048 outStr.str("");
01049 outStr.clear();
01050 outStr << "FOUND A NEW NUMBER " << varNode->coef << endl;
01051 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01052 insList.push_back( iNumNonlinearNonz);
01053 mapNewNumber[ varNode->coef] = iNumNonlinearNonz++;
01054 }
01055 else insList.push_back( pos->second);
01056 insList.push_back( EP_MULTIPLY);
01057 }
01058 break;
01059 default:
01060 insList.push_back( nlNodeIdxLindo[iNodeID] );
01061 break;
01062 }
01063 }
01064
01065 if(posTree->first < 0)
01066 {
01067
01068
01069 paiObjsBegin[ iCountObjs] = iInstListLength;
01070 paiObjsLength[ iCountObjs] = insList.size() - iInstListLength;
01071 iInstListLength = insList.size();
01072 iCountObjs++;
01073 }
01074 else
01075 {
01076
01077 paiConsBegin[ iCountCons] = iInstListLength;
01078 paiConsLength[ iCountCons] = insList.size() - iInstListLength;
01079 paiNonlinearConIndex[ iCountCons] = posTree->first;
01080 outStr.str("");
01081 outStr.clear();
01082 outStr << "CONSTRAINT ILIST LENGTH = " << iInstListLength << endl;
01083 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01084 iInstListLength = insList.size();
01085 iCountCons++;
01086 }
01087 }
01088 postFixVec.clear();
01089 }
01090
01091 padNonlinearNonz = new double[ iNumNonlinearNonz];
01092 outStr.str("");
01093 outStr.clear();
01094 for(pos = mapNewNumber.begin(); pos != mapNewNumber.end(); ++pos)
01095 {
01096 padNonlinearNonz[ pos->second] = pos->first;
01097 outStr << "INDEX = " << pos->second << " NUMBER = " << pos->first << endl;
01098 }
01099 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_info, outStr.str());
01100
01101 paiInsList = new int[ iInstListLength];
01102 copy(insList.begin(), insList.end(), paiInsList);
01103
01104
01105
01106 int nLinearz, nAutoDeriv;
01107
01108
01109 nLinearz = 1;
01110 m_iLindoErrorCode = LSsetModelIntParameter (pModel_,
01111 LS_IPARAM_NLP_LINEARZ, nLinearz);
01112 lindoAPIErrorCheck("Error trying to set the LS_IPARAM_NLP_LINEARZ parameter");
01113
01114
01115
01116
01117 nAutoDeriv = 1;
01118 m_iLindoErrorCode = LSsetModelIntParameter (pModel_,
01119 LS_IPARAM_NLP_AUTODERIV, nAutoDeriv);
01120 lindoAPIErrorCheck("Error trying to set the LS_IPARAM_NLP_AUTODERIV parameter");
01121 #ifndef NDEBUG
01122 outStr.str("");
01123 outStr.clear();
01124 outStr << "iNumberOfNonlinearConstraints= " << iNumberOfNonlinearConstraints << std::endl;
01125 outStr << "iNumberOfNonlinearObjectives= " << iNumberOfNonlinearObjectives << std::endl;
01126 outStr << "iNumberOfNewVariables = " << iNumberOfNewVariables << std::endl;
01127 outStr << "iNumNonlinearNonz = " << iNumNonlinearNonz << std::endl;
01128 outStr << "piObjSense = " << "NULL" << std::endl ;
01129 outStr << "pachConType = " << "NULL" << std::endl ;
01130 outStr << "pachVarType = " << "NULL" << std::endl ;
01131 int kl;
01132 outStr << "Here is the instruction list" << std::endl;
01133 for(kl = 0; kl < iInstListLength; kl++)
01134 {
01135 outStr << "instruction list num " << paiInsList[ kl] << endl;
01136 }
01137 outStr << "Number of terms in instruction list " << iInstListLength << std::endl;
01138 outStr << "Here are the constraint indices " << std::endl;
01139 for(kl = 0; kl < iNumberOfNonlinearConstraints; kl++)
01140 {
01141 outStr << "con idx " << paiNonlinearConIndex[ kl] << endl;
01142 }
01143 outStr << "Here come the nonlinear nonzeros " << std::endl;
01144 for(kl = 0; kl < iNumNonlinearNonz; kl++)
01145 {
01146 outStr << "nonz value = " << padNonlinearNonz[ kl] << endl;
01147 }
01148 outStr << "padVarval = " << "NULL" << std::endl ;
01149 for(kl = 0; kl < iNumberOfNonlinearObjectives; kl++)
01150 {
01151 outStr << "obj inst begin = " << paiObjsBegin[ kl] << endl;
01152 }
01153 for(kl = 0; kl < iNumberOfNonlinearObjectives; kl++)
01154 {
01155 outStr << "obj inst list length = " << paiObjsLength[ kl] << endl;
01156 }
01157 for(kl = 0; kl < iNumberOfNonlinearConstraints; kl++)
01158 {
01159 outStr << "constraint inst begin = " << paiConsBegin[ kl] << endl;
01160 }
01161 for(kl = 0; kl < iNumberOfNonlinearConstraints; kl++)
01162 {
01163 outStr << "constraints inst list length = " << paiConsLength[ kl] << endl;
01164 }
01165 outStr << "padVarLowerBounds = " << "NULL" << std::endl ;
01166 outStr << "padUpperBounds = " << "NULL" << std::endl ;
01167 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
01168 #endif
01169 m_iLindoErrorCode = LSaddInstruct (pModel_, iNumberOfNonlinearConstraints,
01170 iNumberOfNonlinearObjectives, iNumberOfNewVariables, iNumNonlinearNonz,
01171 piObjSense, pachConType, pachVarType, paiInsList, iInstListLength, paiNonlinearConIndex,
01172 padNonlinearNonz, padVarval, paiObjsBegin, paiObjsLength, paiConsBegin,
01173 paiConsLength, padVarLowerBounds, padVarUpperBounds);
01174 lindoAPIErrorCheck("Error trying to call LSaddInstruct");
01175
01176
01177
01178 if( iNumberOfNonlinearConstraints > 0) delete[] paiConsBegin;
01179 if( iNumberOfNonlinearConstraints > 0) delete[] paiConsLength;
01180 if( iNumberOfNonlinearObjectives > 0) delete[] paiObjsBegin;
01181 if( iNumberOfNonlinearObjectives > 0) delete[] paiObjsLength;
01182 if( iNumberOfNonlinearConstraints > 0) delete[] paiNonlinearConIndex;
01183 if( iNumNonlinearNonz > 0) delete[] padNonlinearNonz;
01184 if( iInstListLength > 0) delete[] paiInsList;
01185 mapNewNumber.clear();
01186
01187 allExpTrees.clear();
01188
01189 insList.clear();
01190
01191 postFixVec.clear();
01192
01193 return true;
01194 }
01195 catch(const ErrorClass& eclass)
01196 {
01197 osresult->setGeneralMessage( eclass.errormsg);
01198 osresult->setGeneralStatusType( "error");
01199 osrl = osrlwriter->writeOSrL( osresult);
01200 throw ;
01201 }
01202 }
01203
01204
01205
01206 void LindoSolver::dataEchoCheck()
01207 {
01208 int i;
01209 std::ostringstream outStr;
01210
01211
01212 outStr << "This is problem: " << osinstance->getInstanceName() << endl;
01213 outStr << "The problem source is: " << osinstance->getInstanceSource() << endl;
01214 outStr << "The problem description is: " << osinstance->getInstanceDescription() << endl;
01215 outStr << "number of variables = " << osinstance->getVariableNumber() << endl;
01216 outStr << "number of Rows = " << osinstance->getConstraintNumber() << endl;
01217
01218
01219 if(osinstance->getVariableNumber() > 0)
01220 {
01221 for(i = 0; i < osinstance->getVariableNumber(); i++)
01222 {
01223 if(osinstance->getVariableNames() != NULL) outStr << "variable Names " << osinstance->getVariableNames()[ i] << endl;
01224 if(osinstance->getVariableTypes() != NULL) outStr << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
01225 if(osinstance->getVariableLowerBounds() != NULL) outStr << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
01226 if(osinstance->getVariableUpperBounds() != NULL) outStr << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
01227 }
01228 }
01229
01230
01231 if(osinstance->getVariableNumber() > 0 || osinstance->instanceData->objectives->obj != NULL || osinstance->instanceData->objectives->numberOfObjectives > 0)
01232 {
01233 if( osinstance->getObjectiveMaxOrMins()[0] == "min") outStr << "problem is a minimization" << endl;
01234 else outStr << "problem is a maximization" << endl;
01235 for(i = 0; i < osinstance->getVariableNumber(); i++)
01236 {
01237 outStr << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
01238 }
01239 }
01240
01241 if(osinstance->getConstraintNumber() > 0)
01242 {
01243 for(i = 0; i < osinstance->getConstraintNumber(); i++)
01244 {
01245 if(osinstance->getConstraintNames() != NULL) outStr << "row name = " << osinstance->getConstraintNames()[i] << endl;
01246 if(osinstance->getConstraintLowerBounds() != NULL) outStr << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
01247 if(osinstance->getConstraintUpperBounds() != NULL) outStr << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
01248 }
01249 }
01250
01251
01252 outStr << endl;
01253 outStr << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
01254 if(osinstance->getLinearConstraintCoefficientNumber() > 0)
01255 {
01256 for(i = 0; i <= osinstance->getVariableNumber(); i++)
01257 {
01258 outStr << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
01259 }
01260 outStr << endl;
01261 for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++)
01262 {
01263 outStr << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
01264 outStr << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
01265 }
01266 }
01267
01268 outStr << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
01269 for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++)
01270 {
01271 outStr << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
01272 outStr << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
01273 outStr << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
01274 outStr << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
01275 }
01276 osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, outStr.str());
01277
01278 }
01279
01280 void LindoSolver::lindoAPIErrorCheck(std::string errormsg)
01281 {
01282 try
01283 {
01284 ostringstream outStr;
01285 std::string error = errormsg;
01286 char lindoerrormsg[LS_MAX_ERROR_MESSAGE_LENGTH];
01287 if(m_iLindoErrorCode != 0)
01288 {
01289 outStr << endl;
01290 error = "LINDO ERROR: "+ error;
01291 outStr << error << endl;
01292 outStr << "LINDO ERROR NUMBER: " << m_iLindoErrorCode << endl;
01293 if( pEnv_ != NULL) LSgetErrorMessage(pEnv_, m_iLindoErrorCode, lindoerrormsg);
01294 error = lindoerrormsg;
01295 outStr << "LINDO ERROR MESSAGE: " << error;
01296 outStr << endl;
01297 error = outStr.str();
01298 throw ErrorClass( error);
01299 }
01300 }
01301 catch(const ErrorClass& eclass)
01302 {
01303 throw ErrorClass( eclass.errormsg);
01304 }
01305 }
01306
01307
01308
01309
01310
01311