Loading...
Searching...
No Matches
CutstockModel.m
1classdef CutstockModel < handle
2
3 properties (SetAccess = private)
4 widths
5 raw_width
6 demand
7 width
8 pat_rep
9 ws
10 cutstock_data
11 dbout
12 opt
13 job
14 end
15
16 methods
17
18 function obj = CutstockModel(ws)
19
20 obj.ws = ws;
21 obj.opt = ws.addOptions();
22
23 obj.cutstock_data = obj.ws.addDatabase('gdxincname');
24
25 obj.opt.defines('gdxincname', 'gdxincname');
26 obj.opt.defines('dbOut1', 'dbOut1');
27 obj.opt.solveLink = gams.control.options.SolveLink.LoadLibrary;
28
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);
33
34 obj.job = obj.ws.addJobFromString(obj.modelSource());
35 end
36
37 function run(obj, output)
38 if ~obj.cutstock_data.checkDomains()
39 error('Domain Errors in Cutstock Database');
40 end
41
42 if isempty(output)
43 obj.job.run(obj.opt, false, obj.cutstock_data);
44 else
45 obj.job.run(obj.opt, output, false, obj.cutstock_data);
46 end
47 obj.dbout = obj.ws.addDatabaseFromGDX([obj.opt.getDefinitionOf('dbOut1'), '.gdx']);
48 obj.pat_rep = obj.dbout.getParameter('patrep');
49 end
50
51 function model = modelSource(obj)
52 model = {
53 '$Title Cutting Stock - A Column Generation Approach (CUTSTOCK,SEQ=294) '
54 ' '
55 '$ontext '
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. '
59 ' '
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. '
62 ' '
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. '
65 '$offtext '
66 ' '
67 'Set i widths '
68 'Parameter '
69 ' r raw width '
70 ' w(i) width '
71 ' d(i) demand ; '
72 ' '
73 '$if not set gdxincname $abort ''no include file name for data file provided'''
74 '$gdxin %gdxincname% '
75 '$load r i w d '
76 '$gdxin '
77 ' '
78 '* Gilmore-Gomory column generation algorithm '
79 ' '
80 'Set p possible patterns /p1*p1000/ '
81 ' pp(p) dynamic subset of p '
82 'Parameter '
83 ' aip(i,p) number of width i in pattern growing in p; '
84 ' '
85 '* Master model '
86 'Variable xp(p) patterns used '
87 ' z objective variable '
88 'Integer variable xp; xp.up(p) = sum(i, d(i)); '
89 ' '
90 'Equation numpat number of patterns used '
91 ' demand(i) meet demand; '
92 ' '
93 'numpat.. z =e= sum(pp, xp(pp)); '
94 'demand(i).. sum(pp, aip(i,pp)*xp(pp)) =g= d(i); '
95 ' '
96 'model master /numpat, demand/; '
97 ' '
98 '* Pricing problem - Knapsack model '
99 'Variable y(i) new pattern; '
100 'Integer variable y; y.up(i) = ceil(r/w(i)); '
101 ' '
102 'Equation defobj '
103 ' knapsack knapsack constraint; '
104 ' '
105 'defobj.. z =e= 1 - sum(i, demand.m(i)*y(i)); '
106 'knapsack.. sum(i, w(i)*y(i)) =l= r; '
107 ' '
108 'model pricing /defobj, knapsack/; '
109 ' '
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)); '
113 '*display aip; '
114 ' '
115 'Scalar done loop indicator /0/ '
116 'Set pi(p) set of the last pattern; pi(p) = ord(p)=card(pp)+1; '
117 ' '
118 'option optcr=0,limrow=0,limcol=0,solprint=off; '
119 ' '
120 'While(not done and card(pp)<card(p), '
121 ' solve master using rmip minimizing z; '
122 ' solve pricing using mip minimizing z; '
123 ' '
124 '* pattern that might improve the master model found? '
125 ' if(z.l < -0.001, '
126 ' aip(i,pi) = round(y.l(i)); '
127 ' pp(pi) = yes; pi(p) = pi(p-1); '
128 ' else '
129 ' done = 1; '
130 ' ); '
131 '); '
132 'display ''lower bound for number of rolls'', master.objval; '
133 ' '
134 'option solprint=on; '
135 'solve master using mip minimizing z; '
136 ' '
137 'Parameter patrep Solution pattern report '
138 ' demrep Solution demand supply report; '
139 ' '
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)); '
144 ' '
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''); '
148 ' '
149 'display patrep, demrep; '
150 '$if not set dbOut1 $abort ''no file name for out-database 1 file provided'''
151 'execute_unload ''%dbOut1%'', patrep; '
152 ' '};
153 model = sprintf('%s\n', model{:});
154 end
155
156 end
157
158end