001: // -------------------------------------------------------------- -*- C++ -*-
002: // File: warehouse.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: 
016: /* --------------------------------------------------------------------------
017:  * USAGE EXAMPLE:
018:  * warehouse fixed 30 nbWarehouses 5 nbStores 10 disaggregate 1
019:  * --------------------------------------------------------------------------
020:  */
021: 
022: #include <sstream>
023: 
024: ILOSTLBEGIN
025: 
026: class MyParams: public IloOplDataSourceBaseI {
027:     int _nbWarehouses;
028:     int _nbStores;
029:     int _fixed;
030:     IloBool _disaggregate;
031: 
032:     void usage();
033: public:
034:     MyParams(IloEnv& env, int argc, char* argv[]);
035:     void read() const;
036: };
037: static char* getModelText();
038: int main(int argc,char* argv[]) {
039:         IloEnv env;
040:     
041: 
042:     int status = 127;
043:     try {
044:         IloOplErrorHandler handler(env,cout);
045:         std::istringstream in( getModelText() );
046:         IloOplModelSource modelSource(env,in,"warehouse");
047:         IloOplSettings settings(env,handler);
048:         IloOplModelDefinition def(modelSource,settings);
049:         IloCplex cplex(env);
050:         IloOplModel opl(def,cplex);
051:         MyParams params(env,argc,argv);
052:         IloOplDataSource dataSource(&params);
053:         opl.addDataSource(dataSource);
054:         opl.generate();
055:         if ( cplex.solve() ) {
056:             cout << endl
057:                 << "OBJECTIVE: " << fixed << setprecision(2) << opl.getCplex().getObjValue()
058:                 << endl;
059:             opl.postProcess();
060:             opl.printSolution(cout);
061:             status = 0;
062:         } else {
063:             cout << "No solution!" << endl;
064:             status = 1;
065:         }
066:     } catch (IloOplException & e) {
067:         cout << "### OPL exception: " << e.getMessage() << endl;
068:     } catch( IloException & e ) {
069:         cout << "### CONCERT exception: ";
070:         e.print(cout);
071:         status = 2;
072:     } catch (...) {
073:         cout << "### UNEXPECTED ERROR ..." << endl;
074:         status = 3;
075:     }
076: 
077:     env.end();
078: 
079:     cout << endl << "--Press <Enter> to exit--" << endl;
080:     getchar();
081:     
082:     return status;
083: }
084: static char* getModelText() {
085:     return (char*)"\
086:            int   fixed        = ...; \
087:            int   nbWarehouses = ...; \
088:            int   nbStores     = ...; \
089:            int   disaggregate = ...; \
090:            \
091:            assert nbStores > nbWarehouses; \
092:            \
093:            range Warehouses = 1..nbWarehouses; \
094:            range Stores     = 1..nbStores; \
095:            \
096:            int capacity[w in Warehouses] = nbStores div nbWarehouses + w mod (nbStores div nbWarehouses); \
097:            int supplyCost[s in Stores][w in Warehouses] = 1+((s+10*w)%100); \
098:            \
099:            dvar boolean open[Warehouses]; \
100:            dvar boolean supply[Stores][Warehouses]; \
101:            \
102:            minimize \
103:            sum(w in Warehouses) fixed * open[w] + \
104:            sum(w in Warehouses, s in Stores) supplyCost[s][w] * supply[s][w]; \
105:            \
106:            constraints { \
107:              forall(s in Stores) \
108:                sum(w in Warehouses) supply[s][w] == 1; \
109:              forall(w in Warehouses) \
110:                sum(s in Stores) supply[s][w] <= open[w]*capacity[w]; \
111:              if (disaggregate == 1) { \
112:                forall(w in Warehouses, s in Stores) \
113:                  supply[s][w] <= open[w]; \
114:              } \
115:            } \
116:            ";
117: }
118: 
119: MyParams::MyParams(IloEnv& env, int argc, char* argv[]):IloOplDataSourceBaseI(env) {
120:     _nbWarehouses = 5;
121:     _nbStores = 10;
122:     _fixed = 30;
123:     _disaggregate = 1;
124: 
125:     for (int i=1; i<argc; i++) {
126:         if ( strcmp("-h",argv[i])==0 ) {
127:             usage();
128:         } else if ( strcmp("fixed",argv[i])==0 ) {
129:             if ( i==argc ) {
130:                 usage();
131:             }
132:             _fixed=atoi(argv[++i]);
133:         } else if ( strcmp("nbWarehouses",argv[i])==0 ) {
134:             if ( i==argc ) {
135:                 usage();
136:             }
137:             _nbWarehouses=atoi(argv[++i]);
138:         } else if ( strcmp("nbStores",argv[i])==0 ) {
139:             if ( i==argc ) {
140:                 usage();
141:             }
142:             _nbStores=atoi(argv[++i]);
143:         } else if ( strcmp("disaggregate",argv[i])==0 ) {
144:             if ( i==argc ) {
145:                 usage();
146:             }
147:             _disaggregate=atoi(argv[++i]);
148:         } else {
149:             break;
150:         }
151:     }
152: 
153:         cout << "Using parameters: " << endl
154:                 << "    nbWarehouses " << _nbWarehouses << endl
155:                 << "    nbStores     " << _nbStores << endl
156:                 << "    fixed        " << _fixed << endl
157:                 << "    disaggregate " << _disaggregate << endl
158:                 << endl;
159: }
160: 
161: void MyParams::usage() {
162:         cerr << endl
163:                 << "Usage: warehouse [-h] parameters" << endl
164:                 << "  -h " << "this help message" << endl
165:                 << "  parameters " << endl
166:                 << "    nbWarehouses <value> " << endl
167:                 << "    nbStores     <value> " << endl
168:                 << "    fixed        <value> " << endl
169:                 << "    disaggregate <value> " << endl
170:                 << endl;
171:     exit(0);
172: }
173: void MyParams::read() const {
174:     IloOplDataHandler handler = getDataHandler();
175: 
176:     handler.startElement("nbWarehouses");
177:     handler.addIntItem(_nbWarehouses);
178:     handler.endElement();
179: 
180:     handler.startElement("nbStores");
181:     handler.addIntItem(_nbStores);
182:     handler.endElement();
183: 
184:     handler.startElement("fixed");
185:     handler.addIntItem(_fixed);
186:     handler.endElement();
187: 
188:     handler.startElement("disaggregate");
189:     handler.addIntItem(_disaggregate);
190:     handler.endElement();
191: }