/home/coin/SVN-release/OS-2.4.1/OS/src/OSSolverInterfaces/OSLindoSolver.cpp

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

Generated on Thu Nov 10 03:05:51 2011 by  doxygen 1.4.7