Skip to main content

Cutting Stock Problem

Cutting Stock

A classic application of Dantzig-Wolfe Decomposition where the pricing sub-problem is a knapsack problem and column generation produces optimal cutting patterns.

Problem Description

A paper mill receives orders for rolls of paper of varying widths. The mill produces large master rolls of a fixed width WW. Each master roll must be cut into smaller rolls to fill a set of orders. The goal is to minimise the number of master rolls used (equivalently, to minimise waste) while satisfying all orders.

Notation (all symbols defined here, before first use):

WW
Width of a master roll.
nn
Number of distinct order widths.
wiw_i

Width of order ii, for i=1,,ni = 1, \ldots, n.

did_i

Demand (number of rolls required) for order ii.

aija_{ij}

Number of rolls of width wiw_i produced by cutting pattern jj.

xjx_j

Number of times cutting pattern jj is used.

mm
Number of feasible cutting patterns (exponentially large).

A cutting pattern is a feasible assignment of widths to a master roll:

i=1nwiaijW,aijZ0\sum_{i=1}^{n} w_i a_{ij} \le W, \quad a_{ij} \in \mathbb{Z}_{\ge 0}.

Block-Angular LP Formulation

The cutting stock problem can be stated as:

minj=1mxjs.t.j=1maijxjdii=1,,n(coupling constraints)xj0,xjZ+j\begin{aligned} \min \quad & \sum_{j=1}^{m} x_j \\ \text{s.t.} \quad & \sum_{j=1}^{m} a_{ij} x_j \ge d_i \quad \forall i = 1, \ldots, n \quad \text{(coupling constraints)} \\ & x_j \ge 0, \quad x_j \in \mathbb{Z}_+ \quad \forall j \end{aligned}

The LP relaxation sets xj0x_j \ge 0 (replacing integrality). Because there are exponentially many patterns mm, this LP cannot be solved by enumerating all columns — Dantzig-Wolfe Decomposition via column generation is the key technique.

Dantzig-Wolfe Master Problem

Introduce dual variables πi0\pi_i \ge 0 for each demand constraint. The restricted master problem (RMP) maintains only a subset of columns J{1,,m}J \subseteq \{1, \ldots, m\}:

minjJxjs.t.jJaijxjdiixj0jJ\begin{aligned} \min \quad & \sum_{j \in J} x_j \\ \text{s.t.} \quad & \sum_{j \in J} a_{ij} x_j \ge d_i \quad \forall i \\ & x_j \ge 0 \quad \forall j \in J \end{aligned}

At each iteration, solve the RMP and obtain dual variables πi\pi_i^*.

Role of dual variables: πi\pi_i^* is the shadow price of demand ii — the marginal reduction in total rolls used if demand ii were increased by one unit. These prices drive the column generation sub-problem.

Pricing Sub-Problem (Knapsack)

Check whether any currently unlisted pattern can improve the objective. The reduced cost of a new pattern a=(a1,,an)Ta = (a_1, \ldots, a_n)^T is:

cˉ(a)=1i=1nπiai\bar{c}(a) = 1 - \sum_{i=1}^{n} \pi_i^* a_i

We seek a pattern with negative reduced cost — i.e., one that reduces total rolls. This is equivalent to solving a 0-1 knapsack problem:

maxi=1nπiais.t.i=1nwiaiWaiZ0i\begin{aligned} \max \quad & \sum_{i=1}^{n} \pi_i^* a_i \\ \text{s.t.} \quad & \sum_{i=1}^{n} w_i a_i \le W \\ & a_i \in \mathbb{Z}_{\ge 0} \quad \forall i \end{aligned}

If maxiπiai>1\max \sum_i \pi_i^* a_i > 1, a new improving column exists and is added to the RMP. Otherwise, the RMP is optimal.

Numerical Iteration (Example)

Consider n=2n = 2 order widths, W=10W = 10, w1=4w_1 = 4, w2=3w_2 = 3, d1=3d_1 = 3, d2=5d_2 = 5.

Initial patterns: Let p1=(2,0)Tp_1 = (2, 0)^T (two rolls of width 4) and p2=(0,3)Tp_2 = (0, 3)^T (three rolls of width 3).

Iteration 1:

  • Solve RMP with {p1,p2}\{p_1, p_2\}.
  • Obtain duals π1=0.5\pi_1^* = 0.5, π2=0.333\pi_2^* = 0.333.
  • Knapsack: maximise 0.5a1+0.333a20.5 a_1 + 0.333 a_2 subject to 4a1+3a2104a_1 + 3a_2 \le 10.
  • Optimal solution: a1=1,a2=2a_1 = 1, a_2 = 2 giving value 0.5+0.667=1.167>10.5 + 0.667 = 1.167 > 1.
  • Add new pattern p3=(1,2)Tp_3 = (1, 2)^T.

Iteration 2:

  • Re-solve RMP with {p1,p2,p3}\{p_1, p_2, p_3\}.
  • Updated duals and check knapsack again.
  • If no pattern achieves reduced cost <0< 0, LP is optimal.

Citation

Gilmore, P. C., & Gomory, R. E. (1961). A linear programming approach to the cutting-stock problem . Operations Research, 9(6), 849–859. doi:10.1287/opre.9.6.849