5D Library › 复杂系统相变、临界慢化与生态韧性的非线性动力学 · English
第一章 折叠分岔、滞后与难以回头的翻转
平稳的表面
在许多生态系统中,变化并不与压力成比例。浅水湖泊可以在营养负荷缓慢增加的几十年里保持清澈,然后在很短的时间里转为浑浊、以浮游藻类为主;珊瑚礁可以在几年之内被大型藻类覆盖。谢弗、卡彭特、福利、福尔克与沃克在 2001 年的综述中把这类现象称为生态系统的「灾变式转变」,把湖泊、珊瑚礁、林地、荒漠与海洋放在同一个框架下讨论 (Scheffer et al. 2001)。
这个框架的核心是:同样的外部条件下,系统可能有不止一个稳定状态。外部条件慢慢变化时,系统所在的稳定状态慢慢变浅,直到在某一点上消失,系统只好跳到另一个稳定状态;之后即使把条件退回到跳变时的水平,系统也不会回来。这种「来时路与回头路不同」的现象叫做滞后。
放牧模型
推导
设植被(或被收获的种群)的量为 ,按逻辑斯谛方式生长,同时被食草动物(或捕捞)以强度 消耗;消耗随 呈 S 形(霍林 III 型):植被很少时动物吃不到多少,植被充足时动物吃饱了也不多吃。
除 外,平衡条件可写成 ,即「在压力 下, 是一个平衡点」。 先降后升再降,它的局部极小值与极大值就是两个鞍结分岔(折叠点) 与 : 在两者之间时,系统有两个稳定平衡点,中间夹着一个不稳定平衡点。
用植物生长曲线与采食曲线(包括 S 形采食曲线)的图解分析放牧系统的稳定性,来自诺伊—梅尔 (Noy-Meir 1975);梅在 1977 年的综述中把它与其他多稳态的简单模型放在一起,用于放牧系统、害虫以及人类的一些宿主—寄生物系统,讨论了「门槛」与「断点」(May 1977)。本书用无量纲的示意参数 、、,不对应任何具体的草场或渔场。
推导
程序求两个折叠点;把压力极慢地从 1.0 增加到 3.0、再减回 1.0,记录跳变的位置;并从压力为 2.7 时的崩溃状态出发,把压力降到不同水平,看系统能否恢复。
推导
# Folds (saddle-node bifurcations) and hysteresis in the grazing model of Noy-Meir (1975) and
# May (1977): dx/dt = r x (1 - x/K) - c x^2/(x^2 + a^2); x = vegetation (or a harvested
# stock), c = grazing / harvesting pressure. Illustrative values r = 1, K = 10, a = 1.
R, K, A = 1.0, 10.0, 1.0
f = lambda x, c: R * x * (1 - x / K) - c * x * x / (x * x + A * A)
c_of_x = lambda x: R * (1 - x / K) * (x * x + A * A) / x # x > 0 is an equilibrium at c
dc = lambda x, h=1e-6: (c_of_x(x + h) - c_of_x(x - h)) / (2 * h)
def bisect(g, lo, hi, n=80):
for _ in range(n):
mid = (lo + hi) / 2
if (g(lo) > 0) == (g(mid) > 0): lo = mid
else: hi = mid
return (lo + hi) / 2
X1, X2 = bisect(dc, 0.5, 2.5), bisect(dc, 2.5, 9.0) # local min and max of c(x)
C1, C2 = c_of_x(X1), c_of_x(X2)
def equilibria(c):
xs, roots = [i * 0.01 for i in range(1, 1000)], []
for u, v in zip(xs, xs[1:]):
if (f(u, c) > 0) != (f(v, c) > 0):
x = bisect(lambda x: f(x, c), u, v)
if not roots or x - roots[-1] > 0.02: roots.append(x)
return roots
def settle(x, c, t=200.0, dt=0.01):
for _ in range(int(t / dt)): x += f(x, c) * dt
return x
if __name__ == "__main__":
print(f"folds: c1 = {C1:.3f} (at x = {X1:.2f}), c2 = {C2:.3f} (at x = {X2:.2f})")
print(" c equilibria (stable / unstable / stable)")
for c in (1.5, 1.8, 2.2, 2.6, 2.7):
print(f" {c:.1f} " + " ".join(f"{x:5.2f}" for x in equilibria(c)))
x, c, up, down = settle(9.0, 1.0), 1.0, None, None # slow sweep, dc/dt = 0.0005
while c < 3.0:
x += f(x, c) * 0.01; c += 0.000005
if up is None and x < 3.0: up = c
while c > 1.0:
x += f(x, c) * 0.01; c -= 0.000005
if down is None and x > 3.0: down = c
print(f"slow sweep up: collapse at c = {up:.3f}; sweep down: recovery at c = {down:.3f}")
low = settle(9.0, 2.7) # collapsed at c = 2.7: how far must c be cut?
print(f"collapsed state at c = 2.7: x = {low:.2f}")
ends = [(c, settle(low, c, t=400.0)) for c in (2.5, 2.2, 2.0, 1.85, 1.80, 1.75, 1.5)]
print(" pressure cut to c: " + " ".join(f"{c:4.2f}" for c, _ in ends))
print(" x settles at: " + " ".join(f"{e:4.2f}" for _, e in ends)
+ " (> 3 = recovered)")
# folds: c1 = 1.787 (at x = 1.14), c2 = 2.604 (at x = 4.78)
# c equilibria (stable / unstable / stable)
# 1.5 8.20
# 1.8 1.00 1.30 7.70
# 2.2 0.57 2.57 6.86
# 2.6 0.44 4.56 5.00
# 2.7 0.42
# slow sweep up: collapse at c = 2.635; sweep down: recovery at c = 1.762
# collapsed state at c = 2.7: x = 0.42
# pressure cut to c: 2.50 2.20 2.00 1.85 1.80 1.75 1.50
# x settles at: 0.46 0.57 0.68 0.86 1.00 7.79 8.20 (> 3 = recovered)两个折叠点在 与 。在两者之间,同一个 对应两个可能的结局: 时,植被可以停在 6.86,也可以停在 0.57;中间的 2.57 是两个吸引盆的分界。慢扫描显示了滞后:压力上升时系统在 处崩溃(比 2.604 稍晚,因为压力在变,系统来不及跟上),回落时直到 才恢复。从 的崩溃状态出发,把压力降到 2.5、2.2、2.0 甚至 1.80,系统都停在低稳态;只有降到 1.75、低于 ,植被才回到 7.79。越过 之后,压力必须比崩溃点低约 31% 才能恢复。这就是作者框架中所说的「需把压力大幅回调到另一分岔点以下」。
注
术语。 5D Library 第 13 本第四章用尖点模型的标准形式讨论过滞后与折叠点附近的「瓶颈」,那里的两个折叠点是对称的。放牧模型的两个折叠点不对称,崩溃后的状态很低但不为零;压力降到 以下就能恢复。严格地说这是滞后;「不可逆」需要更强的条件。
可逆、滞后与不可逆
推导
浅水湖泊的无量纲磷模型(参照卡彭特、路德维希与布罗克 1999 年的模型与谢弗等人 2001 年综述的第一个专栏):
为水中的磷(浑浊程度), 为流域负荷, 为随出流与沉积的损失速率,最后一项为缺氧的底泥把磷重新释放到水中的正反馈,。程序按 把湖泊分为三类:没有折叠点的「可逆」湖泊;两个折叠点都在正负荷上的「滞后」湖泊;回头的折叠点落在负负荷上的「不可逆」湖泊。
推导
# Reversible, hysteretic and irreversible lakes (after Carpenter, Ludwig & Brock 1999 and
# Box 1 of Scheffer et al. 2001). Dimensionless phosphorus model:
# dx/dt = a - b x + x^q / (1 + x^q)
# x = phosphorus in the water (turbidity), a = loading from the catchment, b = loss rate
# (outflow, burial), x^q/(1+x^q) = recycling from the sediment. q = 8; values illustrative.
Q = 8
def a_eq(x, b): # loading at which x is an equilibrium
return b * x - x ** Q / (1 + x ** Q)
def folds(b):
xs = [i / 2000 for i in range(1, 8000)]
ext = []
for u, v, w in zip(xs, xs[1:], xs[2:]):
if (a_eq(v, b) - a_eq(u, b)) * (a_eq(w, b) - a_eq(v, b)) < 0:
ext.append(a_eq(v, b))
return ext # [] or [a_on, a_off]
def settle(x, a, b, t=300.0, dt=0.01):
for _ in range(int(t / dt)):
x += (a - b * x + x ** Q / (1 + x ** Q)) * dt
return x
print("loss b lake type tips to turbid at a > returns to clear at a <")
for b in (2.5, 1.0, 0.8, 0.6, 0.45):
fo = folds(b)
if not fo:
print(f" {b:4.2f} reversible (no fold: x changes smoothly with a)")
continue
a_on, a_off = fo
kind = "hysteretic" if a_off > 0 else "IRREVERSIBLE"
note = f"{a_off:6.3f}" if a_off > 0 else f"{a_off:6.3f} (impossible: a >= 0)"
print(f" {b:4.2f} {kind:13s} {a_on:6.3f} {note}")
for b in (1.0, 0.6):
a_on, a_off = folds(b)
x = settle(0.2, a_on + 0.05, b) # loading pushed just past the fold
print(f"b = {b}: loading {a_on + 0.05:.3f} -> turbid x = {x:.2f}; loading cut to")
for a in (a_on - 0.05, max(a_off, 0) + 0.03, max(a_off - 0.03, 0.0)):
print(f" a = {a:.3f}: x = {settle(x, a, b):.2f}")
# loss b lake type tips to turbid at a > returns to clear at a <
# 2.50 reversible (no fold: x changes smoothly with a)
# 1.00 hysteretic 0.660 0.389
# 0.80 hysteretic 0.510 0.144
# 0.60 IRREVERSIBLE 0.366 -0.111 (impossible: a >= 0)
# 0.45 IRREVERSIBLE 0.262 -0.309 (impossible: a >= 0)
# b = 1.0: loading 0.710 -> turbid x = 1.70; loading cut to
# a = 0.610: x = 1.59
# a = 0.419: x = 1.32
# a = 0.359: x = 0.36
# b = 0.6: loading 0.416 -> turbid x = 2.36; loading cut to
# a = 0.316: x = 2.19
# a = 0.030: x = 1.69
# a = 0.000: x = 1.63损失速率大()时,湖泊对负荷的反应是平滑的。 时,负荷超过 0.660 湖水变浑,要变回清澈,负荷必须降到 0.389 以下,比翻转时低约 41%; 时要低约 72%。 与 0.45 时,回头的门槛是负数:即使流域负荷完全切断,湖水也停在浑浊状态()。卡彭特等人指出,对不可逆的湖泊,单靠减少负荷不够,必须改变湖泊本身的参数,例如清除富含磷的底泥 (Carpenter et al. 1999)。
证据:湖泊
证据
浅水湖泊。 谢弗等人总结说,浅水湖泊可以在营养负荷越过门槛时突然从清澈、有沉水植物的状态转为浑浊、藻类占优的状态,水草的消失又使浑浊得以维持;恢复清澈所需的营养水平要「大大低于」崩溃时的水平,仅把负荷退回去常常不起作用。他们以荷兰费吕沃湖为例,并指出在营养不太高时,短期内大量减少鱼类可以使湖水重新变清 (Scheffer et al. 2001)。耶珀森等人汇总了 35 个湖泊减少营养负荷后的长期数据(5—35 年,平均 16 年):大多数湖泊的总磷在 10—15 年后才达到新的平衡,底泥中积存的磷拖慢了恢复 (Jeppesen et al. 2005)。
后一组数据与滞后模型的定性预测一致,但它本身不能区分「多稳态的滞后」与「只是很慢的单一平衡」:底泥中的磷库本身就会造成多年的延迟。
证据与争议:珊瑚礁
证据
牙买加的珊瑚礁。 休斯记录了牙买加珊瑚礁的退化:10 米深处的珊瑚覆盖率从 1977—1980 年的平均 52% 降到 1990—1993 年的 3%,肉质大型藻类从 4% 升到 92%。原因包括几十年的过度捕捞、1980 年的飓风「艾伦」,以及 1983 年一种病原体使食藻的冠海胆密度下降 99% 且十年未恢复 (Hughes 1994)。芒比、黑斯廷斯与爱德华兹用模型分析认为,自 1983 年以来加勒比的珊瑚礁普遍失去了韧性,对鹦嘴鱼的过度捕捞十分敏感 (Mumby et al. 2007)。
证据
争议。 布鲁诺等人分析了 1996—2006 年对全球 1,851 个珊瑚礁的 3,581 次调查,只有约 4% 的珊瑚礁以大型藻类为主(覆盖率超过 50%),印度—太平洋地区只有 1% (Bruno et al. 2009)。达吉恩、阿伦森、布鲁诺与普雷希特认为,在能下确定结论的地方,化石与现代数据「压倒性地」支持「相移」假说而不是「可替代稳态」假说:一种给定的热带珊瑚礁环境最多只支持一种稳定群落,文献中的混淆来自误解理论,以及把持续的环境变化引起的「相移」与可替代稳态之间的切换混为一谈;如果把环境恢复过来,群落应会回到以珊瑚为主 (Dudgeon et al. 2010)。
这场争论决定管理的方向。如果珊瑚礁是滞后系统,恢复需要「矫枉过正」;如果它只是随环境变化的单一状态,恢复环境本身就够了。两种假说的区别不在于变化是否突然,而在于回头的路是否不同,这只有在环境被改善之后才能检验。
注
类比的边界。 「越过门槛之后要大幅回调才能恢复」常被用来描述企业资金链的恶性循环,或者身体在长期压力下的突然失代偿。作为类比,它提醒人们注意正反馈与不对称的恢复路径;但本章的模型与证据都来自生态系统,不能用于任何企业的经营或投资判断,也不能用于任何人的医疗判断。本书不作投资建议,也不是医疗建议。
假说 · 尚未验证
滞后低估假说(尚未确立)。作者推测,管理一个有滞后的资源系统的人,往往默认「把压力退回到出事时的水平就能恢复」。可以检验的预测是:在一个参与者不知道模型结构的模拟收获任务中,崩溃发生后,多数参与者第一次减少的努力量不足以使压力低于恢复门槛 。如果事先登记的实验中多数参与者第一次调整就把压力降到 以下,这一假说就被推翻。
本章小结
具有正反馈的系统在一段条件范围内可以有两个稳定状态。放牧模型中,压力越过 后系统跳到低稳态,要恢复必须退到 以下,比崩溃点低约 31%。湖泊磷模型中,同一结构可以给出可逆、滞后与不可逆三种行为。湖泊的多稳态与缓慢恢复有较好的证据;珊瑚礁是否有可替代的稳态仍有争议。下一章讨论,系统接近折叠点时能否从它对小扰动的反应中看出来。
参考文献
Fan, Y. (2026). Phase Transitions, Critical Slowing Down and Resilience in Complex Dynamical Systems: From Saddle-Node Bifurcations and Early-Warning Signals to Cascading Failures, Read Beside Classical Chinese Thought on Incipient Change [复杂系统相变、临界慢化与生态韧性的非线性动力学] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23770082 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).