TOPIC 41 · PHASE H

复杂度到底怎么量MEASURING COMPLEXITY

纯随机和纯有序,都不复杂(Neither pure order nor pure randomness is complex)

2026-08-28 · 方法与限度

你能想到的每一种"复杂度"量法,几乎都会把一页乱码判成最复杂的东西。而一页乱码不是复杂,是无聊。这门学科花了三十年补这个洞,补法本身比问题有用得多。

"这也太复杂了"是办公室里最常见的一句评价,而它同时用来形容两种正好相反的东西:一份四十页、层层嵌套、每一步都写死了的审批流程;和一个根本没有流程、谁都可以随时插一脚的项目。前者是规则太多,后者是规则太少。用同一个词描述它们,再用同一句"要简化"去处理,是很多失败的起点。

这一期问的是:复杂度能不能真的量出一个数来。这听起来学究气,但它决定一件很实际的事——当有人说"降低复杂度"的时候,你有没有办法追问他降的到底是什么。

反直觉的地方在这儿:几乎所有你第一时间想得到的量法——信息量、猜不猜得到、描述有多长——都会把随机排在最高。随机是这些尺子上的满分。而随机显然不是我们想说的那个"复杂"。这一期讲四把尺子:前两把在这一点上翻了车,后两把是为了修它才被造出来的。

本站前面用过很多次"复杂"这个词:第 1 期分了复杂与繁杂(complex vs complicated),第 2 期讲涌现,第 26 期讲复杂适应系统。本期不添新机制,只做一件事:把"复杂"这个词拆成几个互不相同、各自可算的量,并且指出它们在哪儿互相打架。

01"复杂"这个词同时指着两个反方向(Two Opposite Things, One Word)

先把要求写清楚。任何一把够格的复杂度尺子,都应该在两端给出低分。

一端是完全有序:一页纸上全是字母 A,一块食盐晶体里钠和氯永远隔一个排一个,一首只有一个音符反复的曲子。这些东西你看一小块就知道全部,没有任何东西需要解释。

另一端是完全随机:抛一千次硬币记下来的那串正反,电视机没信号时的雪花点。这些东西你看一小块推不出任何别的部分——但同样没有东西需要解释,因为"它就是随机的"这五个字已经把它说完了。

我们真正想用"复杂"指的东西,全都落在中间:一个细胞、一门语言、一座城市、一本小说。它们既不是照抄自己,也不是毫无章法;你看一部分能推出一些别的部分,但推不全。

我们想要的那种"复杂",两端都必须给低分 复杂度 细胞 · 语言 · 城市 · 小说 完全有序 一小块就说完了全部 有章法,但推不全 这才是我们想说的"复杂" 完全随机 "它是随机的"就说完了全部
这条曲线不是一个已被证实的规律,是我们对尺子提出的要求。下面两节会看到,前两把尺子做不到;第 06 节会回头质疑这条要求本身。
🌀 文学与艺术 · 音乐落在两端之间 1975 年 Voss 和 Clarke 把大量录音的响度与音高涨落做频谱分析,发现它们既不像白噪声(前后完全不相关),也不像慢漂移的随机游走,而是落在中间的 1/f 谱上:短程有关联,长程也有关联,但都不锁死。这给上面那条曲线的中点提供了一个可测的坐标,并且推出一个可验的预测——纯随机音符与纯周期循环生成的曲子,失败方式应该是相反的两种(一种没有走向,一种没有意外),而不是同一种"不好听"。但别多读:1/f 是必要不充分,把噪声整成 1/f 谱并不会得到音乐。

EN Any usable measure of complexity must score low at both ends: a page of nothing but A, and a page of coin flips. Everything we actually want to call complex — a cell, a language, a city, a novel — sits in between: partly predictable from a sample, never fully. This inverted-U is a requirement we impose on the ruler, not a law that has been proven; section 06 returns to question it.

02熵:测的是"你猜不猜得到"(Entropy — How Surprised You Are)

第一把尺子来自通信工程。1948 年,贝尔实验室的 Claude Shannon 要解决的问题很具体:一条电报线一秒钟最多能传多少东西。

他给出的量叫信息熵(Shannon entropy),单位是比特(bit)。定义可以用一句大白话说完:平均而言,你要问多少个"是不是"的问题,才能确定下一个符号是什么。

