Loading...
Searching...
No Matches
Cutstock.java
1package com.gams.examples.cutstock;
2
3import java.io.File;
4import java.util.HashMap;
5import java.util.Iterator;
6import java.util.Map;
7import java.util.Map.Entry;
8
12import com.gams.api.GAMSJob;
15import com.gams.api.GAMSOptions;
18import com.gams.api.GAMSSet;
23
32public class Cutstock {
33
34 public static void main(String[] args) {
35 // check workspace info from command line arguments
37 if (args.length > 0)
38 wsInfo.setSystemDirectory( args[0] );
39 // create a directory
40 File workingDirectory = new File(System.getProperty("user.dir"), "Cutstock");
41 workingDirectory.mkdir();
42 wsInfo.setWorkingDirectory(workingDirectory.getAbsolutePath());
43 // create a workspace
44 GAMSWorkspace ws = new GAMSWorkspace(wsInfo);
45
46 // instantiate GAMSOptions and define parameters
47 GAMSOptions opt = ws.addOptions();
48 GAMSDatabase cutstockData = ws.addDatabase("csdata");
49 opt.setAllModelTypes("Cplex");
50 opt.setOptCR( 0.0 ); // Solve to optimality
51 int maxpattern = 35;
52 opt.defines("pmax", String.valueOf(maxpattern));
53 opt.defines("solveMasterAs", "RMIP");
54
55 // define input data
56 Map<String, Double> d = new HashMap<String, Double>();
57 {
58 d.put( "i1", Double.valueOf(97) );
59 d.put( "i2", Double.valueOf(610) );
60 d.put( "i3", Double.valueOf(395) );
61 d.put( "i4", Double.valueOf(211) );
62 }
63 Map<String, Double> w = new HashMap<String, Double>();
64 {
65 w.put( "i1", Double.valueOf(45) );
66 w.put( "i2", Double.valueOf(36) );
67 w.put( "i3", Double.valueOf(31) );
68 w.put( "i4", Double.valueOf(14) );
69
70 }
71 int r = 100; // raw width
72
73 GAMSSet widths = cutstockData.addSet("i", 1, "widths");
74 GAMSParameter rawWidth = cutstockData.addParameter("r", 0, "raw width");
75 GAMSParameter demand = cutstockData.addParameter("d", 1, "demand");
76 GAMSParameter width = cutstockData.addParameter("w", 1, "width");
77
78 rawWidth.addRecord().setValue( 100 );
79 for (String i : d.keySet())
80 widths.addRecord(i);
81 for (Entry<String, Double> e : d.entrySet())
82 demand.addRecord( e.getKey() ).setValue( e.getValue() );
83 for (Entry<String, Double> e : w.entrySet())
84 width.addRecord( e.getKey() ).setValue( e.getValue() );
85
86 // create initial checkpoint
87 GAMSCheckpoint masterCP = ws.addCheckpoint();
88 GAMSJob masterInitJob = ws.addJobFromString(masterModel);
89 masterInitJob.run(opt, masterCP, cutstockData);
90
91 GAMSJob masterJob = ws.addJobFromString("execute_load 'csdata', aip, pp; solve master min z using %solveMasterAs%;", masterCP);
92
93 GAMSSet pattern = cutstockData.addSet("pp", 1, "pattern index");
94 GAMSParameter patternData = cutstockData.addParameter("aip", 2, "pattern data");
95
96 // Initial pattern: pattern i hold width i
97 int patternCount = 0;
98 for (Entry<String, Double> e : w.entrySet()) {
99 String[] keys = new String[] { e.getKey(), pattern.addRecord( Integer.toString(++patternCount) ).getKey(0) };
100 patternData.addRecord(keys).setValue( (int)(r / e.getValue()) );
101 }
102
103 // create model instance for sub job
104 GAMSCheckpoint subCP = ws.addCheckpoint();
105 ws.addJobFromString(subModel).run(opt, subCP, cutstockData);
106
107 GAMSModelInstance subMI = subCP.addModelInstance();
108
109 // define modifier demdual
110 GAMSParameter demandDual = subMI.SyncDB().addParameter("demdual", 1, "dual of demand from master");
111 subMI.instantiate("pricing min z using mip", opt, new GAMSModifier(demandDual));
112
113 // find new pattern
114 boolean patternAdded = true;
115 while (patternAdded)
116 {
117 masterJob.run(opt, masterCP, cutstockData);
118 // Copy duals into gmssubMI.SyncDB DB
119 demandDual.clear();
120 for(GAMSEquationRecord dem : masterJob.OutDB().getEquation("demand"))
121 demandDual.addRecord( dem.getKey(0) ).setValue( dem.getMarginal() );
122
123 subMI.solve();
124
125 if (subMI.SyncDB().getVariable("z").findRecord().getLevel() < -0.00001) {
126 if (patternCount == maxpattern) {
127 System.out.println("Out of pattern. Increase maxpattern (currently ["+maxpattern+"])");
128 patternAdded = false;
129 }
130 else {
131 System.out.println("New pattern Value: " + subMI.SyncDB().getVariable("z").findRecord().getLevel());
132 GAMSSetRecord s = pattern.addRecord( Integer.toString(++patternCount) );
133 for (GAMSVariableRecord y : subMI.SyncDB().getVariable("y")) {
134 if (y.getLevel() > 0.5) {
135 String[] keys = new String[] { y.getKey(0), s.getKey(0) };
136 patternData.addRecord( keys ).setValue( Math.round(y.getLevel()) );
137 }
138 }
139 }
140 } else {
141 patternAdded = false;
142 }
143 }
144
145 // solve final MIP
146 opt.defines("solveMasterAs", "MIP");
147 masterJob.run(opt, cutstockData);
148
149 System.out.println("Optimal Solution: "+masterJob.OutDB().getVariable("z").findRecord().getLevel());
150
151 for (GAMSVariableRecord xp : masterJob.OutDB().getVariable("xp")) {
152 if (xp.getLevel() > 0.5) {
153 System.out.println(" pattern ["+xp.getKey(0)+"] ["+xp.getLevel()+"] times: ");
154 GAMSParameter param = masterJob.OutDB().getParameter("aip");
155 @SuppressWarnings("unused")
156 GAMSParameterRecord aip = param.getFirstRecord(new String[] { " ", xp.getKey(0) });
157 Iterator<GAMSParameterRecord> it = param.iterator();
158 while (it.hasNext()) {
159 GAMSParameterRecord rec = it.next();
160 System.out.println(" ["+rec.getKey(0)+"] : ["+ rec.getValue()+"]");
161 }
162 System.out.println();
163 }
164 }
165
166 // clean up of unmanaged resources
167 cutstockData.dispose();
168 subMI.dispose();
169 opt.dispose();
170
171 }
172
173 static String masterModel =
174 "$Title Cutting Stock - Master problem \n" +
175 " \n" +
176 "Set i widths \n" +
177 "Parameter \n" +
178 " w(i) width \n" +
179 " d(i) demand \n" +
180 "Scalar \n" +
181 " r raw width; \n" +
182 "$gdxin csdata \n" +
183 "$load i w d r \n" +
184 " \n" +
185 "$if not set pmax $set pmax 1000 \n" +
186 "Set p possible patterns /1*%pmax%/ \n" +
187 " pp(p) dynamic subset of p \n" +
188 "Parameter \n" +
189 " aip(i,p) number of width i in pattern growing in p;\n" +
190 " \n" +
191 "* Master model \n" +
192 "Variable xp(p) patterns used \n" +
193 " z objective variable \n" +
194 "Integer variable xp; xp.up(p) = sum(i, d(i)); \n" +
195 " \n" +
196 "Equation numpat number of patterns used \n" +
197 " demand(i) meet demand; \n" +
198 " \n" +
199 "numpat.. z =e= sum(pp, xp(pp)); \n" +
200 "demand(i).. sum(pp, aip(i,pp)*xp(pp)) =g= d(i); \n" +
201 " \n" +
202 "model master /numpat, demand/; \n" +
203 " \n";
204
205 static String subModel =
206 "$Title Cutting Stock - Pricing problem is a knapsack model \n" +
207 " \n" +
208 "Set i widths \n" +
209 "Parameter \n" +
210 " w(i) width; \n" +
211 "Scalar \n" +
212 " r raw width; \n" +
213 " \n" +
214 "$gdxin csdata \n" +
215 "$load i w r \n" +
216 " \n" +
217 "Parameter \n" +
218 " demdual(i) duals of master demand constraint /#i eps/; \n" +
219 " \n" +
220 "Variable z, y(i) new pattern; \n" +
221 "Integer variable y; y.up(i) = ceil(r/w(i)); \n" +
222 " \n" +
223 "Equation defobj \n" +
224 " knapsack; \n" +
225 " \n" +
226 "defobj.. z =e= 1 - sum(i, demdual(i)*y(i)); \n" +
227 "knapsack.. sum(i, w(i)*y(i)) =l= r; \n" +
228 "model pricing /defobj, knapsack/; \n" +
229 " \n";
230}
231
GAMSModelInstance addModelInstance()
GAMSParameter getParameter(String identifier)
GAMSSet addSet(String identifier, int dimension)
GAMSEquation getEquation(String identifier)
GAMSParameter addParameter(String identifier, int dimension)
GAMSVariable getVariable(String identifier)
GAMSDatabase OutDB()
void instantiate(String modelDefinition, GAMSModifier ... modifiers)
void defines(String defStr, String asStr)
void setAllModelTypes(String value)
Iterator< T > iterator()
T findRecord(String ... keys)
T addRecord(Vector< String > keys)
void setSystemDirectory(String directory)
void setWorkingDirectory(String directory)
GAMSJob addJobFromString(String source)
GAMSCheckpoint addCheckpoint()
This example implements a column generation approach.
Definition: Cutstock.java:32
Provides package namespace for Java interface and examples to General Algebraic Model System (GAMS).
&#160;