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: