单台手术中位 55 分钟,一天 480 分钟,按均值算能排 8 台(440 分钟),看起来宽裕。实测: 8 台的拖班概率 45%。要压到 10% 以内,一天只能排 5 台,利用率掉到 62%。 从 8 台到 5 台,少掉的那 3 台就是「平均」和「保证」之间的差价。
前两节的对象是病人。这一节换成资源:手术间怎么排。 这是医院管理里最典型、也最容易算错的一类问题。
一、排程不是加减法
最朴素的算法是除法:一天 480 分钟,单台 55 分钟,480 ÷ 55 = 8.7,排 8 台。 这个算法在教科书里叫「按均值排」,在实际科室里叫「天天拖班」。 问题出在「55 分钟」是一个中位数,不是一个常数。实际每台手术的时长是一个分布: 大部分在 40~70 分钟,少数会到 150 分钟以上。 总时长是 8 个随机变量相加。 它的均值确实是 8 × 55 = 440,但它是一个分布,有宽度。 排程要保证的不是「均值不超过 480」,是「绝大多数日子不超过 480」。 而这两件事在数学上差得很远。 这一节的 Demo 用一个对数正态分布(中位 55 分钟、σ=0.40)模拟 40 万台手术, 再把它们按每天 k 台分组求和,看总量的分布。 全程没有排队论,就是「把随机数加起来」——但结论足够硬。
二、均值够用,90 分位差得远
| 每天排台数 | 总时长均值 | 利用率 | 总量 P90 | 拖班概率 |
|---|---|---|---|---|
| 5 | 298 | 62% | 371 | 0% |
| 6 | 358 | 75% | 438 | 3% |
| 7 | 417 | 87% | 504 | 16% |
| 8 | 477 | 99% | 570 | 45% |
| (时长单位分钟。拖班=当天总时长超过 480 分钟。) | ||||
| 先算最朴素的账:中位 55 分钟 × 8 台 = 440 分钟,看起来 480 分钟够用。 | ||||
| 但实际拖班概率是 45%。 | ||||
| 因为「总时长」不是一个数,是一个分布。 | ||||
| 8 台的均值是 477 分钟(已经接近 480 了),而 90 分位是 570 分钟——远超 480。 | ||||
| 注意均值 477 这件事本身就值得看:8 台的平均总时长,已经贴着 480 了。 | ||||
| 「中位 55 × 8 = 440」这个算法错在把中位数当成了均值—— | ||||
| 对数正态分布的均值比中位数高(这里是 59.6 分钟)。 | ||||
| 中位数和均值在偏态分布里差得很开,而排程要的是均值。 | ||||
| 所以「8 台」这个数字错了两层: | ||||
| ① 用中位数代替均值,低估了单台时长;② 用均值代替分布,低估了波动。 | ||||
| 两层叠加,45% 的拖班率就这么来的。 |
三、拖班的元凶是长尾
少排一台呢?7 台拖班概率 16%,6 台 3%,5 台 0%。 要压到 10% 以内,一天只能排 5 台——而按均值算,8 台都能排。这就是「平均」和「保证」的差。 代价也很清楚:排 5 台的利用率只有 62%。 走廊空着、手术间闲着,这是排程为了「不拖班」付的钱。 为什么波动这么大?看那一行「超出一倍中位的比例是 4.2%」。 4.2% 的手术会超过 110 分钟,这些就是拖班的元凶。 一台 180 分钟的手术,能把一整天的富余全部吃掉。 而且长尾的杀伤力是非线性的。一台超长手术不只让自己晚,它后面的每一台都往后推, 最后推的是接台时间和麻醉复苏室。 这就是为什么手术室拖班会连锁到整个楼层的运转。 放到更一般的场景看:任何「单件工时不确定、又必须当天做完」的排程, 都会撞上同一个数学事实——按均值排,一半的日子会超时。 门诊号源、检查预约、救护车调度、客服排班,全是这一类。
四、落地:混合策略,不是一味保守
实务上的解法不是「排得保守」,而是混合策略。 因为方差的来源不是「平均多长」,是「有个别特别长的」。所以要对症下药: ① 短手术集中排。 把 30 分钟左右的台(比如白内障、内镜)放在一起,一天能排十几台,波动被平均掉。 这是最有效的一招——短台的天数里,拖班几乎不会发生。 ② 长手术单独安排,且只排一台。 一台 4 小时的手术独占一个手术间,不要往后面接台。 因为它的不确定性最大,接什么都可能被拖。 ③ 中间留一个「缓冲位」。 在长手术之后空出一段不排台的时间,专门吸收超时。 这一段空着不是浪费——它是把「拖到晚上十点」换成「下午空一小时」。 ④ 按科室分别标定,不要全院一个参数。 骨科和眼科的手术时长分布完全不同。 用全院平均的 σ 去排眼科,会让你白白少排很多台。 最后一句:排程优化的目标不是「排满」,是「在可接受的拖班率下排满」。 这两个目标之间差的那些台数,就是管理水平的真实刻度。
五、动手 Demo:手术排程:按均值能排 8 台,但 45% 的日子会拖班
造 40 万台手术的时长,服从对数正态分布(中位 55 分钟、σ=0.40),截断在 20 至 400 分钟。 把样本按每 k 台一组求和,模拟「一天排 k 台」的总时长分布,统计均值、利用率、90 分位, 以及总时长超过 480 分钟的比例(也就是拖班概率)。
per = np.exp(rg.normal(np.log(55.0), 0.40, 400000))
per = np.clip(per, 20.0, 400.0)
tot = per.reshape(-1, k).sum(axis=1) # 每 k 台一组
over = 100.0 * float(np.mean(tot > 480.0)) # 拖班概率
p90 = float(np.percentile(tot, 90))
use = 100.0 * tot.mean() / 480.0 # 利用率
实跑输出:
--------------------------------------------------------------------
手术排程:按均值能排 8 台,但 45% 的日子会拖班
--------------------------------------------------------------------
单台时长 中位 55 分钟,σ=0.40
可用时间 每天 480 分钟
模拟 40 万台手术的时长分布
超出一倍中位的比例 4.2%
每天排台数 总时长均值 利用率 总量 P90 拖班概率
-----------------------------------------------------
5 298 62% 371 0%
6 358 75% 438 3%
7 417 87% 504 16%
8 477 99% 570 45%
先算最朴素的账:**中位 55 分钟 × 8 台 = 440 分钟,看起来 480 分钟够用。**
**但实际拖班概率是 45%。**
**因为「总时长」不是一个数,是一个分布。**
**8 台的均值是 477 分钟,但 90 分位是 570 分钟——远超 480。**
少排一台呢?**7 台,拖班概率 16%;6 台 3%;5 台 0%。**
**要压到 10% 以内,一天只能排 5 台**——**而按均值算,8 台都能排。这就是「平均」和「保证」的差。**
代价也很清楚:**排 5 台的利用率只有 62%。**
**走廊空着、手术间闲着,这是排程为了「不拖班」付的钱。**
实务上的解法不是「排得保守」,而是**混合策略**:
**短手术(比如 30 分钟)多排几台,长手术单独安排,中间留一台「缓冲位」。**
**因为方差的来源不是「平均多长」,是「有个别特别长的」。**
**单台超出一倍中位的比例是 4.2%,这些就是拖班的元凶。**
要说明:时长分布是我**设的对数正态**。
**真实手术时长受术式、术者、并发症影响,分布更复杂。**
**但「按均值排必然拖班」这个结论不依赖具体分布**——它只要求「时长有波动」。
这一条可以推广到所有排程问题:
**只要单件工时不确定,按均值排就一定会有一半的日子超时。**
**这是数学,不是管理不善。**
done -> _out_39s.txt
8 台那一行是这一节的主角:均值 477(已经贴到 480 了)、90 分位 570、拖班 45%。 三个数一起看才完整——只看均值会觉得「刚刚好」,看 90 分位才知道「一半的日子要加班」。 利用率那一列容易被误读。 8 台时 99%,看着很「高效」——但它的意思是「平均值几乎把 480 分钟填满」, 也就是说没有任何余量吸收波动。 而排 5 台时 62%,看着浪费,但那 38% 的空隙正是「不拖班」的保障。 这一条可以推广到所有排程问题:只要单件工时不确定,按均值排就一定会有一半的日子超时。 这是数学,不是管理不善。 所以「我们科室总是加班」这件事,很多时候不是人手不够,是排程的算法用错了。 要说明:时长分布是我设的对数正态, 真实手术时长受术式、术者、并发症影响,分布更复杂,还常有「接台等待」这种额外开销。 但「按均值排必然拖班」这个结论不依赖具体分布—— 它只要求「时长有波动」,而这个要求在任何真实科室里都成立。
30 秒实验
- 把 σ 从 0.40 加到 0.70(波动更大),重跑 8 台那一行。 拖班概率会冲到 60% 以上——波动越大,按均值排越不可行。
- 把可用时间从 480 分钟改成 600(加晚班),看 8 台那一行。 拖班概率会大幅下降,但利用率也跟着降——加时间等于加成本。
- 把截断上限从 400 改成 250(不许超长台混进来),看所有行。 拖班概率全线下降,说明长尾就是元凶。
常见误区
- 「中位 55 分钟 × 8 = 440,480 分钟够用」。中位数不是均值,8 台的实际均值是 477 分钟。
- 「拖班是偶尔的意外」。8 台排法下 45% 的日子会拖班,这不是意外,是常态。
- 「排得越满越高效」。 排 8 台利用率 99%,代价是近一半的日子加班;排 5 台利用率 62%,但几乎不拖班。
自测三问(点开对答案)
1. 为什么「480 ÷ 55 = 8 台」这个算法是错的? —— 两层错:把中位数当均值(对数正态的均值更高),并且用均值代替了分布——排程要保证的是分位数, 不是均值。 2. 为什么排 8 台的利用率 99% 反而是个危险信号? —— 因为均值几乎填满了全部可用时间,没有任何余量吸收波动,所以一半的日子必然超时。 3. 拖班的根源是什么,该怎么对症? —— 单台时长的长尾(4.2% 的手术超过中位两倍)。对策是短台集中排、长台单独排、中间留缓冲位。11.2 讲完医疗的三个场景: 诊断、干预、资源。11.3 换到法律—— 那一行的输出不是概率,是「有还是没有」这类判断,而它的坑在另一个地方:文字本身。
- ☐ (本节完,下一节 11.3.1 法律文本智能处理)