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

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

Generated on Mon Aug 3 03:02:25 2009 by  doxygen 1.4.7