从拥挤的兔子到伪随机数算法

写于2017年7月30日。
阅读《复杂》一书时的笔记及延伸。
本文涉及到的生态学、数学、计算机科学部分都比较肤浅,如有错漏,欢迎斧正。

又是兔子

我们多少接触过这样一个问题

  1. 第一个月初有一对刚诞生的兔子
  2. 第二个月之后(第三个月初)它们可以生育
  3. 每月每对可生育的兔子会诞生下一对新兔子
  4. 兔子永不死去

问:第n月时,一共有多少只兔子?

对,描述兔子数量的数列就是我们熟悉的斐波那契数列,很多人都是通过这个问题了解递归的吧(也许吧,也可能是Tower of Hanoi)?

不过兔子怎么可能“永不死去”呢!那我们现在开始考虑兔子的出生率和死亡率。先从容易的来:每对兔子父母每年生四只小兔,然后死去。如果一开始有两只兔子(第0年),那么第1年会有四只兔子,第二年会有8只兔子……每年兔子的数量会翻一番。记第 t 年的兔子数量为

,那么:

,即

很显然,如果不受限制,兔子的数量会越来越多,最终撑满这个星球,乃至整个宇宙。

假如我们考虑种群数量增长所受的限制呢?可想而知,如果种群数量越来越多,也许很多小兔子由于太过拥挤,缺少食物和空间,没有繁殖就死去。整个种群的数量就不会呈现上述无限增长的情况了。生物学家用一种叫 logistic model 的简化方式来描述这种情况下的群体增长:


其中,
为这一代的种群数量,
为出生率,
为死亡率,k 为承载能力。

举个例子,如果出生率为2,死亡率为0.4,承载力为32,第1代有20只兔子,套用上面的模型,那么第2代有12只兔子;再把这个结果代入计算,会得出第三代仍然有12只兔子;从此种群数量维持在12。

如果我们改变一些参数,比如把死亡率降到0.1,那么依据模型计算,第2代有14.25只兔子,第三代为15.01816只兔子(不要在意兔子的数量为什么可以是小数)。实际上我们的计算过程是把这一代的计算结果代入模型公式,计算下一代的结果,这个重复不断的过程就是迭代,对模型进行迭代。

logistic map

由 logistic model 进行迭代计算还是有些麻烦,我们可以再进行一点简化:把出生率和死亡率合成一个变量 R,种群数量由承载率(当前种群数量与最大可能的种群数量的比率)x 代替,x = n / k,由于当前种群数量总是介于0和 k 之间,所以 x 总是介于0和1之间。

那么我们就可以把上面的logistic model的公式改写一下,于是我们有:

这个方程称为logistic map,是动力系统理论和混沌研究中的一个重要方程。

如果我们让 R 值变化,那么logistic map就很有趣了。

不妨先假定 R=2,我们发现,不管 x 的初始值是什么(先用0.2试试吧),最后总会达到同一个固定的值:

不同的初始值只会让到达0.5的速度有快有慢,但经过若干步骤后,都会到达0.5。那么这个0.5就称为不动点(fixed point)。

我们把 R 的值调大,也许这样的不动点依然后存在,但到达不动点的速度会越来越慢。假如 R=3.1 ,我们再来看看,会发现情况似乎不太一样了:

R=3.1,x0=0.2

x 的值最终会在0.5580141和0.7645665之间振荡。我们称之为吸引子。

