001: // --------------------------------------------------------------------------
002: // Licensed Materials - Property of IBM
003: //
004: // 5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55
005: // Copyright IBM Corporation 1998, 2013. All Rights Reserved.
006: //
007: // Note to U.S. Government Users Restricted Rights:
008: // Use, duplication or disclosure restricted by GSA ADP Schedule
009: // Contract with IBM Corp.
010: // --------------------------------------------------------------------------
011: 
012: {string} Products = ...;
013: {string} Resources = ...;
014: int NbPeriods = ...;
015: range Periods = 1..NbPeriods;
016: 
017: float Consumption[Resources][Products] = ...;
018: float Capacity[Resources] = ...;
019: float Demand[Products][Periods] = ...;
020: float InsideCost[Products] = ...;
021: float OutsideCost[Products]  = ...;
022: float Inventory[Products]  = ...;
023: float InvCost[Products]  = ...;
024: 
025: dvar float+ Inside[Products][Periods];
026: dvar float+ Outside[Products][Periods];
027: dvar float+ Inv[Products][0..NbPeriods];
028: 
029: 
030: execute {
031:   writeln("* Note: This OPL model is not compliant with cloud execution");
032: }
033: 
034: 
035: minimize
036:   sum( p in Products , t in Periods ) 
037:     (InsideCost[p]*Inside[p][t] + 
038:      OutsideCost[p]*Outside[p][t] +
039:      InvCost[p]*Inv[p][t]);
040: 
041: subject to {
042:   forall( r in Resources , t in Periods )
043:     ctCapacity:
044:       sum( p in Products ) 
045:         Consumption[r][p] * Inside[p][t] <= Capacity[r];
046: 
047:   forall( p in Products , t in Periods )
048:     ctDemand:
049:       Inv[p][t-1] + Inside[p][t] + Outside[p][t] == 
050:       Demand[p][t] + Inv[p][t];
051: 
052:   forall( p in Products )
053:     ctInventory:
054:       Inv[p][0] == Inventory[p]; 
055: }
056: 
057: tuple plan {
058:   float inside;
059:   float outside;
060:   float inv;
061: }
062: 
063: plan Plan[p in Products][t in Periods] = 
064:   <Inside[p,t],Outside[p,t],Inv[p,t]>;
065: 
066: main {
067:   var status = 0;
068:   thisOplModel.generate();
069: 
070:   var produce = thisOplModel;
071:   var capFlour = produce.Capacity["flour"];
072: 
073:   var best;
074:   var curr = Infinity;
075:   var basis = new IloOplCplexBasis();
076:   var ofile = new IloOplOutputFile("mulprod_main.txt");
077:   while ( 1 ) {
078:     best = curr;
079:     writeln("Solve with capFlour = ",capFlour);
080:     if ( cplex.solve() ) {
081:       curr = cplex.getObjValue();
082:       writeln();
083:       writeln("OBJECTIVE: ",curr);
084:       ofile.writeln("Objective with capFlour = ", capFlour, " is ", curr);        
085:     } 
086:     else {
087:       writeln("No solution!");
088:       break;
089:     }
090:     if ( best==curr ) break;
091: 
092:     if ( !basis.getBasis(cplex) ) {
093:       writeln("warm start preparation failed: ",basis.status);
094:       break;
095:     }
096: 
097:     // prepare next iteration
098:     var def = produce.modelDefinition;
099:     var data = produce.dataElements;
100:       
101:     if ( produce!=thisOplModel ) {
102:       produce.end();
103:     }
104: 
105:     produce = new IloOplModel(def,cplex);
106:     capFlour++;
107:     data.Capacity["flour"] = capFlour;
108:     produce.addDataSource(data);
109:     produce.generate();
110: 
111:     if ( !basis.setBasis(cplex) ) {
112:       writeln("warm start ",basis.Nrows,"x",basis.Ncols," failed: ",basis.status);
113:       break;
114:     }
115:   }
116:   basis.end();
117:   ofile.close();
118:   if (Math.abs(cplex.getObjValue() - 393.5)>=0.01) {
119:       status = -1;
120:   }
121:   if (best != Infinity) {
122:     writeln("plan = ",produce.Plan);
123:   }
124:   
125:   if ( produce!=thisOplModel ) {
126:     produce.end();
127:   }
128: 
129:   status;
130: }