paper2skills Playbook

Multi-objective multi-site supplier selection and order splitting

Skill-Supplier-Capacity-Planning · 04-供应链

causalexperimentforecastingoptimizationpricing供应链与补货定价与利润WF-A 智能补货WF-D 选品扫描WF-F 动态定价
实现难度⭐⭐⭐☆☆
业务视角
适用角色供应链负责人 · 采购负责人 · CEO / 运营 VP
适用平台Amazon FBA · 海外仓 · 多国仓位(美/欧/日)
什么情况下用库存周转率低,资金压在海外仓出不来;SKU 断货紧急空运,物流成本吃掉毛利;多仓库存分布不均
成功是什么样的库存周转天数从 90 天降到 60 天,断货率 <3%,海外仓综合成本降低 15-25%
业务痛点
库存周转天数太长资金压死了断货了只能空运救急成本爆了多市场库存分配不均

1. 解决的问题

核心思想:当旺季需求(如双11前 8,000 件/月)超过工厂单月产能(5,000 件),需要解决三个问题:① 提前多久开始生产(提前期排程)?② 多供应商时如何分单(Pareto 前沿)?③ 产能完全满足不了时,哪个 SKU 优先(优先级排序)?

2. 核心算法逻辑

核心思想:当旺季需求(如双11前 8,000 件/月)超过工厂单月产能(5,000 件),需要解决三个问题:① 提前多久开始生产(提前期排程)?② 多供应商时如何分单(Pareto 前沿)?③ 产能完全满足不了时,哪个 SKU 优先(优先级排序)?

3. 业务应用场景

- 业务问题:吸奶器工厂月产能 5,000 件,8-10 月三个月需求分别为 6,500/8,000/4,000 件,总缺口 3,500 件。如何排产使缺货损失最小? - 预期产出:

场景 B:多供应商分单的 Pareto 决策

- 业务问题:主供(深圳工厂)vs 备供(广州工厂),成本低 15% 但历史延误率 22%,如何分配 2,000 件订单? - Pareto 分析输出:

4. 输入数据要求

请查看原始代码模板获取输入规格。

5. 输出结果

请查看原始代码模板获取输出规格。

6. 业务价值 / ROI

  • ROI 预估
  • 备供分单的最优 Pareto 点(70/30)vs 全主供:延误风险从 22% → 6%,期望缺货损失减少 $6,280/批次
  • 随机优化 vs MRP(满产场景):年节省 10-20% × $200K 季度采购 = $80,000-$160,000/年
  • 产能优先级排序:高毛利 SKU 优先保障,避免因低毛利 SKU 占产能导致主力 SKU 断货
  • 实施难度:⭐⭐⭐☆☆(3/5)— 需要供应商产能数据和历史延误率
  • 优先级评分:⭐⭐⭐⭐☆(4/5)— 旺季必用,平时可简化为 MRP

7. 代码模板

代码块数量:8 · 路径:paper2skills-code/supply_chain/supplier_capacity_planning

"""
Skill-Supplier-Capacity-Planning
基于 arXiv:2402.14506 (滚动排产随机优化) +
    IJPE 2024 (CLSP鲁棒vs随机决策树) +
    JIMO 2024 (多供应商Pareto分单)
母婴跨境 DTC 供应商产能约束下的生产排期与分单决策
"""

import numpy as np
from dataclasses import dataclass, field
from scipy import stats


@dataclass
class SupplierSpec:
    supplier_id: str
    monthly_capacity: int
    unit_cost: float
    lead_time_days: int
    delay_rate: float
    delay_days_avg: float = 5.0
    is_primary: bool = True

    @property
    def reliability_score(self) -> float:
        return 1.0 - self.delay_rate


@dataclass
class SKUPlan:
    sku_id: str
    monthly_demands: list[float]
    gross_margin: float
    bsr_rank: int
    demand_cv: float
    unit_price: float

    @property
    def priority_score(self) -> float:
        bsr_factor = max(0.1, 1.0 - self.bsr_rank / 200.0)
        cv_factor = max(0.5, 1.0 - self.demand_cv)
        return self.gross_margin * bsr_factor * cv_factor


def rolling_horizon_plan(
    skus: list[SKUPlan],
    monthly_capacity: int,
    horizon: int = 3,
    rush_premium_rate: float = 0.08,
) -> dict:
    """
    滚动视野排产:满产时按优先级分配产能,缺口触发备供。
    """
    monthly_plans = []
    for t in range(horizon):
        total_demand = sum(s.monthly_demands[t] for s in skus if t < len(s.monthly_demands))
        capacity_util = total_demand / monthly_capacity
        gap = max(0, total_demand - monthly_capacity)

        sorted_skus = sorted(skus, key=lambda s: -s.priority_score)

8. 论文来源

  • 2402.14506