kishorkukreja/awesome-supply-chain/1d-cutting-stock

Claude Code and agent skill by kishorkukreja/awesome-supply-chain

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

When the user wants to cut 1D materials optimally, minimize waste in linear cutting, or solve one-dimensional cutting stock problems. Also use when the user mentions "1D cutting," "linear cutting optimization," "rod cutting," "pipe cutting," "beam cutting," "trim loss," "cutting stock problem," "pattern generation," or "column generation for cutting." For 2D problems, see 2d-cutting-stock. For general trim loss, see trim-loss-minimization.

Install

npx vskill@latest install kishorkukreja/awesome-supply-chain/1d-cutting-stock

SKILL.md

1D Cutting Stock Problem

You are an expert in one-dimensional cutting stock problems and linear cutting optimization. Your goal is to help minimize material waste and costs when cutting standard-length stock materials (pipes, rods, beams, paper rolls, etc.) into smaller pieces to meet customer demand.

Initial Assessment

Before solving 1D cutting stock problems, understand:

  1. Problem Characteristics
  • What material is being cut? (steel rods, pipes, lumber, paper, fabric)
  • Standard stock lengths available? (e.g., 6m, 12m, custom lengths)
  • Are multiple stock lengths available or single length?
  • Cost per stock piece or per unit length?
  1. Demand Requirements
  • How many different item lengths needed?
  • Quantity of each length? (10s, 100s, 1000s)
  • Complete list of (length, quantity) pairs?
  • Any tolerance on lengths (+/- allowance)?
  1. Cutting Constraints
  • Minimum usable piece length?
  • Maximum number of cuts per stock?
  • Kerf width (saw blade thickness/material lost per cut)?
  • Any setup costs for different cutting patterns?
  1. Optimization Objective
  • Minimize number of stock pieces used?
  • Minimize total material cost?
  • Minimize trim waste percentage?
  • Maximize utilization?
  1. Solution Requirements
  • Need exact optimal solution or fast approximation?
  • Real-time cutting (online) or batch planning (offline)?
  • Can patterns be complex or need simplicity?

1D Cutting Stock Framework

Problem Classification

1. Classical Cutting Stock Problem (CSP)

  • Single stock length
  • Multiple item lengths with demands
  • Minimize number of stocks used
  • Minimize waste

2. Multiple Stock Lengths Problem

  • Different stock lengths available
  • Each has different cost
  • Minimize total cost (not just quantity)

3. Residual Length Problem

  • Previously cut stocks with residual lengths available
  • Use residuals before cutting new stocks
  • Minimize total material consumption

4. Cutting Stock with Setup Costs

  • Each distinct cutting pattern has setup cost
  • Minimize stocks used + pattern complexity
  • Trade-off between waste and setups

5. Two-Stage Cutting

  • First cut stocks into intermediate pieces
  • Then cut intermediates into final items
  • Common in integrated production

Mathematical Formulation

Classical Cutting Stock Problem

Given:

  • L = standard stock length
  • n = number of item types
  • l_i = length of item type i (i = 1, ..., n)
  • d_i = demand for item type i

Pattern Definition: A cutting pattern j is a vector a_j = (a_1j, a_2j, ..., a_nj) where:

  • a_ij = number of items of type i cut from pattern j
  • Σ(l_i × a_ij) ≤ L (pattern feasibility)

Decision Variables:

  • x_j = number of times pattern j is used

Objective: Minimize Σ x_j (minimize total stocks used)

Constraints: Σ(a_ij × x_j) ≥ d_i for all i = 1, ..., n (meet demand) x_j ≥ 0, integer

Key Challenge:

  • Number of possible patterns is exponential
  • Cannot enumerate all patterns explicitly
  • Requires column generation technique

Algorithms and Solution Methods

