1function cutstock(varargin)
3 % check workspace info from arguments
5 wsInfo = gams.control.WorkspaceInfo();
6 wsInfo.systemDirectory = varargin{1};
7 ws = gams.control.Workspace(wsInfo);
9 ws = gams.control.Workspace();
12 % instantiate Options and define parameters
13 opt = ws.addOptions();
14 cutstockData = ws.addDatabase(
'csdata');
15 opt.setAllModelTypes(
'Cplex');
16 opt.optCR = 0; % Solve to optimality
18 opt.defines(
'pmax', sprintf(
'%d', maxpattern));
19 opt.defines(
'solveMasterAs',
'RMIP');
22 d = containers.Map({
'i1',
'i2',
'i3',
'i4'}, {97, 610, 395, 211});
23 w = containers.Map({
'i1',
'i2',
'i3',
'i4'}, {45, 36, 31, 14});
26 widths = cutstockData.addSet(
'i', 1,
'widths');
27 rawWidth = cutstockData.addParameter(
'r', 0,
'raw width');
28 demand = cutstockData.addParameter(
'd', 1,
'demand');
29 width = cutstockData.addParameter(
'w', 1,
'width');
32 widths.addRecord(key{1});
33 rec = demand.addRecord(key{1});
34 rec.value = d(key{1});
37 rec = width.addRecord(key{1});
38 rec.value = w(key{1});
40 rec = rawWidth.addRecord();
44 '$Title Cutting Stock - Master problem '
55 '$if not set pmax $set pmax 1000 '
56 'Set p possible patterns /1*%pmax%/ '
57 ' pp(p) dynamic subset of p '
59 ' aip(i,p) number of width i in pattern growing in p;'
62 'Variable xp(p) patterns used '
63 ' z objective variable '
64 'Integer variable xp; xp.up(p) = sum(i, d(i)); '
66 'Equation numpat number of patterns used '
67 ' demand(i) meet demand; '
69 'numpat.. z =e= sum(pp, xp(pp)); '
70 'demand(i).. sum(pp, aip(i,pp)*xp(pp)) =g= d(i); '
72 'model master /numpat, demand/; '
74 masterModel = sprintf(
'%s\n', masterModel{:});
77 '$Title Cutting Stock - Pricing problem is a knapsack model '
89 ' demdual(i) duals of master demand constraint /#i eps/; '
91 'Variable z, y(i) new pattern; '
92 'Integer variable y; y.up(i) = ceil(r/w(i)); '
97 'defobj.. z =e= 1 - sum(i, demdual(i)*y(i)); '
98 'knapsack.. sum(i, w(i)*y(i)) =l= r; '
99 'model pricing /defobj, knapsack/; '
101 subModel = sprintf(
'%s\n', subModel{:});
103 % create initial checkpoint
104 masterCP = ws.addCheckpoint();
105 masterInitJob = ws.addJobFromString(masterModel);
106 masterInitJob.run(opt, masterCP, cutstockData);
108 masterJob = ws.addJobFromString(
'execute_load ''csdata'', aip, pp; solve master min z using %solveMasterAs%;', masterCP);
110 pattern = cutstockData.addSet(
'pp', 1,
'pattern index');
111 patternData = cutstockData.addParameter(
'aip', 2,
'pattern data');
113 % Initial pattern: pattern i hold width i
116 patternCount = patternCount + 1;
117 patternCount_str = sprintf(
'%d', patternCount);
118 pattern.addRecord(patternCount_str);
119 rec = patternData.addRecord(key{1}, patternCount_str);
120 rec.value = floor(r / w(key{1}));
123 % create model instance
for sub job
124 subCP = ws.addCheckpoint();
125 ws.addJobFromString(subModel).run(opt, subCP, cutstockData);
127 subMI = subCP.addModelInstance();
129 % define modifier demdual
130 demandDual = subMI.syncDB.addParameter(
'demdual', 1,
'dual of demand from master');
131 subMI.instantiate(
'pricing min z using mip', opt, gams.control.Modifier(demandDual));
136 masterJob.run(opt, masterCP, cutstockData);
138 % Copy duals into gmssubMI.syncDB DB
140 for d = masterJob.outDB.getEquation(
'demand').records
141 rec = demandDual.addRecord(d{1}.key(1));
142 rec.value = d{1}.marginal;
147 z_level = subMI.syncDB.getVariable(
'z').record.level;
148 if z_level < -0.00001
149 if patternCount == maxpattern
150 fprintf('Out of pattern. Increase maxpattern (currently [%d])\n', maxpattern);
151 patternAdded =
false;
153 fprintf(
'New pattern Value: %g\n', z_level);
154 patternCount = patternCount + 1;
155 s = pattern.addRecord(sprintf(
'%d', patternCount));
156 for y = subMI.syncDB.getVariable(
'y').records
158 rec = patternData.addRecord(y{1}.key(1), s.key(1));
159 rec.value = round(y{1}.level);
164 patternAdded =
false;
169 opt.defines(
"solveMasterAs",
"MIP");
170 masterJob.run(opt, cutstockData);
172 fprintf(
"Optimal Solution: %g\n", masterJob.outDB.getVariable(
"z").record.level);
173 for xp = masterJob.outDB.getVariable(
"xp").records
175 fprintf(
" pattern [%s] [%g] times: ", xp{1}.key(1), xp{1}.level);
176 for aip = masterJob.outDB.getParameter(
"aip").records
177 fprintf(
" [%s] : [%g]\n", aip{1}.key(1), aip{1}.value);
183 % clean up of unmanaged resources
184 cutstockData.dispose();