如果下一个字母永远是 A,你一个问题都不用问,熵是 0。如果下一个字母是 26 个字母里等概率的一个,你大概要问 4.7 个问题(因为 2 的 4.7 次方约等于 26),熵是 4.70 比特。真实英文介于两者之间:按单个字母出现的频率算,大约 4.1 比特——e 比 z 常见得多,所以你能少问一点。

熵的排序:乱码最高,有意义的文本紧随其后,纯重复垫底 ① 一页全是 A 字母出现频率 0 比特/字母 一个问题都不用问 ② 一段真实英文 e t a o i n s h r d … 约 4.1 比特/字母 只按单字母频率算 ③ 26 字母均匀乱码 每个字母一样常见 4.70 比特/字母 满分
注意 ② 和 ③ 挨得有多近:4.1 对 4.70。在这把尺子上,一本小说和一页乱码几乎是同一个东西。

问题就在这张图里。熵给出的排序是:乱码 > 有意义的文本 > 纯重复。对通信工程,这个排序完全正确——乱码确实最占带宽。对我们要的那个"复杂",它错得离谱:它把满分发给了最无聊的东西,还把一本小说和一页乱码放到了几乎同一个位置。

还有一件更容易被忽略的事:熵不是某个对象自带的属性,它是相对于一个概率分布算出来的。"这串字母的熵"这个说法严格说不成立,成立的是"在假定它由某个信源产生的前提下,每个符号的熵"。换一个信源假设,同一串东西的熵就变了。上图里英文取 4.1 比特,是因为只考虑了单个字母的频率;Shannon 1951 年那篇文章里让人去猜下一个字母、把上下文也算进来之后,英文每字母的熵掉到了大约 1 比特出头。同一段文字,两个数字差四倍,因为问的不是同一个问题。

🌀 工程与技术史 · "口令强度"这个说法从一开始就搭错了 既然熵是分布的属性而不是字符串的属性,那么"Tr0ub4dor&3 的熵是多少"这个问题就没有答案;有答案的是"生成它的那套流程能等可能地产出多少种结果"。xkcd 第 936 号漫画讲的正是这件事:四个随机常用词拼起来的口令看着"简单",但它的生成分布远大于一个被逐字符改写的单词。结论是可操作的——口令强度只能审计生成方式,审计成品是在量错的那一头。美国国家标准与技术研究院(NIST)2017 年的口令指南干脆删掉了"必须含大写与符号"这类对成品的硬性要求,理由正是如此。
🎯 决策线

下次看到"这个系统的熵是 X"或者任何一个"多样性指标",先问两件事:符号表是什么(你把什么算作一个符号),粗粒化怎么切的(多细算一个不同的状态)。这两项不同,两个数字就不可比——这是跨团队的复杂度指标永远吵不出结果的头号原因。要做的动作:上报任何熵/多样性数字时,把这两项写在同一行;写不出来,这个数字不进决策。

EN Shannon entropy measures how many yes/no questions you need to pin down the next symbol. Zero for a page of A, about 4.1 bits per letter for English by single-letter frequency, 4.70 bits for uniform gibberish. Its ordering is gibberish > prose > repetition — correct for a telegraph line, wrong for what we mean by complex. Entropy is also a property of an assumed distribution, not of the object: Shannon's 1951 context experiments put English near 1 bit per letter, four times lower, for the same text.

03柯尔莫哥洛夫复杂度:最短的那段程序(Kolmogorov Complexity — The Shortest Program)

第二把尺子想绕开"要先假定一个信源"这个麻烦,直接问对象本身。

1960 年代,Ray Solomonoff、Andrey Kolmogorov 和 Gregory Chaitin 各自独立想到了同一件事:一个东西的复杂度,就是能生成它的最短那段程序的长度。这个量叫柯尔莫哥洛夫复杂度(Kolmogorov complexity)。

好处是它彻底摆脱了概率。不用假定谁在产生这串东西,只问:要把它完整重建出来,你最少得写多少字。

