001: // -------------------------------------------------------------- -*- C++ -*-
002: // File: steelmill.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: /*
015: This problem is based on "prob038: Steel mill slab design problem" from
016: CSPLib (www.csplib.org). It is a simplification of an industrial problem
017: described in J. R. Kalagnanam, M. W. Dawande, M. Trumbo, H. S. Lee.
018: "Inventory Matching Problems in the Steel Industry," IBM Research
019: Report RC 21171, 1998.
020: */
021: 
022: #include <ilopl/iloopl.h>
023: 
024: 
025: #include <sstream>
026: 
027: ILOSTLBEGIN
028: 
029: class MyData: public IloOplDataSourceBaseI {
030: public:
031:         MyData(IloEnv& env);
032:     void read() const;
033: };
034: static char* getModelText();
035: int main(int argc,char* argv[]) {
036:         IloEnv env;
037:     
038: 
039:     int status = 127;
040:     try {
041:         IloOplErrorHandler handler(env,cout);
042:         std::istringstream in( getModelText() );
043:         IloOplModelSource modelSource(env,in,"steelmill");
044:             IloOplSettings settings(env,handler);
045:         IloOplModelDefinition def(modelSource,settings);
046:         IloCP cp(env);
047:         IloOplModel opl(def,cp);
048:         MyData data(env);
049:         IloOplDataSource dataSource(&data);
050:         opl.addDataSource(dataSource);
051:         opl.generate();
052:         if ( cp.solve() ) {
053:             cout << endl 
054:                 << "OBJECTIVE: "  << opl.getCP().getObjValue() 
055:                 << endl;
056:             opl.postProcess();
057:             opl.printSolution(cout);
058:             status = 0;
059:         } else {
060:             cout << "No solution!" << endl;
061:             status = 1;
062:         }
063:     } catch( IloOplException & e ) {
064:         cout << "### OPL exception: " << e.getMessage() << endl;
065:     } catch( IloException & e ) {
066:         cout << "### CONCERT exception: ";
067:         e.print(cout);
068:         status = 2;
069:     } catch (...) {
070:         cout << "### UNEXPECTED ERROR ..." << endl;
071:         status = 3;
072:     }
073: 
074:     env.end();
075: 
076:     cout << endl << "--Press <Enter> to exit--" << endl;
077:     getchar();
078: 
079:     return status;
080: }
081: static char* getModelText() {
082:     return (char*)"\
083: using CP;\
084: \
085: int nbOrders   = ...;\
086: int nbSlabs = ...;\
087: int nbColors   = ...;\
088: int nbCap      = ...;\
089: int capacities[1..nbCap] = ...;\
090: int weight[1..nbOrders] = ...;\
091: int colors[1..nbOrders] = ...;\
092: int maxLoad = sum(i in 1..nbOrders) weight[i];\
093: int maxCap  = max(i in 1..nbCap) capacities[i];\
094: int loss[c in 0..maxCap] = min(i in 1..nbCap : capacities[i] >= c) capacities[i] - c; \
095: execute {\
096: writeln(\"loss = \", loss);\
097: writeln(\"maxLoad = \", maxLoad);\
098: writeln(\"maxCap = \", maxCap);\
099: };\
100: dvar int where[1..nbOrders] in 1..nbSlabs;\
101: dvar int load[1..nbSlabs] in 0..maxLoad;\
102: execute {\
103:   cp.param.LogPeriod = 50;\
104:   var f = cp.factory;\
105:   cp.setSearchPhases(f.searchPhase(where));\
106: }\
107: dexpr int totalLoss = sum(s in 1..nbSlabs) loss[load[s]];\
108: \
109: minimize totalLoss;\
110: subject to {  \
111:   packCt: pack(load, where, weight);\
112:   forall(s in 1..nbSlabs)\
113:     colorCt: sum (c in 1..nbColors) (or(o in 1..nbOrders : colors[o] == c) (where[o] == s)) <= 2; \
114: }\
115:            ";
116: }
117: 
118: MyData::MyData(IloEnv& env):IloOplDataSourceBaseI(env) {
119:  
120: }
121: 
122: void MyData::read() const {
123:     const int _nbOrders = 12;
124:     const int _nbSlabs = 12;
125:     const int _nbColors = 8;
126:     const int _nbCap = 20;
127:         
128:     IloOplDataHandler handler = getDataHandler();
129: 
130:     handler.startElement("nbOrders");
131:     handler.addIntItem(_nbOrders);
132:     handler.endElement();
133:     handler.startElement("nbSlabs");
134:     handler.addIntItem(_nbSlabs);
135:     handler.endElement();
136:     handler.startElement("nbColors");
137:     handler.addIntItem(_nbColors);
138:     handler.endElement();
139:     handler.startElement("nbCap");
140:     handler.addIntItem(_nbCap);
141:     handler.endElement();
142: 
143:         int _capacity[_nbCap] = { 0, 11, 13, 16, 17, 19, 20,
144:                                   23, 24, 25, 26, 27, 28, 29,
145:                                   30, 33, 34, 40, 43, 45 };
146:         handler.startElement("capacities");
147:         handler.startArray();
148:         for (int i=0; i<_nbCap; i++)
149:                 handler.addIntItem(_capacity[i]);
150:         handler.endArray();
151:         handler.endElement();
152: 
153:         int _weight[_nbOrders] = { 22, 9, 9, 8, 8, 6, 5, 3, 3, 3, 2, 2};
154:         handler.startElement("weight");
155:         handler.startArray();
156:         for (int i=0; i<_nbOrders; i++)
157:                 handler.addIntItem(_weight[i]);
158:         handler.endArray();
159:         handler.endElement();
160: 
161:         int _colors[_nbOrders] = { 5, 3, 4, 5, 7, 3, 6, 0, 2, 3, 1, 5 };
162:         handler.startElement("colors");
163:         handler.startArray();
164:         for (int i=0; i<_nbOrders; i++)
165:                 handler.addIntItem(_colors[i]);
166:         handler.endArray();
167:         handler.endElement();
168: }