随着 R 值的变化,情形会更加复杂。我从wikipedia上把结论摘录如下:

  1. 0和1之间:不论初始值数值为何,x 会越来越少,最后趋近于0。
  2. 1和2之间:不论初始值数值为何,x 会快速的趋近 (R-1)/R
  3. 2和3之间:经过几次迭代,x 也会越来越接近 (R-1)/R,但一开始会在这个值左右振动,而收敛速率是线性的。
  4. 3:x 仍然会越来越接近 (R-1)/R,但收敛速率极为缓慢,不是线性的。
  5. 3和1+√6(约3.45)之间:针对几乎所有的初始值, 最后会在2个值之间持续的震荡,即x 最后会是a,b,a,b...的变化,其数值和 R 有关。
  6. 3.45和大约3.54之间,针对几乎所有的初始值,x 最后会在4个值之间持续的震荡。
  7. 约大于3.54:x 最后会在8个、16个、32个值……之间持续的震荡,至于 R 何时会令 x 的值由 n 个到 2n 个,则和费根鲍姆常数 𝞭 = 4.669... 有关。
  8. 约为3.5699:这样的振动消失,整个系统开始在混沌的状态之中。针对几乎所有的初始值,都不会出现固定周期的震荡,初值再微小的变化,随着时间都会使结果产生明显的差异,这就是典型混沌的特性。
  9. 大于3.5699:整个系统在混沌的状态之中。不过,当中有些特定的 R 值还是使系统变成非混沌,有周期性的结果,这些区间称为“稳定岛”。例如当 R 约大于3.82,会出现3个值的周期,再大一点出现6个值及12个值的周期。
  10. R 从大约3.5699到大约3.8284之间,系统混沌性质发展的现象有时会称为Pomeau–Manneville场景,其特征是周期性的震荡和非周期性的行为会穿插出现。此特征可以应用在半导体元件中
    。也有其他区域会使系统的周期为5个值,不管任意周期都存在某特定的 R,使周期为指定值。
  11. 大于4:针对几乎所有的初始值,系统最后都会超过区间[0,1]并且发散。

似乎有点枯燥,不过没关系,我们来画个图吧,通过图形来了解一下这个混沌系统。取一个超过3.5699, 不超过4的 R 值,这里我们不妨取 R = 4,还是令 x 初始值是0.2,那么迭代100次:

R=4,x0=0.2

一个感觉,杂乱无章。对于每个 x 的值,虽然它能唯一决定下一个 x 的值是什么,但它们却组合成一个看起来非常随机的轨迹。在计算机中,我们甚至可以用它来生成伪随机数。因此,表面的随机性可能来自非常简单的确定性系统。

不仅如此,对于一个能产生混沌的 R 值,如果初始值有任何的不确定性,那么一定时间后的轨迹就无法预测了。还是刚刚的图,我们考虑稍稍修改一下初始值,比如修改小数点后第10位,假定初始值是0.2000000001会怎么样?这与0.2非常接近,我们把两条轨迹绘制到一起看看:

可以看出,大概在 t = 30时,两条轨迹已经分开,x 的值已经无法预测了。实际上只要初始值有不确定性,不管精确到小数点后多少位,最终都会在 t 大于某个值的时候变得无法预测。

伪随机算法

接下来,我们就来尝试使用logistic model的混沌特性来实现一种简单的伪随机算法。

function* RandomGenerator() {
  let seed = .2;
  function getNext(x) {
    return 4 * x * (1 - x);
  }
  for (let i = 0; i < 30; i++) {
    seed = getNext(seed);
  }
  while (true) {
    seed = getNext(seed);
    yield seed;
  }
}

const randomGenerator = RandomGenerator();

function random () {
  return randomGenerator.next().value;
}

实际上一些常见的伪随机数生成算法,例如线性同余法,也是使用了类似的手段,通过迭代产生混沌系统。而这类的算法所追求的,我觉得有三个方面的内容:

  1. 统计意义上的随机,即随机数结果分页均匀,不能有所倾向。
  2. 更大的循环区间。比如像如上算法,受R值和计算机浮点数精度的影响,一定会在某个时刻产生与之前相同的结果,使得迭代进入循环。而用线性同余算法,循环区间则与选取的模数大小相关。
  3. 更快的性能。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,563评论 18 139
  • 类似气象, 海洋这样的复杂系统是一个对初始条件极为敏感的结构, 开始初始值微小不同会导致最终结果的很大差异, 美国...
    遇见数学阅读 828评论 0 1
  • 第一部分 背景和历史 第1章~第7章 术语卡 术语:奥卡姆剃刀(Occam's Razor) 印象:entia n...
    MealieXu阅读 1,908评论 0 1
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,263评论 25 707
  • 感情不是你喜欢的就一定会是适合你的
    一只解读感情的猫阅读 86评论 0 0