001: // -------------------------------------------------------------- -*- C++ -*-
002: // File: carseq.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: #include <sstream>
018: 
019: ILOSTLBEGIN
020: 
021: 
022: class MyData: public IloOplDataSourceBaseI {
023: public:
024:         MyData(IloEnv& env);
025:     void read() const;
026: };
027: static char* getModelText();
028: int main(int argc,char* argv[]) {
029:         IloEnv env;
030:     
031: 
032:     int status = 127;
033:     try {
034:         IloOplErrorHandler handler(env,cout);
035:         std::istringstream in( getModelText() );
036:         IloOplModelSource modelSource(env,in,"carseq");
037:         IloOplSettings settings(env,handler);
038:         IloOplModelDefinition def(modelSource,settings);
039:         IloCP cp(env);
040:         IloOplModel opl(def,cp);
041:         MyData data(env);
042:         IloOplDataSource dataSource(&data);
043:         opl.addDataSource(dataSource);
044:         opl.generate();
045: 
046:         if ( cp.solve()) {
047:             cout << endl 
048:                 << "OBJECTIVE: "  << opl.getCP().getObjValue() 
049:                 << endl;
050:             opl.postProcess();
051:             opl.printSolution(cout);
052:             status = 0;
053:         } else {
054:             cout << "No solution!" << endl;
055:             status = 1;
056:         }
057:     } catch (IloOplException & e) {
058:         cout << "### OPL exception: " << e.getMessage() << endl;
059:     } catch( IloException & e ) {
060:         cout << "### exception: ";
061:         e.print(cout);
062:         status = 2;
063:     } catch (...) {
064:         cout << "### UNEXPECTED ERROR ..." << endl;
065:         status = 3;
066:     }
067: 
068:     env.end();
069: 
070:     cout << endl << "--Press <Enter> to exit--" << endl;
071:     getchar();
072:     
073:     return status;
074: }
075: static char* getModelText() {
076:     return (char*)"\
077: using CP;\
078: \
079: int  nbConfs    = ...; \
080: int   nbOptions = ...;\
081: \
082: range Confs=1..nbConfs;\
083: range Options=1..nbOptions;\
084: \
085: int demand[Confs] = ...;\
086: tuple CapacitatedWindow { \
087:   int l;\
088:   int u;\
089: };\
090: CapacitatedWindow capacity[Options] = ...; \
091: \
092: range AllConfs = 0..nbConfs;\
093: int nbCars = sum (c in Confs) demand[c];\
094: int nbSlots = ftoi(floor(nbCars * 1.1 + 5)); \
095: int nbBlanks = nbSlots - nbCars;\
096: range Slots = 1..nbSlots;\
097: int option[Options,Confs] = ...; \
098: int allOptions[o in Options, c in AllConfs] = (c == 0) ? 0 : option[o][c];\
099: \
100: dvar int slot[Slots] in AllConfs;\
101: dvar int lastSlot in nbCars..nbSlots;\
102: \
103: minimize lastSlot - nbCars; \
104: subject to { \
105:   count(slot, 0) == nbBlanks;\
106:   forall (c in Confs)\
107:     count(slot, c) == demand[c];\
108: \
109:   forall(o in Options, s in Slots : s + capacity[o].u - 1 <= nbSlots) \
110:     sum(j in s .. s + capacity[o].u - 1) allOptions[o][slot[j]] <= capacity[o].l; \
111: \
112:   forall (s in nbCars + 1 .. nbSlots) \
113:     (s > lastSlot) => slot[s] == 0; \
114: };\
115: ";
116: }
117: 
118: MyData::MyData(IloEnv& env):IloOplDataSourceBaseI(env) {
119:  
120: }
121: 
122: void MyData::read() const {
123:         const int _nbConfs = 7;
124:         const int _nbOptions = 5;
125: 
126:     IloOplDataHandler handler = getDataHandler();
127: 
128:     handler.startElement("nbConfs");
129:     handler.addIntItem(_nbConfs);
130:     handler.endElement();
131:     handler.startElement("nbOptions");
132:     handler.addIntItem(_nbOptions);
133:     handler.endElement();
134: 
135:         int _demand[_nbConfs] = {5, 5, 10, 10, 10, 10, 5};
136:         handler.startElement("demand");
137:         handler.startArray();
138:         for (int i=0; i<_nbConfs; i++)
139:                 handler.addIntItem(_demand[i]);
140:         handler.endArray();
141:         handler.endElement();
142:     
143:         int _option[_nbOptions][_nbConfs] = {{1, 0, 0, 0, 1, 1, 0},
144:                                                                            {0, 0, 1, 1, 0, 1, 0},
145:                                                                            {1, 0, 0, 0, 1, 0, 0},
146:                                                                            {1, 1, 0, 1, 0, 0, 0},
147:                                                                            {0, 0, 1, 0, 0, 0, 0}};
148:         handler.startElement("option");
149:         handler.startArray();
150:         for (int i=0; i< _nbOptions; i++) {
151:                 handler.startArray();
152:                 for (int j=0; j<_nbConfs;j++)
153:                         handler.addIntItem(_option[i][j]);
154:                 handler.endArray();
155:         }
156:         handler.endArray();
157:         handler.endElement();
158: 
159:         int _capacity[_nbOptions][2] = {{1,2},{2,3},{1,3},{2,5},{1,5}};
160:         handler.startElement("capacity");
161:         handler.startArray();
162:         for (int i=0; i<_nbOptions;i++) {
163:                 handler.startTuple();
164:                 handler.addIntItem(_capacity[i][0]);
165:                 handler.addIntItem(_capacity[i][1]);
166:                 handler.endTuple();
167:         }
168:         handler.endArray();
169:         handler.endElement();
170: }