/Users/kmartin/Documents/files/code/cpp/OScpp/COIN-OS/OS/src/OSSolverInterfaces/OSLindoSolver.cpp

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

Generated on Sat Mar 29 22:38:02 2008 by  doxygen 1.5.3