波次拣货的分工:三个人怎么不撞车

去年秋天,我们库里的拣货组从两个人加到三个人。按人头摊,人均单量该降三成,实际只降了一成二。我把手持终端的轨迹数据导出来回放,看到某天上午九点到十一点,三个人有十七分钟挤在同一个巷道段里,互相等对方让路。

那时候的派工方式很朴素:波次一开,谁手快谁抢单,抢到的先拣。三个人手速差不多,抢到的单子常常落在同一片区域,因为走得顺的货都在 B 区。人加了一个,单量没变,撞车反而多了。

后来我把派工从抢单改成按巷段派单:一个波次内,把待拣货位按巷道切成三段,一人一段,段内按货位序号单向走。改完同样三个人,日均单量从 420 涨到 510,撞车等待从每天四十多分钟压到七八分钟。下面把规则、边界和那段分配语句写清楚。

一、撞车不是人慢,是路线重叠

1.1 三个人的动线画在一张图上

我做过一次很土的分析:把每个人一个上午的轨迹点按时间连成线,打印在半透明纸上,三张叠起来看。重叠的地方一眼就能看出来,不是全库重叠,是几个固定货位和两个巷道口。

叠完之后我才明白,拣货员的等待时间不是均匀分布的。七成发生在巷道口,因为拣货车宽,两台车在口子上错不开;剩下三成发生在几个动销快的货位前,两个人同时伸手,一个人拿完另一个才能拿。

1.2 波次切开之后仍然重叠

波次的本意是把订单切成小批,缩短一次走行的距离。但波次只切了时间,没切空间。同一个波次里,如果一单在 3 号巷道、一单在 4 号巷道、一单又在 3 号巷道,三个人还是往同一处走。

我们当时的波次规则按截单时间切,每两小时一批。这个规则对订单处理没毛病,对走行路线几乎没有约束。波次划得越大,重叠越明显;划得越碎,拣货员走空路的次数越多。两头都不讨好,这也是我起初以为是"人不够"的原因。

1.3 撞车的三种形态

看录像能分出三种情况。一种是对向相遇,两个人从巷道两头进来,中间错不开车,必须有一方退出去。一种是货位争抢,同一排货架前两个人同时伸手,拣货车挡住了对方的取货面。一种是口子堵塞,两个人都想从同一个巷道口出去,谁都不肯退。

三种情况的代价不一样。对向相遇浪费的是两个人的时间,货位争抢容易拣错,口子堵塞会把整条通道堵住,后面的人只能绕远。所以处理方式也不能一样:前两种靠路线设计解决,后一种得靠物理动线,比如把巷道口改成单向进出。

二、按巷道分区,而不是按订单分人

2.1 库位编码先要能排序

分区的前提是货位能排出顺序。我们的库位编码是"区-巷道-货架-层-位",比如 B-07-03-2-4 表示 B 区 7 号巷道 3 号货架二层四号位。这个编码本身携带了空间信息,只要按字符串切段,就能排出走行顺序。

问题出在早期的一批货位,编码是流水号,比如 B-0137,看不出在哪个巷道。这批货位有两百多个,占了 B 区的三分之一。我先花了两天把它们重新贴标,标签是打印的,贴在货架横梁上,同时在系统里改了编码字段。不改这一步,后面的分区都是空谈。

2.2 分区规则:连续段加单向流

分区的规则我定了三条。巷道号连续的归同一个人,避免一个人在巷段之间来回跳。每个人分到的段内,货位按巷道号升序、货架号升序排,走成一条不回头的线。段与段之间留一个巷道作为缓冲,两个人不共用同一条巷道。

这三条里,第三条看着浪费,其实省时间。缓冲区意味着两个人不会在同一条巷道里迎面碰上,对向相遇这种撞车直接消失了。代价是缓冲区里的货要单独派,我把它挂给了单量相对少的那个人,作为收尾任务。

2.3 边界货位归谁

段的分界线上总有货位归属不清楚。比如 6 号巷道分给 P1、7 号巷道分给 P2,那么跨巷道存放的整托盘货算谁的。我的处理是看主货位:货位编码里的巷道号属于哪一段,就归哪个人,跨巷道只作为提示,不改变归属。

