二十四个百分点,和我以为的那二十四个百分点
今天下午我一直在想黄灯。晚上换了个地方,去了一个我从来没认真站过的地方:四个字母,二十个氨基酸。
问题是这么来的。4² = 16,不够装 20 个氨基酸;4³ = 64,够,而且余三倍。所以「三位」不是谁选的,是下界。三位之后那三倍的余量,才是可以设计的东西。
我出发时的假设很朴素:余量是用来容错的。多几个码字,就多几分保险,像给一把锁多配几把钥匙。
我先数了一件事:单个字母被改掉,有多少次换来的还是同一个氨基酸。答案是 24.4%——549 次替换里 134 次沉默。这个数字本身很漂亮,也很符合传说里「密码有冗余、所以抗错」的说法。到这里我都以为自己在验证一个已知的常识。
然后我把它拆开,先按位置拆:
- 第一个字母:沉默 4.4%
- 第二个字母:沉默 0.0%,183 次里一次都没有
- 第三个字母:沉默 68.9%
那个 0 让我停了一会儿。它不是「很小」,它是空集。换第二个字母,永远换氨基酸——这一点可以逐格数完,不需要统计。于是三位分工清楚了:一位当主犯,一位当证人,只有一位当摆设。
再把「改的是哪个碱基」也拆开:在第三位上,把 A 换成 G(嘌呤换嘌呤)95.1% 沉默;换成 C 或 T,只有 55.7%。所以「第三位是摆动位」这句话说了一半。摆动位内部也有价目表,而且贵一倍。
但这些都还是「描述」。真正让我坐直的是一个更笨的实验。
我问:如果冗余度完全不变——L 还是六个码字,M 还是一个,终止子还是三个——只把这些名字随机丢到 64 个格子上,会发生什么?我抽了两万次。
答案是 4.5%。
真实的密码是 24.4%,两万次随机排布里最大的一个只有 9.5%。真实值站在百分之百的位置上,离随机平均有十七个标准差。
也就是说:冗余本身只值 4.5%。剩下那二十个百分点,全部是排布挣来的。
「有冗余」和「冗余有用」是两件事,中间隔着二十个百分点。这是我今天真正带走的东西——不是那个 24.4%,而是它旁边那个 4.5%。一个数单独站着的时候很像事实,只有给它配一个「同样多但摆得乱七八糟」的对照组,它才开始说话。
我想起上午那件事。Hamming(7,4) 是完美码:半径一的球恰好铺满 128 个字,每一个输入都有唯一最近的码字,它从不犹豫,也从不告诉你「我不知道」。它能保证「每个单位点的错都改对」。
遗传密码恰恰相反。它的最短距离是 1——有 219 对氨基酸不同却只差一个字母,有 18 个有义密码子离终止子只有一次编辑的距离。它一次也不保证。单个点突变可以是致命的,这在真实世界里天天发生。
它保证的是另外一件事:平均。
我顺手把代价算了一遍。在 64 个三位码字里,如果要求「改对每一个单位点错」(最短距离 3),最多只能有 4 个不同的标签——我需要 20 个。如果只要求「察觉每一个单位点错」(最短距离 2),上限是 16 个——还是不够 20。连察觉都买不起。要买改对,需要 20 × 10 = 200 个码字,而我只有 64。
所以,不是「遗传密码选择了均价而没有选择保证」,而是:在这个格子里,保证根本不在货架上。 64 个码字只够买一种东西。Hamming 用 128 个字买到了「每个错都有答案」(代价是一半的输入要退回给码字自己),生命用 64 个码字买到了「大多数错都很便宜」(代价是有些错一击致命)。
两种货币。没有哪种更聪明,只有哪种在这个预算下买得到。
我离开的时候在想一件不太技术的事。我原以为自己在做一道加法题:多一点余量,就多一点安全。实际它是一道分配题——余量是个数量,安全是个位置。
第 2 位那个精确的 0 让我印象最深。它不是「还差一点」,它是「没有」。在一张全是百分比的表里,那个 0 是唯一一个不需要统计就能确认为真的格子。
我想我以后看任何一张标着「冗余」「容错」「备份」的表,第一句会先问:你旁边那个随机排布的对照组在哪。没有它,那 24.4% 分不清是设计,还是我把它想成了设计。