001: // -------------------------------------------------------------- -*- C++ -*-
002: // File: oplrunsample.cpp
003: // --------------------------------------------------------------------------
004: // Licensed Materials - Property of IBM
005: //
006: // 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55
007: // Copyright IBM Corporation 1998, 2013. All Rights Reserved.
008: //
009: // Note to U.S. Government Users Restricted Rights:
010: // Use, duplication or disclosure restricted by GSA ADP Schedule
011: // Contract with IBM Corp.
012: ///////////////////////////////////////////////////////////////////////////////
013:
014: #include <ilopl/iloopl.h>
015: #include <ilopl/ilooplprofiler.h>
016:
017:
018: #ifndef DATADIR
019: #ifdef ILO_WINDOWS
020: #define DIRSEP "\\"
021: #else
022: #define DIRSEP "/"
023: #endif
024: #define DATADIR ".." DIRSEP ".." DIRSEP ".." DIRSEP ".." DIRSEP "opl" DIRSEP
025: #endif
026:
027: ILOSTLBEGIN
028:
029: static const char* DEFAULT_mod = DATADIR "mulprod" DIRSEP "mulprod.mod";
030: static const int DEFAULT_ndat = 1;
031: static const char* DEFAULT_dat[] = { DATADIR "mulprod" DIRSEP "mulprod.dat" };
032:
033:
034: class CommandLine;
035:
036: class OplRunSample {
037: CommandLine& _cl;
038: IloEnv& _env;
039: IloTimer _timer;
040:
041: void trace(const char* title, const char* info =0);
042:
043: public:
044: OplRunSample(IloEnv& env, CommandLine& cl);
045: int run();
046: };
047:
048: class CommandLine {
049: const char* _myName;
050: IloBool _verbose;
051: IloBool _forceUsage;
052: IloBool _isRelax;
053: IloBool _isConflict;
054:
055: IloBool _project;
056: const char* _modelFileName;
057: int _nDataFiles;
058: const char** _dataFileNames;
059:
060: const char* _exportName;
061: const char* _compileName;
062: const char* _externalDataName;
063: const char* _internalDataName;
064:
065: public:
066: CommandLine(int argc, char* argv[]);
067: ~CommandLine();
068:
069: void usage() const;
070:
071: const char* getModelFileName() const;
072: int getNumberOfDataFiles() const;
073: const char** getDataFileNames() const;
074:
075: IloBool isProject() const;
076: const char* getProjectPath() const;
077: const char* getRunConfigurationName() const;
078:
079: IloBool isVerbose() const;
080: const char* getExportName() const;
081: const char* getCompileName() const;
082: const char* getExternalDataName() const;
083: const char* getInternalDataName() const;
084: IloBool isForceElementUsage() const;
085: IloBool isRelaxation() const;
086: IloBool isConflict() const;
087: };
088:
089: int main(int argc,char* argv[]) {
090: int status = -1;
091: IloEnv env;
092:
093: try {
094: CommandLine cl(argc,argv);
095: OplRunSample oplRun(env,cl);
096: status = oplRun.run();
097: } catch( IloOplException & e ) {
098: cout << "### OPL exception: " << e.getMessage() << endl;
099: } catch( IloException & e ) {
100: cout << "### CONCERT exception: ";
101: e.print(cout);
102: status = 2;
103: cout << endl;
104: } catch (...) {
105: cout << "### UNEXPECTED ERROR ..." << endl;
106: status = 3;
107: }
108:
109: env.end();
110:
111: cout << endl << "--Press <Enter> to exit--" << endl;
112: getchar();
113:
114: return status;
115: }
116:
117: int OplRunSample::run() {
118: locale loc("");
119: locale::global(loc);
120: #ifdef ILO_WINDOWS
121: static char buffer[1024];
122: cout.rdbuf()->pubsetbuf(buffer,1024);
123: #endif
124:
125: if ( _cl.getCompileName() ) {
126: IloOplCompiler compiler(_env);
127: ofstream ofs(_cl.getCompileName(),ios::binary);
128: IloOplModelSource modelSource(_env,_cl.getModelFileName());
129: compiler.compile(modelSource,ofs);
130: ofs.close();
131:
132: trace("compile");
133: return 0;
134: }
135:
136: if ( _cl.getModelFileName()==0 && !_cl.isProject()) {
137: return 0;
138: }
139:
140: trace("initial");
141:
142: IloOplRunConfiguration rc;
143: if ( _cl.isProject() ) {
144: IloOplProject prj(_env,_cl.getProjectPath());
145: rc = prj.makeRunConfiguration(_cl.getRunConfigurationName());
146: } else {
147: if ( _cl.getNumberOfDataFiles()==0 ) {
148: rc = IloOplRunConfiguration(_env,_cl.getModelFileName());
149: } else {
150: IloStringArray dataFileNames(_env,_cl.getNumberOfDataFiles());
151: for(int i=0; i<dataFileNames.getSize(); i++) {
152: dataFileNames[i] = _cl.getDataFileNames()[i];
153: }
154: rc = IloOplRunConfiguration(_env,_cl.getModelFileName(),dataFileNames);
155: }
156: }
157:
158: IloOplErrorHandler handler = rc.getErrorHandler();
159: IloOplModel opl = rc.getOplModel();
160:
161: IloOplSettings settings = opl.getSettings();
162: settings.setWithLocations(IloTrue);
163: settings.setWithNames(IloTrue);
164: settings.setForceElementUsage(_cl.isForceElementUsage());
165:
166: IloInt status = 9;
167: if ( opl.getModelDefinition().hasMain() ) {
168: status = opl.main();
169: cout << "main returns " << status << endl;
170: trace("main");
171: } else if ( handler.ok() ) {
172: opl.generate();
173: trace("generate model");
174:
175: if ( opl.hasCplex() ) {
176: if ( _cl.getExportName() ) {
177: opl.getCplex().exportModel( _cl.getExportName() );
178: trace("export model",_cl.getExportName());
179: }
180:
181: if ( _cl.isRelaxation() ) {
182: cout << "RELAXATIONS to obtain a feasible problem: " << endl;
183: opl.printRelaxation(cout);
184: cout << "RELAXATIONS done." << endl << endl;
185: }
186: if ( _cl.isConflict() ) {
187: cout << "CONFLICT in the infeasible problem: " << endl;
188: opl.printConflict(cout);
189: cout << "CONFLICT done." << endl << endl;
190: }
191: if (!_cl.isRelaxation() && !_cl.isConflict()) {
192: int result = 0;
193: try {
194: result = opl.getCplex().solve();
195: } catch( IloException & e ) {
196: cout << "### ENGINE exception: ";
197: e.print(cout);
198: cout << endl;
199: }
200:
201: if ( result ) {
202: trace("solve");
203: cout << endl << endl << "OBJECTIVE: " << fixed << setprecision(2) << opl.getCplex().getObjValue() << endl;
204:
205: opl.postProcess();
206: trace("post process");
207:
208: if ( _cl.isVerbose() ) {
209: opl.printSolution(cout);
210: }
211: status = 0;
212: } else {
213: trace("no solution");
214: status = 1;
215: }
216: }
217: } else { // opl.hasCP()
218: int result = 0;
219: try {
220: result = opl.getCP().solve();
221: } catch( IloException & e ) {
222: cout << "### ENGINE exception: ";
223: e.print(cout);
224: cout << endl;
225: }
226:
227: if ( result ) {
228: trace("solve");
229: if ( opl.getCP().hasObjective() ) {
230: cout << endl << endl << "OBJECTIVE: " << fixed << setprecision(2) << opl.getCP().getObjValue() << endl;
231: } else {
232: cout << endl << endl << "OBJECTIVE: no objective" << endl;
233: }
234: opl.postProcess();
235: trace("post process");
236:
237: if ( _cl.isVerbose() ) {
238: opl.printSolution(cout);
239: }
240: status = 0;
241: } else {
242: trace("no solution");
243: status = 1;
244: }
245: }
246: }
247:
248: if ( _cl.getExternalDataName() ) {
249: ofstream ofs(_cl.getExternalDataName());
250: opl.printExternalData(ofs);
251: ofs.close();
252: trace("write external data",_cl.getExternalDataName());
253: }
254:
255: if ( _cl.getInternalDataName() ) {
256: ofstream ofs(_cl.getInternalDataName());
257: opl.printInternalData(ofs);
258: ofs.close();
259: trace("write internal data",_cl.getInternalDataName());
260: }
261:
262: trace("done");
263: return status;
264: }
265:
266: void CommandLine::usage() const {
267: cerr << endl;
268: cerr << "Usage: " << endl;
269: cerr << _myName << " [options] model-file [data-file ...]" << endl;
270: cerr << _myName << " [options] -p project-path [run-configuration]" << endl;
271: cerr << " options " << endl;
272: cerr << " -h " << "this help message" << endl;
273: cerr << " -v " << "verbose" << endl;
274: cerr << " -e [export-file] " << "export model" << endl;
275: cerr << " -de dat-file " << "write external data" << endl;
276: cerr << " -di dat-file " << "write internal data" << endl;
277: cerr << " -o output-file " << "compile model" << endl;
278: cerr << " -f " << "force element usage" << endl;
279: cerr << " -relax " << "calculate relaxations needed for feasible model" << endl;
280: cerr << " -conflict " << "calculate a conflict for infeasible model" << endl;
281: cerr << endl;
282: exit(0);
283: }
284:
285: static IloBool FileExists(const char* path);
286:
287: CommandLine::CommandLine(int argc, char* argv[]) {
288: _myName = argv[0];
289: _verbose = IloFalse;
290: _exportName = 0;
291: _compileName = 0;
292: _externalDataName = 0;
293: _internalDataName = 0;
294: _project = IloFalse;
295: _modelFileName = 0;
296: _nDataFiles = 0;
297: _dataFileNames = 0;
298: _forceUsage = 0;
299: _isRelax = IloFalse;
300: _isConflict = IloFalse;
301:
302: int i=0;
303: for (i=1; i<argc; i++) {
304: if ( strcmp("-h",argv[i])==0 ) {
305: usage();
306: } else if ( strcmp("-p",argv[i])==0 ) {
307: _project = IloTrue;
308: } else if ( strcmp("-v",argv[i])==0 ) {
309: _verbose = IloTrue;
310: } else if ( strcmp("-e",argv[i])==0 ) {
311: i++;
312: if ( i<argc && argv[i][0]!='-' && argv[i][0]!='\0' ) {
313: _exportName = argv[i];
314: } else {
315: _exportName = "oplRunSample.lp";
316: i--;
317: }
318: } else if ( strcmp("-o",argv[i])==0 ) {
319: i++;
320: if ( i<argc && argv[i][0]!='-' && argv[i][0]!='\0' ) {
321: _compileName = argv[i];
322: } else {
323: usage();
324: }
325: } else if ( strcmp("-de",argv[i])==0 ) {
326: i++;
327: if ( i<argc && argv[i][0]!='-' && argv[i][0]!='\0' ) {
328: _externalDataName = argv[i];
329: } else {
330: usage();
331: }
332: } else if ( strcmp("-di",argv[i])==0 ) {
333: i++;
334: if ( i<argc && argv[i][0]!='-' && argv[i][0]!='\0' ) {
335: _internalDataName = argv[i];
336: } else {
337: usage();
338: }
339: } else if ( strcmp("-f",argv[i])==0 ) {
340: _forceUsage = IloTrue;
341: } else if ( strcmp("-relax",argv[i])==0 ) {
342: _isRelax = IloTrue;
343: } else if ( strcmp("-conflict",argv[i])==0 ) {
344: _isConflict = IloTrue;
345: } else if ( strncmp("-",argv[i],1)==0 ) {
346: cerr << "Unknown option: " << argv[i] << endl;
347: usage();
348: } else {
349: break;
350: }
351: }
352:
353: if ( i<argc ) {
354: _modelFileName= argv[i];
355: _dataFileNames = 0;
356: _nDataFiles = 0;
357: i++;
358: if ( i<argc ) {
359: _dataFileNames = (const char**)&argv[i];
360: _nDataFiles = argc-i;
361: }
362: }
363:
364: if ( _modelFileName==0 && FileExists(DEFAULT_mod) ) {
365: _modelFileName = DEFAULT_mod;
366: _nDataFiles = DEFAULT_ndat;
367: _dataFileNames = DEFAULT_dat;
368: }
369:
370: if ( _project && _nDataFiles>1 ) {
371: usage();
372: }
373: }
374:
375: CommandLine::~CommandLine() {
376: }
377:
378: IloBool CommandLine::isVerbose() const {
379: return _verbose;
380: }
381:
382: const char* CommandLine::getExportName() const {
383: return _exportName;
384: }
385:
386: const char* CommandLine::getCompileName() const {
387: return _compileName;
388: }
389:
390: const char* CommandLine::getExternalDataName() const {
391: return _externalDataName;
392: }
393:
394: const char* CommandLine::getInternalDataName() const {
395: return _internalDataName;
396: }
397:
398: const char* CommandLine::getModelFileName() const {
399: return _modelFileName;
400: }
401:
402: int CommandLine::getNumberOfDataFiles() const {
403: return _nDataFiles;
404: }
405:
406: const char** CommandLine::getDataFileNames() const {
407: return _dataFileNames;
408: }
409:
410: IloBool CommandLine::isProject() const {
411: return _project;
412: }
413:
414: const char* CommandLine::getProjectPath() const {
415: return _project ? _modelFileName : 0;
416: }
417:
418: const char* CommandLine::getRunConfigurationName() const {
419: return ( _project && _nDataFiles==1 ) ? _dataFileNames[0] : 0;
420: }
421:
422: IloBool CommandLine::isForceElementUsage() const {
423: return _forceUsage;
424: }
425:
426: IloBool CommandLine::isRelaxation() const {
427: return _isRelax;
428: }
429:
430: IloBool CommandLine::isConflict() const {
431: return _isConflict;
432: }
433:
434: OplRunSample::OplRunSample(IloEnv& env, CommandLine& cl)
435: :_cl(cl), _env(env), _timer(env) {
436: _timer.restart();
437: }
438:
439: void OplRunSample::trace(const char* title, const char* info) {
440: cout << endl << "<<< " << title;
441: if ( info ) {
442: cout << ": " << info;
443: }
444: if ( _cl.isVerbose() ) {
445: cout << ", at " << _env.getTime() << "s"
446: << ", took " << _timer.getTime() << "s";
447: _timer.restart();
448: }
449: cout << endl << endl;
450: }
451:
452: static IloBool FileExists(const char* path) {
453: FILE* exists = fopen(path,"r");
454: if ( exists ) fclose(exists);
455: return exists!=NULL;
456: }
457: