1classdef CutstockModel < handle
3 properties (SetAccess =
private)
18 function obj = CutstockModel(ws)
21 obj.opt = ws.addOptions();
23 obj.cutstock_data = obj.ws.addDatabase('gdxincname');
25 obj.opt.defines('gdxincname', 'gdxincname');
26 obj.opt.defines('dbOut1', 'dbOut1');
27 obj.opt.solveLink = gams.control.options.SolveLink.LoadLibrary;
29 obj.widths = obj.cutstock_data.addSet('i', 'widths');
30 obj.raw_width = obj.cutstock_data.addParameter('r', 'raw width');
31 obj.demand = obj.cutstock_data.addParameter('d', 'demand', obj.widths);
32 obj.width = obj.cutstock_data.addParameter('w', 'width', obj.widths);
34 obj.job = obj.ws.addJobFromString(obj.modelSource());
37 function run(obj, output)
38 if ~obj.cutstock_data.checkDomains()
39 error('Domain Errors in Cutstock Database');
43 obj.job.run(obj.opt, false, obj.cutstock_data);
45 obj.job.run(obj.opt, output, false, obj.cutstock_data);
47 obj.dbout = obj.ws.addDatabaseFromGDX([obj.opt.getDefinitionOf('dbOut1'), '.gdx']);
48 obj.pat_rep = obj.dbout.getParameter('patrep');
51 function model = modelSource(obj)
53 '$Title Cutting Stock - A Column Generation Approach (CUTSTOCK,SEQ=294) '
56 'The task is to cut out some paper products of different sizes from a '
57 'large raw paper roll, in order to meet a customer''s order. The objective '
58 'is to minimize the required number of paper rolls. '
60 'P. C. Gilmore and R. E. Gomory, A linear programming approach to the '
61 'cutting stock problem, Part I, Operations Research 9 (1961), 849-859. '
63 'P. C. Gilmore and R. E. Gomory, A linear programming approach to the '
64 'cutting stock problem, Part II, Operations Research 11 (1963), 863-888. '
73 '$if not set gdxincname $abort ''no include file name for data file provided'''
74 '$gdxin %gdxincname% '
78 '* Gilmore-Gomory column generation algorithm '
80 'Set p possible patterns /p1*p1000/ '
81 ' pp(p) dynamic subset of p '
83 ' aip(i,p) number of width i in pattern growing in p; '
86 'Variable xp(p) patterns used '
87 ' z objective variable '
88 'Integer variable xp; xp.up(p) = sum(i, d(i)); '
90 'Equation numpat number of patterns used '
91 ' demand(i) meet demand; '
93 'numpat.. z =e= sum(pp, xp(pp)); '
94 'demand(i).. sum(pp, aip(i,pp)*xp(pp)) =g= d(i); '
96 'model master /numpat, demand/; '
98 '* Pricing problem - Knapsack model '
99 'Variable y(i) new pattern; '
100 'Integer variable y; y.up(i) = ceil(r/w(i)); '
103 ' knapsack knapsack constraint; '
105 'defobj.. z =e= 1 - sum(i, demand.m(i)*y(i)); '
106 'knapsack.. sum(i, w(i)*y(i)) =l= r; '
108 'model pricing /defobj, knapsack/; '
110 '* Initialization - the initial patterns have a single width '
111 'pp(p) = ord(p)<=card(i); '
112 'aip(i,pp(p))$(ord(i)=ord(p)) = floor(r/w(i)); '
115 'Scalar done loop indicator /0/ '
116 'Set pi(p) set of the last pattern; pi(p) = ord(p)=card(pp)+1; '
118 'option optcr=0,limrow=0,limcol=0,solprint=off; '
120 'While(not done and card(pp)<card(p), '
121 ' solve master using rmip minimizing z; '
122 ' solve pricing using mip minimizing z; '
124 '* pattern that might improve the master model found? '
126 ' aip(i,pi) = round(y.l(i)); '
127 ' pp(pi) = yes; pi(p) = pi(p-1); '
132 'display ''lower bound for number of rolls'', master.objval; '
134 'option solprint=on; '
135 'solve master using mip minimizing z; '
137 'Parameter patrep Solution pattern report '
138 ' demrep Solution demand supply report; '
140 'patrep(''# produced'',p) = round(xp.l(p)); '
141 'patrep(i,p)$patrep(''# produced'',p) = aip(i,p); '
142 'patrep(i,''total'') = sum(p, patrep(i,p)); '
143 'patrep(''# produced'',''total'') = sum(p, patrep(''# produced'',p)); '
145 'demrep(i,''produced'') = sum(p,patrep(i,p)*patrep(''# produced'',p)); '
146 'demrep(i,''demand'') = d(i); '
147 'demrep(i,''over'') = demrep(i,''produced'') - demrep(i,''demand''); '
149 'display patrep, demrep; '
150 '$if not set dbOut1 $abort ''no file name for out-database 1 file provided'''
151 'execute_unload ''%dbOut1%'', patrep; '
153 model = sprintf(
'%s\n', model{:});