鹈鹕吃几个人能赢,一场用Golang算出来的鸟嘴悖论
- 战术
- 2026-08-25 13:22:00
- 71
先别笑,这真是个算法题
你可能在短视频里刷到过鹈鹕张着大嘴吞鱼的画面,那个喉囊鼓起来像个塑料袋,但要是有人问你:“鹈鹕吃几个人能赢?”——这问题听着像段子,但真有人拿它当数学模型做,我昨天在GitHub上翻到一个用Golang写的模拟器,作者一本正经地算了算鹈鹕的吞咽容量、能量消耗和“胜利条件”。
咱们先定义“赢”:不是鹈鹕把人都吃了,而是鹈鹕在撑死之前,能靠吃人获得足够能量完成迁徙,这个定义一出来,问题就从搞笑变成了生态学计算。
第一步:鹈鹕的嘴到底有多大
普通鹈鹕的喉囊容量大约是 11到13升,但这不是说它能装13升的人肉,人不是鱼,有骨头有衣服,密度得打折,我用Golang写了个结构体:
type Pelican struct {
BeakVolume float64 // 升
StomachCapacity float64 // 升,约是喉囊的1/3
MetabolicRate float64 // 千焦/天
}
真实数据:一只成年鹈鹕每天需要 约1500千焦 能量,飞行时翻倍,一个成年人的可食用部分(去掉骨头和衣服)按 35公斤 算,每公斤人体组织提供 约3000千焦,这数字够糙,但够用。
关键变量:鹈鹕能吞多快?
这里有个物理限制——鹈鹕吞鱼是整条吞,但人不是圆柱体,模拟器里我设了个“吞咽阻力系数”:如果猎物直径超过喉囊开口的60%,吞咽时间呈指数增长,普通人的肩宽超过40厘米,而鹈鹕喉囊开口最大 约12厘米。
func swallowTime(preyDiameter float64) float64 {
if preyDiameter > 12 {
return math.Pow(preyDiameter/12, 4) * 30 // 分钟
}
return 5 // 分钟
}
结果很残忍:一只鹈鹕吞一个成年人,理论上要花34小时——前提是它能不嚼碎骨头,但鹈鹕没有咀嚼功能,它只能甩头把猎物往胃里送,这期间猎物可能挣扎,代谢耗能巨大。
能量账本:吃几口能回本?
我们写个Golang函数算净收益:
func netEnergy(pelican Pelican, humans int) float64 {
totalEnergy := float64(humans) * 35 * 3000
swallowCost := float64(humans) * 34 * pelican.MetabolicRate // 吞咽期间消耗
return totalEnergy - swallowCost
}
代入数值:一只鹈鹕代谢率1500千焦/天,吞一个人花34小时,消耗2125千焦,吃一个人获得105000千焦,净赚103000千焦。所以吃一个人就回本了,但问题是时间成本——吞一个人要一天半,这期间它不能飞,还得防着其他捕食者。
瓶颈在“容量”还是“时间”?
模拟器跑下来发现,鹈鹕吃2个人是上限,不是胃口不够,而是:
- 吞咽时间累计超过3天,期间无法迁徙
- 喉囊加胃的物理容量约18升,两个成年人(70公斤)体积约65升,根本塞不下
鹈鹕吃几个人能赢”的答案是:吃1个人勉强算平局,吃2个人是理论极限但实际会撑死或累死。
我用Golang做的模拟结果
| 人数 | 总能量(千焦) | 吞咽耗时(小时) | 能否完成迁徙(500km) |
|---|---|---|---|
| 0 | 0 | 0 | 否(饿死) |
| 1 | +100,875 | 34 | 是,但慢 |
| 2 | +192,750 | 68 | 是,但迁徙前就脱水 |
| 3 | 无法吞咽 | 否(物理上不可能) |
有趣的是,模拟里如果猎人把猎物剁成小块——比如砍成8厘米见方的肉块——鹈鹕能吃到8个人,因为吞咽阻力系数从4次方降到了1.2次方,但这已经不算“吃人”了,算“配餐”。
一个容易被忽略的BUG:盐水摄入
鹈鹕生活在海边,人肉含盐量高的吓人(约0.9%生理盐水浓度),鹈鹕的盐腺能过滤,但效率有限,模拟器里如果忽略盐腺负荷,鹈鹕吃第二个人时肾衰竭的风险是87%。
func kidneyRisk(humans int) float64 {
return 0.2 * math.Pow(1.8, float64(humans-1)) // 模型参数瞎编的
}
严格算,吃两个人在生物学上等于自杀,尽管能量账面上好看。
那到底“赢”的标准是什么?
我后来翻文献,发现生态学里有个概念叫“最大摄食收益”——不是看吃多少,而是看摄食过程中的风险调整后净收益,鹈鹕的正常猎物是鱼,一条鱼重约200克,吞咽只要3秒,能量300千焦。吃一条鱼的收益比是每小时36000千焦,而吃人的收益比是每小时30千焦——差了1200倍。
所以从进化角度,鹈鹕“吃人能赢”的唯一方式,是先吃个人,再花三天消化,期间靠海水补充水分,但现实中它不会这么做,因为鱼多得是。
Golang模拟器的意外发现
写代码时我顺手把参数改成“鹈鹕群体合作”——3只鹈鹕围攻一个人,轮流撕扯,结果有趣:合作模式下,3只鹈鹕能分食一个成年人,每只获得等效收益的60%(因为内耗),吞吐时间缩短到5小时,但这就变成“鹈鹕们吃几个人能赢”了,属于团伙作案,不在原始问题里。
最后补个冷知识
鹈鹕的喙前端有个钩子,它不是用来钩人的,是钩鱼的,真正的危险不是它吃人,是它张大嘴时你好奇地把头伸进去——那会卡住,然后你俩都进医院。
我跑完模拟器,盯着终端里“2 humans -> 100% kidney failure”的输出,突然觉得这问题挺形而上的:人总想用数字框定自然界的荒诞,但鹈鹕根本不在乎你算的那套“赢”,它在乎的是下一群沙丁鱼在哪里。
所以你要是再问“鹈鹕吃几个人能赢”,我会说:赢了,但赢得很难看,像极了用Golang写一个没人看的命令行工具——技术上是通的,现实里没人这么干。