三段都是 1000 个字符 — 生成它们的最短程序差了两个数量级 字符串(都是 1000 字符) 最短程序的长度 ABABABABABABABAB…AB AB 重复 500 遍 「打印 AB 五百遍」 14159265358979323846… 圆周率小数点后 1000 位 「跑圆周率算法,取前 1000 位」 QJXFVMZTLKDPWRHBSNCG… 抛硬币抛出来的 「打印 QJXFVMZ…」整串照抄 随机串没有比它自己更短的描述 — 于是它又拿了满分
圆周率的小数展开看起来完全没规律,但它的柯氏复杂度极低:几行算法就能重建任意多位。"看起来随机"和"真的随机"是两件事。

这把尺子确实修好了一件事:它把看起来随机和真的随机分开了。圆周率的小数位通不过任何随机性检验之外的直觉判断——你盯着它看不出任何规律——但它的最短程序只有几行。凡是"能算出来"的东西,柯氏复杂度都低。

然后它在同一个地方翻了同样的车:真正随机的串没有比整串照抄更短的描述,所以它的柯氏复杂度是最高的。抛硬币的结果又一次成了世界上最复杂的东西。

它还多带了一个麻烦:柯氏复杂度算不出来。不是"很难算",是数学上已经证明不存在一个通用程序,能对任意输入给出它的最短描述长度。你永远只能得到一个上界("我已经压到这么短了"),永远不能确认这是最短的。Chaitin 把这件事推得更远:存在一个常数,使得任何形式系统都无法证明任何一个具体的对象的柯氏复杂度超过这个常数。用大白话说——"这个东西确实很复杂"这句话,在绝大多数情况下不可证明。

🌀 生物学 · 基因组大得没道理 日本重楼(Paris japonica)的基因组约 1490 亿个碱基对,是人类的约五十倍;肺鱼和一些两栖类也远超人类。这曾被当成难题,叫"C 值悖论"。柯氏复杂度一上手,难题就消失了:这些庞大基因组里绝大部分是重复序列,而重复序列的最短描述极短——人类自己的脱氧核糖核酸(DNA)里也有一半以上是可高度压缩的重复元件。由此推出一个原本容易忽略的结论:基因组长度量的是存储量,不是描述长度,拿它给物种排"复杂度"从一开始就拿错了尺子——而这也顺带说明,"垃圾 DNA 有多少"这个问题,与"这个物种有多复杂"根本不在同一个量纲上。
🎯 决策线

有人说"这东西太复杂了",先分清是确实没有更短的描述,还是他还没找到规律。有一个便宜到近乎作弊的检验:把它压缩一下。日志、配置文件、报表、代码——gzip 能压到原来 5% 的东西,它的"复杂"是重复,该做的是去重,不是加人。注意这个检验只在一个方向上有效:压得动就证明它简单,压不动只证明你还没证明它简单。

EN Kolmogorov complexity is the length of the shortest program that outputs the object. It fixes one thing — the digits of π look random but compress to a few lines, so "looks random" and "is random" finally separate. It fails in the same place as entropy: a truly random string has no description shorter than itself, so it scores highest again. And it is uncomputable — you only ever get an upper bound, and by Chaitin's result, "this object really is complex" is unprovable beyond a fixed constant.

04有效复杂度:把随机的部分扣掉(Effective Complexity — Subtracting the Noise)

两把尺子在同一个地方翻车,说明问题不在尺子,在问法。Murray Gell-Mann 和 Seth Lloyd 在 1996 年换了个问法。

他们说:一个对象的完整描述,可以拆成两部分——规律的那部分(这个对象所属的那一类东西共有的结构)和随机的那部分(在这个结构之内、纯属偶然的具体取值)。有效复杂度(effective complexity)只算前者的长度。

拿抛硬币的记录说事:完整描述它需要一千位,但其中"规律"的部分只有一句话——"一千次独立、公平的抛掷"。这句话很短,所以随机串的有效复杂度接近零。而食盐晶体的规律部分也很短——"钠氯交替,无限重复"。两端同时被压到低分。只有那些规律本身就很长、需要一大段话才能说清结构的东西,才能拿高分。

把完整描述拆开:只有铜色那一段算数 规律部分 = 有效复杂度 随机部分(不算数) 食盐晶体 「钠氯交替,无限重复」 有效复杂度:低 一段真实基因组 一大段结构 + 一堆中性突变 有效复杂度:高 抛一千次硬币 「一千次公平独立抛掷」 有效复杂度:≈ 0 完整描述长度
整根柱子的高度是柯氏复杂度,铜色那一段才是有效复杂度。最右边那根柱子最高,有效复杂度却几乎为零——这正是前两把尺子修不好的地方。

