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
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
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
00099 nl2osil = new OSnl2osil( stub);
00100
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
00114
00115
00123 char *amplclient_options = NULL;
00124 char *agent_address = NULL;
00125 char *solver_option = NULL;
00126
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
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
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
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
00234
00235
00236
00237
00238 if(solver_option != NULL){
00239 num_procOption = strstr(solver_option, "num_proc");
00240 if (num_procOption != NULL){
00241
00242
00243
00244
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
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
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
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
00364 osagent = new OSSolverAgent( URL);
00365
00366 string::size_type iStringpos;
00367 iStringpos = osol.find("</osol");
00368
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
00391 std::string sResultFileName = "solutionResult.osrl";
00392 FileUtil *fileUtil;
00393 fileUtil = new FileUtil();
00394 fileUtil->writeFileFromString(sResultFileName, osrl);
00395 delete fileUtil;
00396
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
00404
00405
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
00430
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
00441
00442 }
00443
00444
00445
00446 write_sol( const_cast<char*>(sReport.c_str()), x, y , NULL);
00447
00448 delete osrlreader;
00449 osrlreader = NULL;
00450
00451
00452
00453
00454 }else{
00455
00456
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
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
00470 delete solverType;
00471
00472 solverType = NULL;
00473 }
00474 delete osrlwriter;
00475
00476 osrlwriter = NULL;
00477 delete nl2osil;
00478
00479 nl2osil = NULL;
00480 ASL_free(&asl);
00481 return 0;
00482 }