Method 1: First Fit Decreasing (FFD) - Simple Heuristic
python
def first_fit_decreasing(items, stock_length):
"""
First Fit Decreasing Heuristic for 1D Cutting Stock
Fast greedy algorithm - good for quick solutions
Parameters:
- items: list of (length, quantity, item_id) tuples
- stock_length: length of standard stock
Returns: cutting plan with patterns
Performance: Typically 10-30% above optimal
Complexity: O(n log n + nk) where k = number of stocks used
"""
# Expand items by quantity and sort by decreasing length
pieces = []
for length, quantity, item_id in items:
for _ in range(quantity):
pieces.append((length, item_id))
pieces.sort(reverse=True, key=lambda x: x[0])
# Initialize bins (stocks)
stocks = []
for piece_length, item_id in pieces:
# Try to fit in existing stock
placed = False
for stock in stocks:
if stock['remaining'] >= piece_length:
stock['items'].append({
'length': piece_length,
'id': item_id
})
stock['remaining'] -= piece_length
placed = True
break
# Need new stock
if not placed:
new_stock = {
'items': [{
'length': piece_length,
'id': item_id
}],
'remaining': stock_length - piece_length
}
stocks.append(new_stock)
# Calculate statistics
total_used = sum(stock_length - s['remaining'] for s in stocks)
total_available = len(stocks) * stock_length
utilization = (total_used / total_available * 100) if total_available > 0 else 0
return {
'num_stocks': len(stocks),
'stocks': stocks,
'utilization': utilization,
'waste': total_available - total_used
}
# Example usage
items = [
(2300, 5, 'A'), # 5 pieces of 2300mm
(1500, 8, 'B'), # 8 pieces of 1500mm
(1200, 12, 'C'), # 12 pieces of 1200mm
(800, 6, 'D') # 6 pieces of 800mm
]
stock_length = 6000
result = first_fit_decreasing(items, stock_length)
print(f"Stocks needed: {result['num_stocks']}")
print(f"Utilization: {result['utilization']:.2f}%")
print(f"Waste: {result['waste']}mm")
Method 2: Best Fit Decreasing (BFD) - Improved Heuristic
python
def best_fit_decreasing(items, stock_length):
"""
Best Fit Decreasing Heuristic
Better than FFD - finds tightest fit to minimize waste
Parameters:
- items: list of (length, quantity, item_id) tuples
- stock_length: length of standard stock
Returns: cutting plan
Performance: Typically 5-20% above optimal
"""
# Expand and sort pieces
pieces = []
for length, quantity, item_id in items:
for _ in range(quantity):
pieces.append((length, item_id))
pieces.sort(reverse=True, key=lambda x: x[0])
stocks = []
for piece_length, item_id in pieces:
# Find best fitting stock (minimum remaining space after placement)
best_stock_idx = None
min_remaining = float('inf')
for idx, stock in enumerate(stocks):
if stock['remaining'] >= piece_length:
remaining_after = stock['remaining'] - piece_length
if remaining_after < min_remaining:
min_remaining = remaining_after
best_stock_idx = idx
if best_stock_idx is not None:
# Place in best fitting stock
stocks[best_stock_idx]['items'].append({
'length': piece_length,
'id': item_id
})
stocks[best_stock_idx]['remaining'] -= piece_length
else:
# Create new stock
new_stock = {
'items': [{
'length': piece_length,
'id': item_id
}],
'remaining': stock_length - piece_length
}
stocks.append(new_stock)
# Calculate statistics
total_used = sum(stock_length - s['remaining'] for s in stocks)
total_available = len(stocks) * stock_length
return {
'num_stocks': len(stocks),
'stocks': stocks,
'utilization': (total_used / total_available * 100) if total_available > 0 else 0,
'waste': total_available - total_used
}
Method 3: Column Generation - Optimal Solution
python
from pulp import *
import numpy as np
class ColumnGenerationCuttingStock:
"""
Column Generation for 1D Cutting Stock Problem
Finds optimal or near-optimal solution using:
1. Master Problem (LP): Select best patterns
2. Pricing Problem (Knapsack): Generate new profitable patterns
This is the state-of-the-art exact method for cutting stock
"""
def __init__(self, stock_length, items, kerf=0):
"""
Initialize cutting stock problem
Parameters:
- stock_length: length of standard stock
- items: list of (length, demand, item_id) tuples
- kerf: material lost per cut (saw blade width)
"""
self.stock_length = stock_length
self.items = items
self.kerf = kerf
self.n_items = len(items)
# Extract lengths and demands
self.lengths = [item[0] for item in items]
self.demands = [item[1] for item in items]
self.item_ids = [item[2] for item in items]
# Storage for patterns
self.patterns = []
self.pattern_count = 0
def generate_initial_patterns(self):
"""
Generate initial patterns (one item type per pattern)
Each pattern cuts maximum number of one item type
"""
initial_patterns = []
for i in range(self.n_items):
pattern = [0] * self.n_items
# Maximum number of item i that fits in one stock
max_fit = int(self.stock_length / (self.lengths[i] + self.kerf))
pattern[i] = max_fit
initial_patterns.append(pattern)
self.patterns = initial_patterns
return initial_patterns
def solve_master_problem(self):
"""
Solve Master Problem (Restricted)
Linear Programming Relaxation:
Minimize Σ x_j
Subject to: Σ(a_ij × x_j) ≥ d_i for all i
x_j ≥ 0
Returns: solution and dual values
"""
prob = LpProblem("Cutting_Stock_Master", LpMinimize)
# Decision variables: x_j = number of times pattern j is used
num_patterns = len(self.patterns)
x = [LpVariable(f"x_{j}", lowBound=0, cat='Continuous')
for j in range(num_patterns)]
# Objective: minimize total stocks used
prob += lpSum(x), "Total_Stocks"
# Constraints: meet demand for each item type
constraints = []
for i in range(self.n_items):
constraint = lpSum(self.patterns[j][i] * x[j]
for j in range(num_patterns)) >= self.demands[i]
prob += constraint, f"Demand_{i}"
constraints.append(constraint)
# Solve
prob.solve(PULP_CBC_CMD(msg=0))
# Extract solution
solution = {
'objective': value(prob.objective),
'pattern_usage': [x[j].varValue for j in range(num_patterns)],
'status': LpStatus[prob.status]
}
# Extract dual values (shadow prices)
dual_values = []
for i in range(self.n_items):
constraint_name = f"Demand_{i}"
for name, constraint in prob.constraints.items():
if constraint_name in name:
dual_values.append(constraint.pi)
break
solution['dual_values'] = dual_values
return solution
def solve_pricing_problem(self, dual_values):
"""
Solve Pricing Problem (Knapsack)
Find new pattern with negative reduced cost:
max Σ(π_i × a_i)
subject to: Σ(l_i × a_i) ≤ L
a_i ≥ 0, integer
This is a 0/1 knapsack variant (unbounded knapsack)
Parameters:
- dual_values: dual values from master problem (π_i)
Returns: new pattern if found, None otherwise
"""
# Solve unbounded knapsack
# dp[w] = maximum value achievable with weight w
capacity = self.stock_length
dp = [0] * (capacity + 1)
item_used = [[-1, 0] for _ in range(capacity + 1)] # [item_idx, count]

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
74
Repository forks
18
7-day trend score
22

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/kishorkukreja/awesome-supply-chain/1d-cutting-stock/badge)](https://verified-skill.com/skills/kishorkukreja/awesome-supply-chain/1d-cutting-stock)

Something wrong with this skill or its page? Tell us.