这一步是真的进展。但它带来一个新东西,而这个新东西是本期最要紧的一句话:"哪部分算规律、哪部分算随机"这条线,不在对象里,在切它的人手上。

同一份基因组,在研究物种分类的人手里,个体之间的差异是噪声;在研究群体遗传的人手里,那些差异就是全部的信号。同一份销售数据,季节性对某个部门是规律,对另一个部门是要剔除的干扰。Gell-Mann 和 Lloyd 自己就明说了这一点:有效复杂度只有在指定了"由谁、以什么粗粒化程度来看"之后才有值。科学哲学家 James McAllister 在 2003 年把这条批评推到底——既然任何一组数据都能被不同的观察者切出不同的规律集,有效复杂度就不是对象的客观属性。

该怎么看待这件事,取决于你要它干什么。如果你要一个能刻在石头上的宇宙常数,那这是致命伤。如果你要的是一把工作用的尺子,那它只是把一个隐含的选择变成了必须写出来的参数——而这多半是好事。

🌀 经济与制度 · 出口清单里的"规律部分" Hidalgo 和 Hausmann 的经济复杂度指数不看一个国家出口多少,看它出口的东西里有多少是别人做不了的——做法是把"国家—产品"矩阵反复迭代,把随行情年年涨落的那一层洗掉,只留下稳定的能力结构。这就是"扣掉随机、只留规律"的一次真实实做。由此得到一个从总量里看不出来的结论:两个人均收入相同的国家,后续增长可以差得很远,而差别不在收入这个标量里,在被洗出来的那部分结构里——所以看一个经济体(或者一家公司),要看它产品清单的形状,不是它的总量。

EN Gell-Mann and Lloyd split a full description into regularities plus random detail, and count only the regularities. Coin flips need one short sentence of structure, so they score near zero; a salt crystal also needs one short sentence. Both ends collapse, which is exactly what was wanted. The cost: the line between regularity and noise is drawn by an observer at a chosen coarse-graining, so effective complexity is not an objective property of the object (McAllister 2003). For a working ruler that is a parameter you must declare, not a fatal flaw.

05逻辑深度:生成它花了多少功夫(Logical Depth — What It Cost to Make)

还有一条完全不同的路。1988 年 Charles Bennett 问的不是"描述有多长",而是"从最短的那段描述出发,跑出这个东西要多少步"。

这个量叫逻辑深度(logical depth)。它把"描述"和"生成"分开了,而这一分立刻解释了一件前面几把尺子都解释不了的事。

抛硬币的记录,程序很长(整串照抄),但运行只要一步——打印。它是浅的。食盐晶体,程序很短,运行也几乎不用算。它也是浅的。而圆周率小数点后第十亿位开始的那一千位,程序很短,但要拿到它必须实打实地算上十亿位——它是深的。一个物种的基因组同理:描述它的规则不算太长,但那套东西是几十亿年的试错一步步跑出来的,没有捷径可以跳过去。

"描述有多长"和"生成要多久"是两个独立的方向 深:短描述 + 大量计算,跳不过去 最短描述有多长(柯尔莫哥洛夫复杂度)→ 生成要跑多少步 → 食盐晶体(浅) 短程序,几步就摆完 抛硬币记录(浅) 长程序,但只用打印一次 圆周率第十亿位起的一千位 几行算法,十亿步计算 一个物种的基因组 几十亿年试错,没有捷径 两端在横轴上离得最远,在纵轴上却挨在一起 — 它们共同的特征是"便宜"
逻辑深度把价值放在生成历史上:一个深的对象携带着无法回放的计算,你拿到它的唯一办法是重跑一遍。

这把尺子最有用的地方是它对"值不值钱"给了一个说法。一段深的东西——一套跑了十年的流程、一个物种、一份积累出来的客户名单——它的描述可以很短,但它自己不能被便宜地重造,因为里面压着一段跑过的计算。这和"它有多大""它写了多少条"完全无关。