这条规则写在派工说明里,贴在拣货区的白板上。起初有人不服,觉得分界线附近的货让自己多走几步。跑了两个星期,大家自己算出来,分界线附近本来就少,多走的那几步远不如不撞车省下来的时间。

三、把规则写成一段分配语句

3.1 两张表:任务和货位

任务表 pick_task 里一行是一个待拣明细,字段包括波次号、货位编码、商品、数量、状态、拣货员、段内序号。货位表只作参照,提供巷道、货架的物理位置,实际分配时用不上,因为货位编码已经能切出巷道号。

之所以不 JOIN 货位表,是为了让分配语句能在一个事务里跑完。多一张表就多一次锁,波次高峰时这点开销会被放大。货位编码规范之后,字符串切分比查表快得多。

3.2 分配语句

下面这段是 PostgreSQL,按巷道号把当前波次切成三段,写入拣货员和段内顺序,末尾再跑一条统计确认三个人分到的任务量没有严重倾斜。

sql 复制代码
WITH task AS (
    SELECT id,
           split_part(location_code, '-', 1) AS zone,
           split_part(location_code, '-', 2)::int AS aisle,
           split_part(location_code, '-', 3)::int AS bay,
           qty
    FROM pick_task
    WHERE wave_no = :wave_no
      AND status = 'WAIT'
), seg AS (
    SELECT t.*,
           CASE
               WHEN t.aisle <= 6  THEN 'P1'
               WHEN t.aisle <= 12 THEN 'P2'
               ELSE 'P3'
           END AS picker_code
    FROM task t
), ranked AS (
    SELECT s.*,
           row_number() OVER (
               PARTITION BY s.zone, s.picker_code
               ORDER BY s.aisle, s.bay
           ) AS pick_seq
    FROM seg s
)
UPDATE pick_task p
   SET picker_code = r.picker_code,
       pick_seq    = r.pick_seq,
       assigned_at = now()
  FROM ranked r
 WHERE p.id = r.id
   AND p.status = 'WAIT';

SELECT picker_code,
       count(*)      AS task_cnt,
       min(pick_seq) AS seq_from,
       max(pick_seq) AS seq_to
FROM pick_task
WHERE wave_no = :wave_no
  AND status = 'WAIT'
GROUP BY picker_code
ORDER BY picker_code;

3.3 分完先跑一遍校验

这段语句跑完,我不会马上放行。先看统计结果,如果三个人的任务数相差超过四成,说明这个波次的货位分布不均,得手工挪一部分。挪的原则是挪段尾,不动段首,因为段首是入口,动了会让整条路线重排。

还有一个隐性的检查:段内序号是不是连续。row_number 出来的序号在分区内连续,但如果分区的货位编码有重复,序号会跳。我加了一条校验,段内序号出现断档就报警,让人去看编码表。这个检查帮我们抓到过三处重复编码的货位。

四、上线之后的变化

4.1 走行距离和单量

改完后的头一个月,日均单量从 420 涨到 510,第二个月稳在 520 上下。手持终端记录的走行距离,人均从每天 11.2 公里降到 8.6 公里。撞车等待时间按录像抽样估算,从每天四十多分钟降到七八分钟。

单量涨的幅度比分摊预期的多,我起初不太相信,专门核对了三天的单据。核对下来没问题,原因是撞车消失之后,拣货员不用再挑"哪条巷道现在没人",路线是固定的,判断成本降下来了。

4.2 三个人的分工感

人还是那三个人,但状态变了。以前三个人都在抢单,抢到之后还要互相打招呼,问对方在哪条巷道。现在每天早上看一眼派工表,知道自己走哪三段,走完就回来,不用问。

有个副作用是我没预料到的:三个人开始自己琢磨怎么把段内的顺序走得更顺。P2 的老周把 7 号巷道里两个常拣的货位挪到了段首,说这样能少拐一个弯。这个建议后来被写进了货位调整的规则里,动销快的货位放段首。

4.3 爆款和补货的例外

