# factory 项目优化算法切入点分析

> 目的：盘点 factory（玻纤/玻璃管制品生产管理系统）中可以引入运筹学/优化算法的环节，
> 作为学习与逐步改造的路线图。
> 结论先说：**当前系统几乎全是 CRUD + 简单规则，尚无真正意义上的优化算法；
> 但多个环节的业务模型已铺好地基，只差把"平均分摊/手工填报"换成"求最优"。**

---

## 一、优化点总览（按投入产出比排序）

| 优先级 | 环节 | 当前实现 | 可引入算法 | 主要落点 |
|:---:|---|---|---|---|
| ★★★ | 生产排产调度 | 总量除天数/工段数，平均分摊 | 多机调度 / FJSP / CP-SAT | `apps/pm/services.py:157` |
| ★★★ | 安全库存补货 | 字段已备但只做预警，采购纯手工 | (s,S) / EOQ / MILP | `apps/mtm/models.py:101`、`apps/pum` |
| ★★ | 合批/批次合并决策 | 追溯完善，合批时机靠人工 | 凑批/批量合并优化 | `apps/wpm/models.py:667,876` |
| ★★ | 装箱/配载 | Pack 模型预留但未启用 | bin-packing / 配载 | `apps/inm/models.py:140,195` |
| ★ | 人员-工段指派排班 | 班次静态查表，考勤手工 | 指派问题 / min-cost flow | `apps/mtm/models.py:149`、`apps/hrm` |
| ★ | 一维下料/切割 | 仅数量层"切分工序"，无几何排样 | cutting-stock（需确认定尺需求） | `apps/mtm/models.py:22` |

---

## 二、逐项详解

### 1. 生产排产调度 ★★★（最核心，最值得动）

**当前怎么做**（`apps/pm/services.py:157` `PmService.schedue_mtasks`）：

- 排到天：`task_count_day = math.ceil(count / rela_days)` —— 总量除以天数，平摊。
- 排到工段：`base_demand = count // mgroups_count`，余数依次 +1 —— 均分到同工序的多个工段。
- 留了明确的坑：同一工序有多个工段时，`to_day` 模式**直接报错**"工段存在多个"（`services.py:243`），
  注释写着"先平均分配"（`services.py:240`）。

**差在哪**：

- `Mtask` 有 `priority`（优先级 10/20/30，`pm/models.py:40`）、`start_date/end_date`（交期）。
- `Route` 有 `hour_work`（工时）、`out_rate`（出材率）、`div_number`（切分数）。
- 工艺是完整的 DAG（`mtm/models.py:480` `Route.validate_dag`，BFS 可达 + DFS 环检测）。
- **以上字段排产逻辑几乎都没用**：平摊既不看产能、不看交期、不看各工段现有负载。
- 相关：`cal_x_task_count()`（`services.py:17`）做 BOM/工艺 DAG 逆向物料需求展开（类 MRP 反算），
  多路线时同样是"平均分配需求"（`services.py:51`）。

**能上什么算法**：

- 入门：**带约束的负载均衡指派**（填那个"多工段平均分配"的坑）——把 N 件产品分到 M 个工段，
  让各工段完工时间最均衡。LPT 贪心 / 多机调度，几十行搞定。
- 进阶：**有限产能排程（FJSP，柔性作业车间调度）**——考虑交期、优先级、工段日产能上限。
  用 OR-Tools 的 CP-SAT 建模是这个领域最标准的练手项目。

**落点**：`apps/pm/services.py:240` 与 `:356` 的"平均分配"分支。

**缺口提示**：目前只有 `hour_work`（单工序工时），**没有设备/工段日产能上限模型**，
排产不校验产能——要做有限能力排程需先补一个产能字段/表。

---

### 2. 安全库存补货 + 采购联动 ★★★（字段已备而未用，最"干净"的起步点）

**当前**：

- `Material` 上已有 `count_safe`（下限）、`count_safe_upper`（上限）、
  `week_esitimate_consume`（周消耗预估）三个字段（`apps/mtm/models.py:101-103`）。
- 但**只用来做低库存筛选预警**（`apps/mtm/filters.py:40`，过滤 `count <= count_safe`）。
- 采购计划是各部门**纯手工填报**（`apps/pum/models.py:103` `PuPlanItem`，注释"因为各部门填写"）。
- `count_safe_upper` 和 `week_esitimate_consume` 已备但排产/采购都未消费。