🌀 历史与制度 · 抄得来条文,抄不来判例 十九世纪多个拉美共和国按美国宪法的样子立国,条文相似度很高,运行结果差异极大。逻辑深度给这件事一个不必归咎于民情或素质的解释:一部宪法真正在起作用的部分,是几百年判例一步一步跑出来、无法从条文回放的那段计算;条文是最短描述,判例是运行步数。于是有个很实用的判据——评估一套制度(或一份公司流程手册)能不能照搬,别数它有多少条,数其中有多少条是被具体案子逼出来的:那部分不会跟着文本一起搬走。
🎯 决策线

评估一个已经存在的东西(祖传代码、走了十年的流程、一份客户名单),别用"它有多大",用"从零重建它要跑多少次真实反馈"。可操作的近似问法:这里面有多少条规则,是当初被一次具体事故打出来的?说不出几条 → 它是浅的,重写的成本就是写代码的时间。能说出几十条、每条都对得上一次事故 → 它是深的,重写的成本是重新踩一遍那些坑的时间,通常高一个数量级。

EN Bennett's logical depth asks not how long the description is but how many steps it takes to run. A random string is shallow (long program, one print). A crystal is shallow (short program, trivial run). The billionth digits of π are deep: short program, a billion steps you cannot skip. So is a genome. Depth prices the thing that cannot be cheaply recreated — the computation frozen inside an object, independent of its size.

06这套说法在哪儿不成立(Where This Breaks Down)

现在说反面,而这一节比前面五节都重要。

第一,这四把尺子在同一个对象上会给出互相矛盾的排序。它们不是"同一个东西的四种测法",是四个不同的量,只是共用了"复杂度"这个词。

同样三个对象,四把尺子给出的排序互相打架 食盐晶体 一本小说 一页乱码 香农熵 最低 高 最高 柯氏复杂度 最低 高 最高 有效复杂度 低 最高 ≈ 0 逻辑深度 浅 深 浅 看最右一列:前两把尺子给"一页乱码"发满分,后两把给它垫底
所以"把复杂度降下来"这句话在没有指明是哪一把尺子之前,没有内容。

第二,这些量基本都算不出来。柯氏复杂度不可计算已经说过;有效复杂度依赖一个你必须自己指定的粗粒化;逻辑深度同样绕不开"最短程序"这个不可计算的起点。实践中能拿到的永远是替代品——压缩率、模型的参数量、拟合残差——而替代品和原量的关系,多数时候没人验证过。

第三,"两端都低、中间高"这条曲线是被假设的,不是被证明的。Seth Lloyd 曾经列过一份清单,收录了四十来种不同的"复杂度"定义,它们分别是为不同学科的不同问题造的。把它们全都摆在同一条有序—随机轴上、指望它们在同一个位置取峰值,这个期待本身没有依据。

元胞自动机(cellular automata)这边有过一次很清楚的教训 → 参考 · 生命游戏与元胞自动机:1990 年前后 Chris Langton 提出用一个参数 λ 刻画规则的"有序—混沌"位置,Norman Packard 的实验似乎显示演化会把规则推向"混沌边缘"。1993 年 Melanie Mitchell、Peter Hraber 和 James Crutchfield 重做了这个实验,发现原结果主要是实验设置和遗传算法的机制造成的,不是"混沌边缘"本身的性质。这不是说边缘不存在,是说那次证据不成立——而"混沌边缘"至今仍然是本领域被引用最随意的短语之一。

第四,也是最要紧的:这四把尺子都不预测任何东西。它们是描述性的量,不是动力学。知道一个系统"有效复杂度很高",不能推出它会不会崩、什么时候崩、往哪儿走。本站前四十期讲的机制——反馈、临界、幂律、韧性——每一条都能推出可检验的预言;本期这四把尺子一条都不能。它们的价值在别处:它们把"复杂"这个模糊词拆成几个各自意思明确的量,从而让"这很复杂"这句话变成一个可以追问的说法。这是词汇上的进展,不是理论上的进展——把它当成后者,就是复杂性科学被批评得最多的那种毛病。

🎯 决策线

不要把"复杂度"做成一个单一的考核数字。任何"把复杂度降下来"的目标,必须先说明降哪一种:降熵(减少不确定性,通常好)、降柯氏复杂度(减少规则条数,通常好)、降有效复杂度(砍掉真实存在的结构,多半坏)、降逻辑深度(丢掉积累的经验,几乎总是坏)。上报模板里那一栏笼统的"复杂度",要么拆成这四条,要么删掉——它现在唯一稳定的作用是让四种意见看起来像在讨论同一件事。

