1) 一眼看懂总流程(流程图)
输入表格(款名/颜色/总数)
|
v
标准化输入 -> items = [{name,color,total,rem}]
|
+--> 参数读取:TOL / LIMIT / BLANKS / GROUP_LIMIT / 减浪费参数
|
v
while (存在 rem > 0):
A. 可选回填:backfillToExistingBatches(...)
- 把当前剩余量插入已有组的“后续空白页”
- 满足最小连插页数、最小回填量
B. 新建一组(12坑位)
- USABLE = 12 - BLANKS
- 先用 rem 最小的款填每个可用坑
- 剩余坑用 rem 最大款补齐
C. 估算本组印张数 batchSize
- 初值:min(最小rem + TOL, LIMIT)
- 压力下限:pressureMinBatch = ceil(剩余总量 / (USABLE * 剩余目标组数))
- 取更优:pickBetterBatchSize(...) 追求利用率 ~ 90%
D. 按坑位分配数量
- 同款多个坑:平均分配 + 余数前置
- appendSlotSegment(...) 记录 start/end/pageStart/pageEnd
E. 若本组实际分配量=0,则退出;否则入 allBatchData
结束后:
renderAllBatches()
updateResultSummary()
updateAllocationCheck()
updateDistributionColumnFromBatches()
注:这里的“页”本质是该坑位序号段在该组内占用的印张跨度,不是文件分页。
2) 核心数据结构(表格)
| 对象 | 字段 | 作用 |
| 输入款 | `name / color / total / rem` | `rem` 是未分配剩余量,算法每轮递减 |
| 组 | `id / size / slots[12]` | `size` 是本组估算印张数(每坑可覆盖的最大页幅) |
| 坑位 | `slot.segments[]` | 一个坑可由多个分段组成(尤其回填后) |
| 分段 | `start/end/qty/pageStart/pageEnd` | NO号段范围与占用页范围,用于渲染与导出 |
3) 关键参数怎么影响结果
| 参数 | 影响方向 | 经验建议 | 快捷操作 |
| `TOL`? | 越大越倾向增大每组印张数 | 2-5 常用,过大可能浪费增多 | |
| `LIMIT`? | 越小组数越多,越大组数可能更少 | 按生产上限设硬边界 | |
| `BLANKS`? | 越大可用坑越少,组数通常上升 | 除非工艺要求,否则尽量低 | |
| `GROUP_LIMIT`? | 目标越小,batchSize 压力越大 | 可当“优化目标”而非绝对强裁 | |
| `SPLIT_CONTROL`? | 越小越防拆分;越大越偏吞吐/可拆分 | 建议 40-80;想少拆可设 0-30 | |
| `REDUCE_WASTE_LEVEL`? | 越高越优先回填旧组空白 | 建议 55-75;追求极低浪费可到 85+ | |
| 减少浪费 / 回填 | 优先利用已有组剩余页,减少新组 | 需要细调时再改下方两个高级参数 | |
提示:点击“填入推荐”或表格里的快捷按钮,会直接写入顶部参数框。
4) 每轮分配的细节步骤(非常详细)
- 筛 activeItems:取 `rem > 0` 的款,按 `rem` 升序;目的是优先照顾小尾款,避免末期碎片化。
- 构造 slots:先“一款一坑”填到 `USABLE`;若还有坑,用 `rem` 最大款重复占坑,提升大款吞吐。
- 算 batchSize 初值:`min(active最小rem + TOL, LIMIT)`。
- 压力下限:根据“剩余总量 / (可用坑 * 剩余目标组数)”算出必须达到的最小批量,避免后续组数超标。
- 利用率微调:`pickBetterBatchSize` 会尝试从当前值向下找更优,目标利用率约 90%。
- 同款多坑均分:若某款占了 N 个坑,先算总可拿量,再 `floor` 平均,余数从前几个坑+1。
- 写入 segment:通过 `appendSlotSegment` 记录 NO 段与页段,同时扣减 `item.rem`。
- 收敛判断:本轮 `usedQty<=0` 时跳出,避免死循环;否则生成 `currentBatch` 入结果集。
5) 回填策略(减少浪费)的判定
- 遍历已有组每个坑,计算可回填容量 `cap = pageCount - usedPages`。
- 只保留 `cap >= minContiguous` 的候选坑,按 `cap` 从大到小回填。
- 对剩余款按 `rem` 从小到大处理,优先“消灭小尾款”。
- 回填量 `take` 同时满足:`take >= minContiguous`,并受 `minQty` 约束。
- 回填成功会记入 `lastWasteOptimizeInfo`(回填数量、段数、影响组数)。
如果你看到“浪费下降但组数没降”,通常说明回填在消化尾款而不是减少组数,这属于正常表现。
6) 结果校验与异常信号
| 信号 | 含义 | 排查方向 |
| 未拼上 X 款 | 某些 name 在结果中为 0 | 检查输入名称是否空格/复制异常 |
| 数量不足 X 款 | 实际分配小于输入 total | 看参数是否过于保守(高 BLANKS / 低 LIMIT) |
| 超分配 X 款 | 实际分配超过输入 total | 重点检查 rem 递减与重复分配路径 |
| 组数超过上限提示 | 仅代表未达“目标”,不代表截断 | 调大 LIMIT / TOL,或降低 BLANKS |