**能上什么算法**：

- **(s, S) 再订货点 / EOQ 经济订货批量**——字段都齐了，直接算"什么时候补、补多少最省"。
  运筹学入门第一课，最适合起步。
- 进阶：多物料需求汇总 + 供应商分批下单优化（MILP）。

**落点**：新增一个 service，消费 `count_safe_upper` + `week_esitimate_consume` + 在途量。
改动面最小、最独立，适合作为第一个完整跑通的 POC。

---

### 3. 合批 / 批次合并决策 ★★（追溯完善，决策靠人工）

- 拆合批**追溯**系统已很重：`Handover`（`wpm/models.py:667`，含分批/合批类型）、
  `BatchSt`（`:786`）、`BatchLog`（`:876`，split/merge DAG）、直通率回溯脚本
  `apps/wpm/scripts/batch_gxerp.py`（480+ 行）。
- 但"谁跟谁合、合多少"完全是现场操作工触发，**无自动合批决策**。
- 可做**凑批/合批批量优化**（把零散小批凑成满批，减少批次数/换型）。业务耦合深，建议靠后。

---

### 4. 装箱 / 配载 ★★（一块空地）

- `inm.Pack` 装箱模型建了但字段注释写着"暂时不用"（`apps/inm/models.py:195`）。
- 发货由 MIO 记录（`type='sale_out'`），**无按订单/车辆的配载组合逻辑**。
- 经典 **bin-packing / 装箱问题**，从零引入的好场景；但业务还没启用，属"锦上添花"。

---

### 5. 人员-工段指派排班 ★（班次静态查表）

- 班次/班组是静态主数据（`Shift` `mtm/models.py:149`、`Srule` `:161`、`Team` `:168`）。
- `Mgroup.get_shift()`（`:209`）只是按打卡时间**查表匹配**（含跨天夜班判断），
  考勤靠手工登记（`apps/hrm/serializers.py:288`）。
- 无"把人/班组最优指派到工段/工序"的逻辑。经典**指派问题（匈牙利算法 / min-cost flow）**，
  但需求不明确，优先级低。

---

### 6. 一维下料 / 切割 ★（需确认业务）

- 工序有 `PRO_DIV=20 切分` / `PRO_MERGE=30 合并`（`apps/mtm/models.py:22`），
  排产反算里按 `div_number` 做数量换算（`pm/services.py:62`）。
- 这是**数量层面的切分，不是几何排样**（没有"原料长度→切割方案最小余料"的 cutting-stock 模型）。
- 若产品有定尺切割需求，才是引入一维/二维下料优化的场景——需先确认。

---

## 三、建议的学习路线

目标：边练算法边给系统带来真实价值。建议顺序：

| 阶段 | 做什么 | 学到的算法 | 难度 |
|---|---|---|---|
| **起步** | #2 安全库存自动补货 | (s,S) / EOQ、贪心 | ⭐ 改动独立、立竿见影 |
| **进阶** | #1 把"多工段平均分配"改成负载均衡 | LPT 贪心、多机调度 | ⭐⭐ 有现成坑可填 |
| **登顶** | #1 用 OR-Tools CP-SAT 做有限产能排程 | 约束规划、FJSP | ⭐⭐⭐ 行业标准练手项目 |

**工具推荐**：Google **OR-Tools**（CP-SAT 求解器），Python 生态里做排产/装箱/指派最主流的库，中文资料多。

---

## 四、关键文件索引

- 排产核心：`apps/pm/services.py:17`（MRP反算）、`:116`（订单→大任务）、`:157`（大任务→小任务）
- 任务模型：`apps/pm/models.py:19`（Utask）、`:71`（Mtask，含 priority）
- 工艺 DAG：`apps/mtm/models.py:294`（RoutePack）、`:480`（validate_dag）
- 工序/路线：`apps/mtm/models.py:12`（Process）、`:422`（Route）
- 安全库存：`apps/mtm/models.py:101-103`、`apps/mtm/filters.py:40`、`apps/mtm/views.py:86`
- 采购：`apps/pum/models.py:32`（PuPlan）、`:101`（PuPlanItem）
- 拆合批：`apps/wpm/models.py:667,786,876`；脚本 `apps/wpm/scripts/batch_gxerp.py`
- 装箱：`apps/inm/models.py:140,193,195`
- 排班/班次：`apps/mtm/models.py:149,161,209`、`apps/hrm/models.py:147`
