00001
00065 #include "OSCoinSolver.h"
00066 #include "OSConfig.h"
00067 #include "OSnl2osil.h"
00068 #include "OSiLReader.h"
00069 #include "OSrLReader.h"
00070 #include "OSiLWriter.h"
00071 #include "OSrLWriter.h"
00072 #include "OSInstance.h"
00073 #include "OSResult.h"
00074 #include "OSOption.h"
00075 #include "OSoLReader.h"
00076 #include "OSoLWriter.h"
00077 #include "OSCommandLine.h"
00078 #include "OSCommandLineReader.h"
00079 #include "OSServiceMethods.h"
00080
00081 #ifdef COIN_HAS_LINDO
00082 # include "OSLindoSolver.h"
00083 #endif
00084
00085 #ifdef COIN_HAS_IPOPT
00086 # include "OSIpoptSolver.h"
00087 #endif
00088
00089 #ifdef COIN_HAS_BONMIN
00090 # include "OSBonminSolver.h"
00091 #endif
00092
00093 #ifdef COIN_HAS_COUENNE
00094 # include "OSCouenneSolver.h"
00095 #endif
00096
00097 #include "OSFileUtil.h"
00098 #include "OSDefaultSolver.h"
00099 #include "OSSolverAgent.h"
00100 #include "OShL.h"
00101 #include "OSErrorClass.h"
00102 #include "CoinError.hpp"
00103 #include "OSOption.h"
00104
00105 #include "OSRunSolver.h"
00106 #include <sstream>
00107
00108 #ifdef HAVE_CSTRING
00109 # include <cstring>
00110 #else
00111 # ifdef HAVE_STRING_H
00112 # include <string.h>
00113 # else
00114 # error "don't have header file for string"
00115 # endif
00116 #endif
00117
00118 #include "CoinError.hpp"
00119 #include "CoinHelperFunctions.hpp"
00120
00121
00122 #include <iostream>
00123
00124
00125 #include <asl.h>
00126
00127
00128
00129
00130
00131 using std::cerr;
00132 using std::cout;
00133 using std::endl;
00134 using std::ostringstream;
00135
00136 std::string OSAmplClientVersionInfo();
00137 std::string get_AmplClient_help();
00138 bool callServiceMethod(OSCommandLine* oscommandline);
00139
00140 int main(int argc, char **argv)
00141 {
00142 WindowsErrorPopupBlocker();
00143 char *stub;
00144
00145 ASL *asl;
00146 asl = ASL_alloc(ASL_read_fg);
00147 stub = argv[1];
00148 jac0dim((char*)stub, (fint)strlen(stub));
00149 OSnl2osil *nl2osil = NULL;
00150
00151 std::ostringstream outStr;
00152 std::cout << OSAmplClientVersionInfo();
00153 std::string osss;
00154
00155 outStr << stub << " " << getenv("OSAmplClient_options");
00156 osss = outStr.str();
00157
00158 #ifdef DEBUG_AMPL_CLIENT
00159 std::cout << "Input String = " << osss << std::endl;
00160 #endif
00161
00162 FileUtil *fileUtil = NULL;
00163 OSCommandLine *oscommandline;
00164 oscommandline = new OSCommandLine();
00165 OSCommandLineReader *clreader;
00166 clreader = new OSCommandLineReader();
00167
00168
00169 try
00170 {
00171 oscommandline = clreader->readCommandLine(osss);
00172 if (oscommandline->serviceMethod == "")
00173 oscommandline->serviceMethod = "solve";
00174 oscommandline->convertSolverNametoLowerCase();
00175
00176 }
00177 catch (const ErrorClass& eclass)
00178 {
00179 OSResult *osresult = NULL;
00180 osresult = new OSResult();
00181 osresult->setGeneralMessage(eclass.errormsg);
00182 osresult->setGeneralStatusType("error");
00183 OSrLWriter *osrlwriter = NULL;
00184 osrlwriter = new OSrLWriter();
00185 std::string osrl = osrlwriter->writeOSrL(osresult);
00186 if (oscommandline->osrlFile != "")
00187 {
00188 fileUtil->writeFileFromString(oscommandline->osrlFile, osrl);
00189 if (oscommandline->browser != "")
00190 {
00191 std::string str = oscommandline->browser + " "
00192 + oscommandline->osrlFile;
00193 const char *ch = &str[0];
00194 std::system(ch);
00195 }
00196 }
00197 else
00198 {
00199 std::cout << osrl << std::endl;
00200 }
00201
00202 delete osresult;
00203 osresult = NULL;
00204 delete osrlwriter;
00205 osrlwriter = NULL;
00206 delete fileUtil;
00207 fileUtil = NULL;
00208 delete oscommandline;
00209 oscommandline = NULL;
00210 delete clreader;
00211 clreader = NULL;
00212 return 1;
00213 }
00214
00215 #ifdef DEBUG_AMPL_CLIENT
00216 std::cout << oscommandline->list_options() << std::endl;
00217 #endif
00218
00219
00220 if (oscommandline->quit || oscommandline->invokeHelp || oscommandline->writeVersion || oscommandline->listOptions)
00221 {
00222 if (oscommandline->invokeHelp)
00223 std::cout << std::endl << std::endl << get_AmplClient_help() << std::endl;
00224 if (oscommandline->listOptions)
00225 std::cout << std::endl << std::endl << oscommandline->list_options() << std::endl;
00226 delete oscommandline;
00227 oscommandline = NULL;
00228 return 0;
00229 }
00230
00231
00232 bool result = callServiceMethod(oscommandline);
00233 if (result == true)
00234 return 0;
00235 else
00236 return 1;
00237 }
00238
00239 bool callServiceMethod(OSCommandLine* oscommandline)
00240 {
00241 FileUtil *fileUtil = new FileUtil();
00242 try
00243 {
00244 bool result;
00245 OSServiceMethods *osservicemethods;
00246 osservicemethods = new OSServiceMethods(oscommandline);
00247
00248 if (oscommandline->printModel)
00249 oscommandline->osinstance->printModel();
00250 if (oscommandline->printRowNumberAsString != "")
00251 oscommandline->osinstance->printModel(atoi((oscommandline->printRowNumberAsString).c_str()));
00252
00253 result = osservicemethods->executeServiceMethod(oscommandline);
00254
00255
00256 if (result == false)
00257 throw ErrorClass(osservicemethods->resultString);
00258 else
00259 {
00260 if (oscommandline->serviceMethod == "getJobID")
00261 {
00262 std::cout << "The job ID generated by the system is:" << std::endl << std::endl;
00263 std::cout << osservicemethods->resultString << std::endl << std::endl;
00264 std::cout << "Be sure to make a record of this job ID for later." << std::endl;
00265 std::cout << "You will need it to retrieve the job or inquire into its status." << std::endl;
00266 }
00267 else if (oscommandline->serviceMethod == "solve" || oscommandline->serviceMethod == "retrieve")
00268 {
00269 if (oscommandline->osrlFile != "")
00270 {
00271 fileUtil->writeFileFromString(oscommandline->osrlFile, osservicemethods->resultString);
00272 if (oscommandline->browser != "")
00273 {
00274 std::string str = oscommandline->browser + " "
00275 + oscommandline->osrlFile;
00276 const char *ch = &str[0];
00277 std::system(ch);
00278 }
00279 std::cout << "\nSolve command executed. Please see " << oscommandline->osrlFile << " for results." << std::endl;
00280 }
00281 else
00282 {
00283 std::cout << osservicemethods->resultString << std::endl;
00284 }
00285 }
00286 else if (oscommandline->serviceMethod == "kill" || oscommandline->serviceMethod == "knock")
00287 {
00288 if (oscommandline->osplOutputFile != "")
00289 {
00290 fileUtil->writeFileFromString(oscommandline->osplOutputFile, osservicemethods->resultString);
00291 }
00292 else
00293 {
00294 std::cout << osservicemethods->resultString << std::endl;
00295 }
00296 }
00297 }
00298 return 0;
00299 }
00300 catch (const ErrorClass& eclass)
00301 {
00302 OSResult *osresult = NULL;
00303 OSrLWriter *osrlwriter = NULL;
00304 osrlwriter = new OSrLWriter();
00305 osresult = new OSResult();
00306 osresult->setGeneralMessage(eclass.errormsg);
00307 osresult->setGeneralStatusType("error");
00308 std::string osrl = osrlwriter->writeOSrL(osresult);
00309 if (oscommandline->osrlFile != "")
00310 {
00311 fileUtil->writeFileFromString(oscommandline->osrlFile, osrl);
00312 if (oscommandline->browser != "")
00313 {
00314 std::string str = oscommandline->browser + " "
00315 + oscommandline->osrlFile;
00316 const char *ch = &str[0];
00317 std::system(ch);
00318 }
00319 }
00320 else
00321 {
00322 std::cout << osrl << std::endl;
00323 }
00324
00325 delete osresult;
00326 osresult = NULL;
00327 delete osrlwriter;
00328 osrlwriter = NULL;
00329
00330 delete oscommandline;
00331 oscommandline = NULL;
00332 delete fileUtil;
00333 fileUtil = NULL;
00334 return 1;
00335 }
00336 }
00337
00338 std::string get_AmplClient_help()
00339 {
00340
00341 std::ostringstream helpMsg;
00342
00343 helpMsg << "************************* HELP *************************"
00344 << endl << endl;
00345 helpMsg
00346 << "In this HELP file we assume that the solve service method is used and "
00347 << endl;
00348 helpMsg
00349 << "that we are solving problems locally, that is the solver is on the "
00350 << endl;
00351 helpMsg
00352 << "machine running this OSSolverService. See Section 10.3 of the User\'s "
00353 << endl;
00354 helpMsg
00355 << "Manual for other service methods or calling a server remotely. "
00356 << endl;
00357 helpMsg << "The OSSolverService takes the parameters listed below. "
00358 << endl;
00359 helpMsg
00360 << "The order of the parameters is irrelevant. Not all the parameters "
00361 << endl;
00362 helpMsg << "are required. However, the location of an instance file is "
00363 << endl;
00364 helpMsg
00365 << "required when using the solve service method. The location of the "
00366 << endl;
00367 helpMsg << "instance file is specified using the osil option. " << endl;
00368
00369 helpMsg << endl;
00370
00371 helpMsg
00372 << "-osil xxx.osil this is the name of the file that contains the "
00373 << endl;
00374 helpMsg << "optimization instance in OSiL format. This option may be "
00375 << endl;
00376 helpMsg << "specified in the OSoL solver options file. " << endl;
00377
00378 helpMsg << endl;
00379
00380 helpMsg
00381 << "-osol xxx.osol this is the name of the file that contains the solver options. "
00382 << endl;
00383 helpMsg << "It is not necessary to specify this option. " << endl;
00384
00385 helpMsg << endl;
00386
00387 helpMsg
00388 << "-osrl xxx.osrl this is the name of the file to which the solver solution is written. "
00389 << endl;
00390 helpMsg
00391 << "It is not necessary to specify this option. If this option is not specified, "
00392 << endl;
00393 helpMsg << "the result will be printed to standard out. " << endl;
00394
00395 helpMsg << endl;
00396
00397 helpMsg
00398 << "-osplInput xxx.ospl this is the name of an input file in the OS Process"
00399 << endl;
00400 helpMsg << " Language (OSpL), this is used as input to the knock method."
00401 << endl;
00402
00403 helpMsg << endl;
00404
00405 helpMsg
00406 << "-osplOutput xxx.ospl this is the name of an output file in the OS Process"
00407 << endl;
00408 helpMsg
00409 << "Language (OSpL), this the output string from the knock and kill methods."
00410 << endl;
00411
00412 helpMsg << endl;
00413
00414 helpMsg << "-serviceLocation url is the URL of the solver service. "
00415 << endl;
00416 helpMsg
00417 << "This is not required, and if not specified it is assumed that "
00418 << endl;
00419 helpMsg << "the problem is solved locally. " << endl;
00420
00421 helpMsg << endl;
00422
00423 helpMsg
00424 << "-serviceMethod methodName this is the method on the solver service to be invoked. "
00425 << endl;
00426 helpMsg
00427 << "The options are solve, send, kill, knock, getJobID, and retrieve. "
00428 << endl;
00429 helpMsg
00430 << "This option is not required, and the default value is solve. "
00431 << endl;
00432
00433 helpMsg << endl;
00434
00435 helpMsg
00436 << "-mps xxx.mps this is the name of the mps file if the problem instance "
00437 << endl;
00438 helpMsg
00439 << "is in mps format. The default file format is OSiL so this option is not required. "
00440 << endl;
00441
00442 helpMsg << endl;
00443
00444 helpMsg
00445 << "-nl xxx.nl this is the name of the AMPL nl file if the problem "
00446 << endl;
00447 helpMsg
00448 << "instance is in AMPL nl format. The default file format is OSiL "
00449 << endl;
00450 helpMsg << "so this option is not required. " << endl;
00451
00452 helpMsg << endl;
00453
00454 helpMsg
00455 << "-solver solverName Possible values for default OS installation "
00456 << endl;
00457 helpMsg
00458 << "are bonmin(COIN-OR Bonmin), couenne (COIN-OR Couenne), clp (COIN-OR Clp),"
00459 << endl;
00460 helpMsg << "cbc (COIN-OR Cbc), dylp (COIN-OR DyLP), ipopt (COIN-OR Ipopt),"
00461 << endl;
00462 helpMsg << "and symphony (COIN-OR SYMPHONY). Other solvers supported"
00463 << endl;
00464 helpMsg
00465 << "(if the necessary libraries are present) are cplex (Cplex through COIN-OR Osi),"
00466 << endl;
00467 helpMsg
00468 << "glpk (glpk through COIN-OR Osi), knitro (Knitro), and lindo (LINDO)."
00469 << endl;
00470 helpMsg << "If no value is specified for this parameter," << endl;
00471 helpMsg << "then cbc is the default value of this parameter." << endl;
00472
00473 helpMsg << endl;
00474
00475 helpMsg
00476 << "-browser browserName this paramater is a path to the browser on the "
00477 << endl;
00478 helpMsg
00479 << "local machine. If this optional parameter is specified then the "
00480 << endl;
00481 helpMsg << "solver result in OSrL format is transformed using XSLT into "
00482 << endl;
00483 helpMsg << "HTML and displayed in the browser. " << endl;
00484
00485 helpMsg << endl;
00486
00487 helpMsg
00488 << "-config pathToConfigureFile this parameter specifies a path on "
00489 << endl;
00490 helpMsg
00491 << "the local machine to a text file containing values for the input parameters. "
00492 << endl;
00493 helpMsg
00494 << "This is convenient for the user not wishing to constantly retype parameter values. "
00495 << endl;
00496 helpMsg
00497 << "This configure file can contain values for all of the other parameters. "
00498 << endl;
00499
00500 helpMsg << endl;
00501
00502 helpMsg << "--version or -v get the current version of this executable "
00503 << endl;
00504
00505 helpMsg << endl;
00506
00507 helpMsg << "--help or -h to get this help file " << endl;
00508
00509 helpMsg << endl;
00510
00511 helpMsg
00512 << "Note: If you specify a configure file by using the -config option, you can "
00513 << endl;
00514 helpMsg
00515 << "override the values of the options in the configure file by putting them in "
00516 << endl;
00517 helpMsg << "at the command line. " << endl << endl;
00518
00519 helpMsg
00520 << "See the OS User\' Manual: http://www.coin-or.org/OS/doc/osUsersManual.pdf"
00521 << endl;
00522 helpMsg << "for more detail on how to use the OS project. " << endl;
00523
00524 helpMsg << endl;
00525 helpMsg << "********************************************************"
00526 << endl << endl;
00527
00528 return helpMsg.str();
00529 }
00530
00531
00532 std::string OSAmplClientVersionInfo()
00533 {
00534 std::ostringstream versionMsg;
00535 versionMsg << "In order to find the version of this project " << endl;
00536 versionMsg << "connect to the directory where you downloaded " << endl;
00537 versionMsg << "and do: " << endl;
00538 versionMsg << "svn info " << endl;
00539
00540 return versionMsg.str();
00541 }
00542
00543 #if 0
00544
00545 nl2osil = new OSnl2osil( stub);
00546
00547 OSInstance *osinstance;
00548 std::cout << " call nl2osil" << std::endl;
00549
00550
00551
00552
00553 try
00554 {
00555 nl2osil->createOSInstance() ;
00556 }
00557 catch(const ErrorClass& eclass)
00558 {
00559 std::cout << eclass.errormsg << std::endl;
00560 return 0;
00561 }
00562 std::cout << " return from nl2osil" << std::endl;
00563 osinstance = nl2osil->osinstance;
00564 std::cout << " osinstance created" << std::endl;
00565
00566
00567 OSiLWriter *osilwriter = NULL;
00568 osilwriter = new OSiLWriter();
00569 osilwriter->m_bWhiteSpace = true;
00570 std::string sModeInstanceName = "modelInstance.osil";
00571 FileUtil *fileUtil;
00572 fileUtil = new FileUtil();
00573 fileUtil->writeFileFromString(sModeInstanceName, osilwriter->writeOSiL( osinstance) );
00574 delete fileUtil;
00575 fileUtil = NULL;
00576 delete osilwriter;
00577 osilwriter = NULL;
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 char *amplclient_options = NULL;
00592 DefaultSolver *solverType = NULL;
00593 std::string sSolverName = "";
00594 std::string osolFileName = "";
00595 std::string osol ="";
00596 std::string serviceLocation = "";
00597 osOptionsStruc *osoptions;
00598
00599 amplclient_options = getenv("OSAmplClient_options");
00600 if( amplclient_options != NULL)
00601 {
00602 cout << "HERE ARE THE AMPLCLIENT OPTIONS " << amplclient_options << endl;
00603
00604 osoptions = new osOptionsStruc(amplclient_options);
00605 }
00606
00607
00608
00609 if(osolFileName.size() > 0)
00610 {
00611 FileUtil *fileUtil;
00612 fileUtil = new FileUtil();
00613 osol = fileUtil->getFileAsString( osolFileName.c_str() );
00614 delete fileUtil;
00615 }
00616
00617
00618
00619
00620
00621 unsigned int k;
00622 for(k = 0; k < sSolverName.length(); k++)
00623 {
00624 sSolverName[ k] = tolower( sSolverName[ k]);
00625 }
00626
00627
00628 OSrLReader *osrlreader = NULL;
00629 OSrLWriter *osrlwriter;
00630 osrlwriter = new OSrLWriter();
00631 OSResult *osresult = NULL;
00632 std::string osrl = "";
00633
00634
00635 try
00636 {
00637 if(serviceLocation.size() == 0 )
00638 {
00639
00640 osrl = runSolver(sSolverName, osol, osinstance);
00641 }
00642
00643
00644 else
00645 {
00646 OSSolverAgent* osagent = NULL;
00647 OSiLWriter *osilwriter = NULL;
00648 osilwriter = new OSiLWriter();
00649 std::string osil = osilwriter->writeOSiL( osinstance);
00651
00652
00653
00654
00655
00657
00658 osagent = new OSSolverAgent( serviceLocation);
00659 cout << "Place remote synchronous call: " + serviceLocation << endl << endl << endl;
00660
00661 osrl = osagent->solve(osil, osol);
00662 if (osrl.size() == 0) throw ErrorClass("Nothing was returned from the server, please check service address");
00663 delete osilwriter;
00664 delete osagent;
00665 }
00666 }
00667 catch(const ErrorClass& eclass)
00668 {
00669 osresult = new OSResult();
00670 osresult->setGeneralMessage( eclass.errormsg);
00671 osresult->setGeneralStatusType( "error");
00672 osrl = osrlwriter->writeOSrL( osresult);
00673 std::cout << osrl << std::endl;
00674 osrl = " ";
00675 write_sol(const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00676 delete osresult;
00677 return 0;
00678 }
00679
00680 try
00681 {
00682
00683 std::string sResultFileName = "solutionResult.osrl";
00684 FileUtil *fileUtil;
00685 fileUtil = new FileUtil();
00686 fileUtil->writeFileFromString(sResultFileName, osrl);
00687 delete fileUtil;
00688
00689 std::string::size_type pos1 = osrl.find( "error");
00690 if(pos1 == std::string::npos)
00691 {
00692 std::string sReport = "model was solved";
00693 std::cout << sReport << std::endl;
00694
00695 osrlreader = new OSrLReader();
00696 osresult = osrlreader->readOSrL( osrl);
00697
00698
00699
00700
00701
00702 sReport = " ";
00703 int i;
00704 int vecSize;
00705 double *x;
00706 double *y;
00707 int numVars = osresult->getVariableNumber();
00708 int numCons = osresult->getConstraintNumber();
00709 x = new double[ numVars];
00710 y = new double[ numCons];
00711
00712 std::vector<IndexValuePair*> primalValPair;
00713 std::vector<IndexValuePair*> dualValPair;
00714 dualValPair = osresult->getOptimalDualVariableValues( 0);
00715 primalValPair = osresult->getOptimalPrimalVariableValues( 0);
00716
00717 for(i = 0; i < numVars; i++)
00718 {
00719 x[ i] = 0.0;
00720 }
00721 vecSize = primalValPair.size();
00722 for(i = 0; i < vecSize; i++)
00723 {
00724 x[ primalValPair[i]->idx ] = primalValPair[i]->value;
00725
00726
00727 }
00728
00729
00730 for(i = 0; i < numCons; i++)
00731 {
00732 y[ i] = 0.0;
00733 }
00734 vecSize = dualValPair.size();
00735 for(i = 0; i < vecSize; i++)
00736 {
00737 y[ dualValPair[i]->idx ] = dualValPair[i]->value;
00738
00739
00740 }
00741
00742
00743
00744 write_sol( const_cast<char*>(sReport.c_str()), x, y , NULL);
00745
00746 delete osrlreader;
00747 osrlreader = NULL;
00748
00749
00750
00751
00752 }
00753 else
00754 {
00755
00756
00757 std::cout << osrl << std::endl;
00758 osrl = " ";
00759
00760 write_sol( const_cast<char*>(osrl.c_str()), NULL, NULL, NULL);
00761 need_nl = 0;
00762 }
00763
00764 }
00765 catch(const ErrorClass& eclass)
00766 {
00767 cout << "There was an error parsing the OSrL" << endl << eclass.errormsg << endl << endl;
00768 }
00769 if( solverType != NULL )
00770 {
00771
00772 delete solverType;
00773
00774 solverType = NULL;
00775 }
00776 delete osrlwriter;
00777
00778 osrlwriter = NULL;
00779 delete nl2osil;
00780
00781 nl2osil = NULL;
00782 ASL_free(&asl);
00783 return 0;
00784 }
00785
00786
00787
00788
00789 void getAmplClientOptions(char *amplclient_options, std::string *solverName,
00790 std::string *solverOptions, std::string *serviceLocation)
00791 {
00792
00793 osOptionsStruc *osoptions;
00794
00795 void* scanner;
00796
00797
00798 osoptions = new osOptionsStruc();
00799 osoptions->configFile = "";
00800 osoptions->osilFile = "";
00801 osoptions->osil = "";
00802 osoptions->osolFile = "";
00803 osoptions->osol = "";
00804 osoptions->osrlFile = "";
00805 osoptions->osrl = "";
00806
00807 osoptions->insList = "";
00808 osoptions->serviceLocation = "";
00809 osoptions->serviceMethod = "";
00810 osoptions->osplInputFile = "";
00811 osoptions->osplOutputFile = "";
00812 osoptions->mpsFile = "";
00813 osoptions->nlFile = "";
00814 osoptions->gamsControlFile = "";
00815 osoptions->solverName = "";
00816 osoptions->browser = "";
00817 osoptions->invokeHelp = false;
00818 osoptions->writeVersion = false;
00819 try
00820 {
00821
00822 ossslex_init( &scanner);
00823
00824 setyyextra( osoptions, scanner);
00825
00826 osss_scan_string( amplclient_options, scanner);
00827
00828 ossslex( scanner);
00829 ossslex_destroy( scanner);
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 *solverName = osoptions->solverName;
00849 *solverOptions = osoptions->osolFile;
00850
00851 *serviceLocation = osoptions->serviceLocation;
00852
00853 }
00854 catch(const ErrorClass& eclass)
00855 {
00856 cout << "There was an error processing OSAmplClient options: " << endl << eclass.errormsg << endl << endl;
00857 throw ErrorClass( eclass.errormsg) ;
00858 }
00859 }
00860 #endif