EN Four limits. The four measures disagree with each other on the same object, so "complexity" names four quantities, not one. Almost none of them is computable, so what gets used in practice are proxies whose relation to the original is rarely checked. The inverted-U is an assumption, not a result — Seth Lloyd catalogued roughly forty rival definitions, and the 1993 Mitchell-Hraber-Crutchfield reanalysis dissolved the best-known "evolution to the edge of chaos" evidence. Most importantly, none of these measures predicts anything. They are a gain in vocabulary, not in theory.

🎒 场景 · BigCat

  1. 投资与仓位每次一个策略的回测曲线变得更漂亮,几乎都是因为往规则里又加了一个条件。把这套规则当成一段描述来看:手上真正独立的历史事件有多少个(不是多少根 K 线,是多少段互不相同的市场状态)?规则条数一旦逼近这个数,回测拟合的就是那段本该被扣掉的随机部分——有效复杂度接近零,柯氏复杂度却在涨。具体动作:策略表里加一栏"规则条数 ÷ 独立事件数",自己定一条线(比如 1/10),超线的策略直接不看回测曲线。
  2. 育儿孩子把一件事做得特别"绕"——一套自己编的游戏规则、一个多此一举的步骤——大人的两种本能反应("简化一下吧"和"真聪明")测的是同一件事的两个错误维度。改问的那一句:这一条是怎么来的?答得出"上次那样不行"的,是逻辑深度,那段计算是他自己跑出来的,你替他简化就是把它抹掉;答不出、纯粹是一次性想出来的,才是可以随便讨论的描述长度。具体动作:打断之前先问那一句,答得上来就闭嘴看着。
  3. 写作与这个学习站本身每期定稿前那句"这期够不够有分量",下意识的判据是长度和术语密度——而这两样量的都是熵那一头,乱码在这把尺子上永远赢。改看的是:这一期里,有多少段是删掉之后结论会变的(规律部分),有多少段删了什么都不影响(随机部分)。具体动作:定稿前做一遍删除测试,逐段问"删了结论变不变";如果一次能删掉三段以上而结论不动,说明有效复杂度低,该重写而不是再加长。

🌀 越界 · 跨学科的联想(Crossings)

深入思考(Going Deeper)

如果"复杂度在中间取峰值"是我们强加的要求,那我们凭什么这么要求?

一个不太舒服的可能:因为我们自己和我们关心的一切都在中间,所以我们把"有意思"编码成了"复杂"。这未必是错的——尺子本来就是为用途造的——但它意味着这条曲线的地位是工程规范,不是自然规律。区别在于:工程规范可以按用途改,自然规律不能。谁要把它当后者用,就得先拿出一个独立于"我们觉得有意思"的判据。

熵一直在增加,那复杂度是不是也一直在增加?

不是,而且它们的形状不一样。Scott Aaronson、Sean Carroll 和 Lauren Ouellette 2014 年做了个很直观的模拟:让"咖啡"和"奶"在一个格子世界里混合,熵单调上升到底,而他们定义的一种复杂度先升后降——刚倒进去时是两块纯色(简单),完全混匀后是均匀的灰(也简单),中间那段丝缕交错的花纹才是峰值。这至少说明"熵增"和"复杂度增"是两条不同的曲线,也提示复杂结构可能本来就是一段过渡期的产物。

一个组织的复杂度能量吗?

能量的是替代品,而且要先挑尺子。想量柯氏复杂度,可以数不重复的流程规则条数(去掉重复项之后)。想量逻辑深度,可以数其中有多少条能追溯到一次具体事故。想量熵,可以看同一类请求的处理路径分布有多分散。这三个数会指向不同的整改方向,而这恰恰是好事——"我们组织太复杂了"这句话的问题就在于它同时暗示了三种互相冲突的整改。

为什么一个算不出来的量还值得学?

因为它划边界。柯氏复杂度不可计算这件事本身就是可用的结论:它意味着"最简解"永远不能被机械地找到,所以任何声称"我们已经做到最简"的说法都超出了可证明的范围;也意味着压缩率这类上界估计是原则上无法被消除的近似,而不是暂时的技术不足。一个量的价值有时不在它的数值,在它证明了哪些事做不到。

延伸阅读(Further Reading)