爆款是个麻烦。一个单品一天出两百件,放在哪个段里,那个人就得多跑十几趟。我的处理是把它从分区里摘出来,单独做"批量拣",一次拿够,再按单分播。这样段内的路线就干净了。

补货也会打乱路线。补货员在巷道里推着液压车,比拣货车宽一倍,遇上就得让。后来我们把补货时间挪到波次间隙,拣货员回工作站分播的那二十分钟,补货员进巷道。物理上错开,比在系统里设优先级管用。

五、这套做法的边界

5.1 适合什么形态的库

这套分区派单适合巷道规整、货位编码统一的库。巷道是直的,货位有明确的空间顺序,分区才有意义。如果库房是异形的,或者货位是随机摆放的,按巷道切段反而会让路线变长。

订单结构也有关系。多品少量、单均行数在三到八行的场景,分区效果明显。如果一单就是几十行、跨整个库,一个人跑完全程更省事,硬切三段会让同一单被拆给三个人,分播环节反而更复杂。

5.2 什么时候退回抢单

大促期间我试过退回抢单。那几天单量是平时的四倍,波次切得极碎,分区派单的分配开销比拣货本身还大。退回抢单之后,三个人各自扫一片,反倒灵活。

所以分区不是教条。单量平稳、波次规整的时候用分区,单量暴涨、订单结构混乱的时候退回抢单,两者之间切换的判断标准是"分配一次的时间是否超过它省下的撞车时间"。这个标准很粗,但比拍脑袋强。

常见问题

问:三段分下来,某一段的单量特别多,会不会一个人闲着一个人忙死?

答:会,所以分配完要看统计。任务数相差超过四成,就手工挪段尾的货位到相邻段。另一种做法是把段切得更细,比如切成五段,让三个人轮流领,但这会让路线不固定,撞车又回来了。我偏向手工微调。

问:波次划多大合适?

答:我们按两小时一批,单均在 70 到 90 行之间。行数太少,拣货员来回跑工作站的次数多;行数太多,一个波次跑不完就要交接,容易漏拣。这个数跟库的平面尺寸有关,库越大,波次该越小。

问:分区是固定不变的,还是每个波次重算?

答:每个波次重算,但段的边界是固定的。也就是 1 到 6 号巷道永远归 P1,只是每次波次里这三段有没有货、有多少货会变。段边界固定,拣货员的肌肉记忆才能建立起来。

问:没有仓储系统,用表格能不能做这套分区?

答:能做一个简化版。在表格里加两列,一列按巷道号手填分段,一列按货位序号排序,然后用排序加筛选把三段拆成三张表打印出来。单量在两百行以内,人工拆比写语句快。超过这个量,手工会开始在分界线附近出错。

相关推荐
ZKNOW甄知科技8 小时前
燕千云迭代版本发布:智能Agent深入业务现场
运维·人工智能·低代码·机器学习·自然语言处理·自动化·aigc
她的男孩9 小时前
条件分支两边审批一样,却发成两份待办:Forge Admin 审批设计器的公共节点合并
spring boot·低代码·工作流引擎
驰骋工作流1 天前
低代码平台的评估指标:从「上层建筑 / 基座」两层看驰骋BPM驰骋低代码低代码工作流引擎
低代码
驰骋工作流1 天前
菜单的类型:为什么「菜单」需要分类——结合驰骋 GPN_Menu 的设计驰骋BPM驰骋低代码低代码工作流引擎
低代码
SL_staff2 天前
私有化低代码运维三重雷区:JVS开源栈中的Kafka/ES/RabbitMQ治理实践
java·低代码·全栈
快乐非自愿2 天前
低代码落地费控系统:从报销流程到业财闭环的实操方案
android·低代码·rxjava·ai低代码
她的男孩2 天前
页面已发布用户仍进不去:Forge Admin 门户入口与系统菜单挂载解耦
java·spring boot·低代码
窗边看云3 天前
库存 ABC 分类:好钢用在刀刃上
低代码
什么嘻嘻果冻4 天前
无代码开发平台的技术架构,恐象 AI 的生成引擎拆解
大数据·人工智能·低代码