/home/coin/SVN-release/OS-2.0.0/OS/applications/amplClient/OSAmplClient.cpp

Go to the documentation of this file.
00001 
00040 #include "OSCoinSolver.h"
00041 #include "OSConfig.h"
00042 #include "OSnl2osil.h"
00043 #include "OSiLReader.h"
00044 #include "OSrLReader.h"
00045 #include "OSiLWriter.h"
00046 #include "OSrLWriter.h"
00047 #include "OSInstance.h"
00048 #include "OSResult.h"
00049 #ifdef COIN_HAS_LINDO    
00050 #include "OSLindoSolver.h"
00051 #endif 
00052 #ifdef COIN_HAS_IPOPT    
00053 #include "OSIpoptSolver.h"
00054 #endif  
00055 #ifdef COIN_HAS_BONMIN    
00056 #include "OSBonminSolver.h"
00057 #endif 
00058 #ifdef COIN_HAS_COUENNE    
00059 #include "OSCouenneSolver.h"
00060 #endif
00061 #include "OSFileUtil.h"
00062 #include "OSDefaultSolver.h"
00063 #include "OSSolverAgent.h"
00064 #include "OShL.h"
00065 #include "OSErrorClass.h"
00066 #include "CoinError.hpp"
00067 #include <sstream>
00068 
00069 #ifdef HAVE_CSTRING
00070 # include <cstring>
00071 #else
00072 # ifdef HAVE_STRING_H
00073 #  include <string.h>
00074 # else
00075 #  error "don't have header file for string"
00076 # endif
00077 #endif
00078 
00079 #include "CoinError.hpp"
00080 #include "CoinHelperFunctions.hpp"
00081 //AMPL includes must be last.
00082 #include <asl.h>
00083 using std::cerr;
00084 using std::cout;
00085 using std::endl;
00086 
00087 
00088 int main(int argc, char **argv)
00089 {
00090         WindowsErrorPopupBlocker();
00091         char *stub;
00092         // set AMPL structures
00093         ASL *asl;
00094         asl = ASL_alloc(ASL_read_fg);
00095     stub = argv[1];
00096         jac0dim((char*)stub, (fint)strlen(stub));
00097         OSnl2osil *nl2osil = NULL;
00098         //initialize object with stub -- the nl file
00099         nl2osil = new OSnl2osil( stub);
00100         // create an osinstance object
00101         OSInstance *osinstance;
00102         std::cout << " call nl2osil" << std::endl;
00103         try{
00104                 nl2osil->createOSInstance() ;
00105         }
00106         catch(const ErrorClass& eclass){
00107                 std::cout << eclass.errormsg << std::endl;
00108                 return 0;
00109         }
00110         std::cout << " return from  nl2osil" << std::endl;
00111         osinstance = nl2osil->osinstance;
00112         std::cout << " osinstance created" << std::endl;
00113         // turn the osinstance into osil 
00114         // not needed for a local solve
00115         // send an osinstance object in memory
00123         char *amplclient_options = NULL;
00124         char *agent_address = NULL;
00125         char *solver_option = NULL;
00126         // set solver type default to clp
00127         DefaultSolver *solverType  = NULL;      
00128         OSrLReader *osrlreader = NULL;
00129         OSrLWriter *osrlwriter;
00130         osrlwriter = new OSrLWriter();
00131         OSResult *osresult = NULL;
00132         std::string osrl = "";
00133         std::string sSolverName = "";
00134         // note that default solver is coin and default subSolver is Cbc
00135         std::string osol = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <osol xmlns=\"os.optimizationservices.org\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"os.optimizationservices.org http://www.optimizationservices.org/schemas/2.0/OSoL.xsd\"></osol>";
00136         
00137         char *num_procOption = NULL;
00138         char *num_processors = NULL;
00139         char *URL = NULL;
00140         char delims[] = " ";
00141         
00142         // get the solver set by AMPL
00143         amplclient_options = getenv("OSAmplClient_options");
00144         if( amplclient_options != NULL) cout << "HERE ARE THE AMPLCLIENT OPTIONS " <<   amplclient_options << endl;
00145         try{
00146                 if(amplclient_options == NULL ) throw ErrorClass( "a local solver was not specified in AMPL option");
00147                 else{
00148                         if( strstr(amplclient_options, "lindo") != NULL) {
00149                                 // we are requesting the Lindo solver
00150                                 bool bLindoIsPresent = false;
00151                                 #ifdef COIN_HAS_LINDO
00152                                 sSolverName = "lindo";
00153                                 bLindoIsPresent = true;
00154                                 solver_option = getenv("lindo_options");
00155                                 if(( solver_option == NULL) ||  strstr(solver_option, "service") == NULL)  solverType = new LindoSolver();
00156                                 #endif
00157                                 if(bLindoIsPresent == false) throw ErrorClass( "the Lindo solver requested is not present");
00158                         }
00159                         else{ 
00160                                 if( strstr(amplclient_options, "clp") != NULL){
00161                                         if( solver_option != NULL) cout << "HERE ARE THE Clp SOLVER OPTIONS " <<   solver_option << endl;
00162                                         sSolverName = "clp";
00163                                         solver_option = getenv("clp_options");
00164                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00165                                                 solverType = new CoinSolver();
00166                                                 solverType->sSolverName = "clp";
00167                                         }
00168                                 }
00169                                 else{
00170                                         if( strstr(amplclient_options, "cbc") != NULL){
00171                                                 sSolverName = "cbc";
00172                                                 solver_option = getenv("cbc_options");
00173                                                 if( solver_option != NULL) cout << "HERE ARE THE Cbc SOLVER OPTIONS " <<   solver_option << endl;
00174                                                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL)){
00175                                                         solverType = new CoinSolver();
00176                                                         solverType->sSolverName = "cbc";
00177                                                 }
00178                                         }
00179                                         else{
00180                                                 if( strstr(amplclient_options, "cplex") != NULL){
00181                                                         bool bCplexIsPresent = false;
00182                                                         #ifdef COIN_HAS_CPX
00183                                                                 bCplexIsPresent = true;
00184                                                                 sSolverName = "cplex";
00185                                                                 solver_option = getenv("cplex_options");
00186                                                                 if( solver_option != NULL) cout << "HERE ARE THE Cplex SOLVER OPTIONS " <<   solver_option << endl;
00187                                                                 if(  ( solver_option == NULL) ||  (strstr(solver_option, "service") == NULL)){
00188                                                                         solverType = new CoinSolver();
00189                                                                         solverType->sSolverName = "cplex";
00190                                                                 }
00191                                                         #endif
00192                                                                 if(bCplexIsPresent == false) throw ErrorClass( "the Cplex solver requested is not present");
00193                                                 }
00194                                                 else{
00195                                                         if( strstr(amplclient_options, "glpk") != NULL){
00196                                                                 bool bGlpkIsPresent = false;
00197                                                                 #ifdef COIN_HAS_GLPK
00198                                                                         bGlpkIsPresent = true;
00199                                                                         solverType = new CoinSolver();
00200                                                                         sSolverName = "glpk";
00201                                                                         solver_option = getenv("glpk_options");
00202                                                                         if( solver_option != NULL) cout << "HERE ARE THE Glpk SOLVER OPTIONS " <<   solver_option << endl;
00203                                                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL)){
00204                                                                                 solverType = new CoinSolver();
00205                                                                                 solverType->sSolverName = "glpk";
00206                                                                         }
00207                                                                 #endif
00208                                                                 if(bGlpkIsPresent == false) throw ErrorClass( "the Glpk solver requested is not present");
00209                                                         }
00210                                                         else{
00211                                                                 if( strstr(amplclient_options, "ipopt") != NULL){
00212                                                                         bool bIpoptIsPresent = false;
00213                                                                         #ifdef COIN_HAS_IPOPT
00214                                                                                 bIpoptIsPresent = true;
00215                                                                                 sSolverName = "ipopt";
00216                                                                                 solver_option = getenv("ipopt_options");
00217                                                                                 if( solver_option != NULL) cout << "HERE ARE THE Ipopt SOLVER OPTIONS " <<   solver_option << endl;
00218                                                                                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00219                                                                                         solverType = new IpoptSolver();
00220                                                                                         solverType->sSolverName = "ipopt";
00221                                                                                 }
00222                                                                         #endif
00223                                                                         if(bIpoptIsPresent == false) throw ErrorClass( "the Ipopt solver requested is not present");
00224                                                                 }
00225                                                                 else{
00226                                                                         if( strstr(amplclient_options, "symphony") != NULL){
00227                                                                                 bool bSymIsPresent = false;
00228                                                                                 #ifdef COIN_HAS_SYMPHONY
00229                                                                                         bSymIsPresent = true; 
00230                                                                                         sSolverName = "symphony";
00231                                                                                         solver_option = getenv("symphony_options");
00232                                                                                         if( solver_option != NULL) cout << "HERE ARE THE SYMPHONY SOLVER OPTIONS " <<   solver_option << endl;
00233                                                                                         // get the number of parallel parallel processors and insert into the osol
00234                                                                                         // tokenize the symphony_options string
00235                                                                                         // just test for now, make a subroutine later
00236 
00237                                                                                         //
00238                                                                                         if(solver_option != NULL){
00239                                                                                                 num_procOption = strstr(solver_option, "num_proc");
00240                                                                                                 if (num_procOption != NULL){
00241                                                                                                         // kipp -- probably should make this a subroutine in
00242                                                                                                         // case other solvers have options???
00243                                                                                                         // get the number of processors
00244                                                                                                         //move past the num_proc option name token
00245                                                                                                         num_procOption += 8;
00246                                                                                                         num_processors = strtok( num_procOption, delims );
00247                                                                                                         //
00248                                                                                                         string::size_type iStringpos;
00249                                                                                                         iStringpos = osol.find("</osol");
00250                                                                                                         std::string insertText = "<other name=\"num_proc\">";
00251                                                                                                         insertText +=  num_processors;
00252                                                                                                         insertText += "</other>";
00253                                                                                                         osol.insert(iStringpos, insertText);
00254 
00255                                                                                                 }
00256                                                                                         }
00257                                                                                         if(  ( solver_option == NULL) ||  (strstr(solver_option, "service") == NULL)){
00258                                                                                                 solverType = new CoinSolver();
00259                                                                                                 solverType->sSolverName = "symphony";
00260                                                                                         }
00261                                                                                 #endif
00262                                                                                 if(bSymIsPresent == false) throw ErrorClass( "the SYMPHONY solver requested is not present");
00263                                                                         }
00264                                                                         else{
00265                                                                                 if( strstr(amplclient_options, "dylp") != NULL){
00266                                                                                         bool bDyLPIsPresent = false;
00267                                                                                         #ifdef COIN_HAS_DYLP
00268                                                                                                 bDyLPIsPresent = true;
00269                                                                                                 sSolverName = "dylp";
00270                                                                                                 solver_option = getenv("dylp_options");
00271                                                                                                 if( solver_option != NULL) cout << "HERE ARE THE DyLP SOLVER OPTIONS " <<   solver_option << endl;
00272                                                                                                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00273                                                                                                         solverType = new CoinSolver();
00274                                                                                                         solverType->sSolverName = "dylp";
00275                                                                                                 }
00276                                                                                         #endif
00277                                                                                         if(bDyLPIsPresent == false) throw ErrorClass( "the DyLP solver requested is not present");
00278                                                                                 }                                               
00279                                                                                 else{
00280                                                                                         if( strstr(amplclient_options, "bonmin") != NULL ){
00281                                                                                                 bool bBonminIsPresent = false;
00282                                                                                                 #ifdef COIN_HAS_BONMIN
00283                                                                                                         bBonminIsPresent = true;
00284                                                                                                         sSolverName = "bonmin";
00285                                                                                                         solver_option = getenv("bonmin_options");
00286                                                                                                         if( solver_option != NULL) cout << "HERE ARE THE Bonmin SOLVER OPTIONS " <<   solver_option << endl;
00287                                                                                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00288                                                                                                                 solverType = new BonminSolver();
00289                                                                                                                 solverType->sSolverName = "bonmin";
00290                                                                                                         }
00291                                                                                                 #endif
00292                                                                                                 if(bBonminIsPresent == false) throw ErrorClass( "the Bonmin solver requested is not present");                                                                                          
00293                                                                                         }
00294                                                                                         else{
00295                                                                                                 if( strstr(amplclient_options, "couenne") != NULL){
00296                                                                                                         bool bCouenneIsPresent = false;
00297                                                                                                         #ifdef COIN_HAS_COUENNE
00298                                                                                                         bCouenneIsPresent = true;
00299                                                                                                         sSolverName = "couenne";
00300                                                                                                         solver_option = getenv("couenne_options");
00301                                                                                                         if( solver_option != NULL) cout << "HERE ARE THE Couenne SOLVER OPTIONS " <<   solver_option << endl;
00302                                                                                                         if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL) ){
00303                                                                                                                 solverType = new CouenneSolver();
00304                                                                                                                 solverType->sSolverName = "counenne";
00305                                                                                                         }
00306                                                                                                         #endif
00307                                                                                                                 if(bCouenneIsPresent == false) throw ErrorClass( "the Couenne solver requested is not present");        
00308                                                                                                 }
00309                                                                                                 else{
00310                                                                                                         throw ErrorClass( "a supported solver has not been selected");
00311                                                                                                 }
00312                                                                                         }
00313                                                                                 }
00314                                                                         }       
00315                                                                 } 
00316                                                         }
00317                                                 }
00318                                         } 
00319                                 }
00320                         }
00321                 }
00322                 // do a local solve
00323                 if( ( solver_option == NULL) || (strstr(solver_option, "service") == NULL)  ){
00324                         solverType->osol = osol;
00325                         std::cout << osol << std::endl;
00326                         OSiLWriter osilwriter;
00327                         std::cout << "WRITE THE INSTANCE" << std::endl;
00328                         std::cout << osilwriter.writeOSiL( osinstance) << std::endl;
00329                         std::cout << "DONE WRITE THE INSTANCE" << std::endl;
00330 
00331                         solverType->osinstance = osinstance;
00332                         solverType->buildSolverInstance();
00333                         solverType->solve();
00334                         osrl = solverType->osrl ;
00335                         //std::cout << osrl << std::endl;
00336                 }
00337         }
00338         catch(const ErrorClass& eclass){
00339                 osresult = new OSResult();      
00340                 osresult->setGeneralMessage( eclass.errormsg);
00341                 osresult->setGeneralStatusType( "error");
00342                 osrl = osrlwriter->writeOSrL( osresult);
00343                 std::cout  << osrl << std::endl;
00344                 osrl = " ";
00345                 write_sol(const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00346                 delete osresult;
00347                 return 0;
00348         }
00349         try{
00350                 // do the following for a remote solve
00351                 if( (solver_option != NULL) && (strstr(solver_option, "service") != NULL)){
00352                         OSSolverAgent* osagent = NULL;
00353                         OSiLWriter *osilwriter = NULL;
00354                         osilwriter = new OSiLWriter();
00355                         std::string  osil = osilwriter->writeOSiL( osinstance);
00357                 
00358                         agent_address = strstr(solver_option, "service");
00359                         agent_address += 7;
00360                         URL = strtok( agent_address, delims );
00361                         std::string sURL = URL;
00363                         // we should be pointing to the start of the address
00364                         osagent = new OSSolverAgent( URL);
00365                         // if a solver option was specified put that in
00366                         string::size_type iStringpos;
00367                         iStringpos = osol.find("</osol");
00368                         //std::cout <<  solverType->sSolverName << std::endl;
00369                         std::string solverInput = "<general><solverToInvoke>" + sSolverName 
00370                                  + "</solverToInvoke></general>";
00371                         osol.insert(iStringpos, solverInput);
00372                         cout << "Place remote synchronous call: " + sURL << endl << endl << endl;
00373                         cout << osol << endl;
00374                         osrl = osagent->solve(osil, osol);
00375                         if (osrl.size() == 0) throw ErrorClass("Nothing was returned from the server, please check service address");
00376                         delete osilwriter;
00377                         delete osagent; 
00378                 } 
00379         }
00380         catch(const ErrorClass& eclass){
00381                 osresult = new OSResult();
00382                 osresult->setGeneralMessage( eclass.errormsg);
00383                 osresult->setGeneralStatusType( "error");
00384                 osrl = osrlwriter->writeOSrL( osresult);        
00385                 write_sol(const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00386                 delete osresult;
00387                 return 0;
00388         }
00389         try{ 
00390                 //need_nl = 0;
00391                 std::string sResultFileName = "solutionResult.osrl";
00392                 FileUtil *fileUtil;
00393                 fileUtil = new FileUtil();
00394                 fileUtil->writeFileFromString(sResultFileName, osrl);
00395                 delete fileUtil;
00396                 //cout << "WRITE THE SOLUTION BACK INTO AMPL" <<endl;
00397                 string::size_type pos1 = osrl.find( "error");
00398                 if(pos1 == std::string::npos){
00399                         std::string sReport = "model was solved";
00400                         std::cout << sReport << std::endl;
00401                         osrlreader = new OSrLReader();
00402                         osresult = osrlreader->readOSrL( osrl);
00403                         // do the following so output is not written twice
00404                         // see page 23 of hooking solver to AMPL
00405                         //need_nl = printf( sReport.c_str());
00406 
00407                         //
00408                         sReport = " ";
00409                         int i;
00410                         int vecSize;
00411                         double *x;
00412                         double *y;
00413                         int numVars = osresult->getVariableNumber();
00414                         int numCons = osresult->getConstraintNumber();
00415                         x = new double[ numVars];
00416                         y = new double[ numCons];
00417                         
00418                         std::vector<IndexValuePair*> primalValPair;
00419                         std::vector<IndexValuePair*> dualValPair;
00420                         dualValPair = osresult->getOptimalDualVariableValues( 0);
00421                         primalValPair = osresult->getOptimalPrimalVariableValues( 0);
00422                         
00423                         for(i = 0; i < numVars; i++){
00424                                 x[ 0] = 0.0;
00425                         }
00426                         vecSize = primalValPair.size();
00427                         for(i = 0; i < vecSize; i++){
00428                                 x[ primalValPair[i]->idx ] = primalValPair[i]->value;
00429                                 //std::cout << "index =  " <<   primalValPair[i]->idx  << std::endl;
00430                                 //std::cout << "value =  " <<   primalValPair[i]->value  << std::endl;
00431                         }
00432                         
00433                         
00434                         for(i = 0; i < numCons; i++){
00435                                 y[ 0] = 0.0;
00436                         }
00437                         vecSize = dualValPair.size();
00438                         for(i = 0; i < vecSize; i++){
00439                                 y[ dualValPair[i]->idx ] = dualValPair[i]->value;  
00440                                 //std::cout << "index =  " <<   primalValPair[i]->idx  << std::endl;
00441                                 //std::cout << "value =  " <<   primalValPair[i]->value  << std::endl;
00442                         }
00443                         
00444 
00445                         
00446                         write_sol(  const_cast<char*>(sReport.c_str()),  x, y , NULL);
00447                         
00448                         delete osrlreader;
00449                         osrlreader = NULL;
00450                         //delete[] x;
00451                         //x = NULL;
00452                         //delete y;
00453                         //y = NULL;
00454                 }else{
00455                         // do the following so output is not written twice
00456                         // see page 23 of hooking solver to AMPL
00457                         std::cout  << osrl << std::endl;
00458                         osrl = " ";
00459                         //
00460                         write_sol(  const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00461                         need_nl = 0;
00462                 }
00463                 //cout << "DONE WRITING THE SOLUTION BACK INTO AMPL" <<endl;
00464         }
00465         catch(const ErrorClass& eclass){
00466                 cout << "There was an error parsing the OSrL" << endl << eclass.errormsg << endl << endl;
00467         }
00468         if(  solverType != NULL ){
00469                 //cout << "TRY TO DELETE solverType" <<endl;
00470                 delete solverType;
00471                 //cout << "solverType JUST DELETED" <<endl;
00472                 solverType = NULL;
00473         }
00474         delete osrlwriter;
00475         //cout << "osrlwriter JUST DELETED" <<endl;
00476         osrlwriter = NULL;
00477         delete nl2osil;
00478         //cout << "nl2osil JUST DELETED" <<endl;
00479         nl2osil = NULL;
00480         ASL_free(&asl);
00481         return 0; 
00482 } // end main

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