人工社会模型初探-糖人帝国

Posted by rogerclarkgc on 周一 02 一月 2017

怎么来的

这个小小的模型来自于1996年的Epstein和Axtell的计算机模拟模型,这个模型有点类似于一个二维细胞自动机,每个细胞都有自己的行为准则,在模型的一开始,他们都随机降生在一块“糖域”上,为了活下去,它们会各自为战,观察四周寻找它们附近的糖块并收割,每进行一次移动,它们会消耗自身储备的糖。糖域中的糖并不持续供应,而是周期性的补给。

这样在一个人工建立的“自然选择”条件下,随机初始化的糖人种群,在一定时间的演化后,会出现何种有趣的结果?有时一个简单的系统,确实也会反应出一些复杂而有启发性的现象。

怎么做的

我选择使用Processing来构建、展示、输出我的模型,因为这种语言基于java且兼容大部分java库,另外由于她主要用于帮助设计师进行创作,十分容易的实现动画效果,效率很高,因此不需要操心模型输出时的执行效率问题。在模型结果分析方面,我使用我常用的R,它简单快速,能够很好的反应出我的想法。

这个模型基本思路很明确,主要由两个部分组成——能自动更新糖的糖域和具有一定规则的糖人。糖人和糖域之间存在信息交换——糖人搜索糖块、糖人收割糖块,因此很容易使用基于对象的模式来对这个模型进行编程。

我根据自己的需求重新定义了糖人的属性和行为规则,如下:

  1. 糖人具有视力、移动能力、代谢能力、糖包四个基本属性,此外,还有一组位置变量记录它当前的位置。
  2. 糖人可以在糖域的上下左右四个方向观察,搜索视野里含糖最多的地方,并尝试朝着那个地点移动。
  3. 每进行一次移动,糖人会从糖包取出糖消化作为能量,消化的多少由代谢能力决定。
  4. 糖人会收割目标地点所有糖,并放置到糖包中,如果糖包中的糖在本回合消耗至低于0,并在下一个回合还没获得足够的糖,那么糖人会立即死亡,并清除出种群。

糖域也有一定的规则:

  1. 糖域的大小由用户指定,并且有如下几种基本形式:

    • 随机糖域,每个地点的糖量由一个perlin噪声决定
    • 非均衡糖域,有两个随机位置的糖峰,其他位置糖量为0
    • 均衡糖域,所有位置糖量相等
    • 正态分布糖域,有两个随机位置的糖峰,呈现二维正态分布
  2. 糖域每隔一定时间回复糖块。

由于一开始没有考虑糖人之间的重叠问题,并且糖人之间的信息交换会极大加大问题的复杂度,所以我的模型中的糖人会重叠,糖人之间也没有任何信息交换。

我采用随机初始化的方式初始糖人种群,种群用java的arrayList方法实现,这是一个动态列表,能够很方便的加入和删除列表元素,用来模拟种群最适合不过。

先来看看,4种糖域的样子,这些图片都是用R脚本生成

sugarscape-random

随机分布的糖域

sugarscape-unbalance

非均衡的糖域

sugarscape-balance

均衡糖域

sugarscape-biunif

二元正态分布糖域

在定义完了糖人和糖域后,只需要定义好运行过程,完成糖域和糖人列表的初始化后就可以完成整个模拟程序了,在一回合糖人社会中,程序按照如下模拟:

  1. 检查回合数,如果处于特定的回合数中(如是5的倍数),补充糖域的糖
  2. 利用糖人列表的writeLog()方法记录日志信息
  3. 显示糖域和糖人位置到屏幕
  4. 更新糖人和糖域状态,此时会逐个遍历每个糖人列表中的糖人,糖人将执行寻找糖块-收割-代谢消化的三步。当糖人所存储的糖为0时,将从糖人列表中永久去除,即判断该糖人已经死亡。

在执行了多代后,部分糖人由于缺少死亡而死亡,但有一部分确活的越来越好,它们十分有效的聚集在糖域的高糖区,迅速收割产生的糖,由于没考虑糖人的堆叠,因此,糖域上会出现极端的人口分布,往往一个方格上聚集了几十个糖人。

下面是某个模拟的动态过程:

sugargif

这个模拟只进行了40回合,就已经出现了明显的“阶级分化”,一部分糖人死亡,活着的糖人都聚集在了糖域上的两大糖山上。如果我们延长模拟运行的时间,会有更加显著的结果

结果

通过长时间运行模型,让结果比较稳定后,使用R展现这些结果,下面是某个比较好的模拟结果。 选用二元正态分布的糖域来进行模拟,该糖域有两个糖峰,糖峰位置是随机分布在半个窗口内。

sugarmap

首先来看不同阶段的人口分布:

first

初始阶段,第一回合的人口分布遵循随机分布的模式

half

经过一半的回合数后,人口已经开始向糖山的峰顶聚集

last

到了最后一回合,两大“财团”已经形成,它们牢牢把住了糖山的峰顶,其他区域已经没有了糖人存在。

每个糖人的特征都是不同的,是否是这些特征造成了阶级的产生?同样,我们用R来展示这些结果,我编写了一个脚本,用来处理产生的日志数据,输出图形化的统计结果,来看看这次模拟的一些统计展示。

feature

初始状态下所用糖人的特性的直方图,可以看到是一个比较均匀的分布,但是总体来看数值偏小的一类较多,它们的特点是:初始糖量少、视力差、代谢能力小、运动能力差。

compare12

比较第一局和最后一局中活着的糖人,可以发现,最后活着的糖人在视力上较差,代谢能力小,运动能力分布在2——4和8-10之间较多,但是与第一局的差别不大。

dead

随机抽取了最后的活着的糖人和死去的一个糖人,可以看到活着的糖人似乎有很好的运气,一开始就降生在有糖的位置,并且在每次搜索中都找到了糖,而且移动到了糖越来越多的位置,而死亡的糖人一开始也有较好的运气,但是在75局左右就开始陷入了入不敷出的阶段,最后糖块消耗殆尽,饥饿而死。

dis

最后是财富的分布,可以看到一开始大家财富分布较均衡,穷人相对较多,到了25%局,就开始了出现财富分配不均的现象,此时穷人更多了,而财富开始聚集在少部分人手中,到了最后一句,讲道理,活到这个时候的都是富翁了,但在这个“财团”里,财富同样分布十分不均,超过10000的巨富只有不到十分之一,而大部分人只是小富小贵。

疑问

这个模型比较粗糙,但已经反映了一些有趣的问题,它重现了财富分配的不均现象,在一个类似自由市场的条件下,缺乏监管和监督的经济体必然会出现少量人把持巨大财富的现象,但带给我的更多是疑问,首先,在初始化时,各个糖人的特性分布比较平均,总体是数值较小的糖人较多,但在第一局和最后一局的糖人特性对比中,却没有出现我所想的结果,按照自然选择的原理,我认为,那些视觉能力强、运动能力强、代谢能力小的个体更加容易存活,而那些视觉能力弱、运动能力差、高代谢的个体会更容易被淘汰,但比较的结果却不尽我意。似乎那些数值较小的个体相对存活的可能更大

我对结果的显著性产生了怀疑,于是进行单因素方差分析,结果如下

> library(multcomp)
> step_result <- aov(step ~ rounds, data = step_roundcompare)
> summary(glht(step_result, linfct = mcp(rounds = "Tukey")))

 Simultaneous Tests for General Linear Hypotheses

Multiple Comparisons of Means: Tukey Contrasts
Fit: aov(formula = step ~ rounds, data = step_roundcompare)

Linear Hypotheses:
         Estimate Std. Error t value Pr(>|t|)  
150 - 1 == 0  -0.3247     0.1322  -2.456   0.0142 *
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1
(Adjusted p values reported -- single-step method)

对第一局和最后一局的运动能力方差分析显示,其显著性为0.014,并且均值上,最后一局存活糖人的运动能力要微微小于第一局的所有糖人

> vision_result <- aov(vision ~ rounds, data = vision_roundcompare)
> summary(glht(vision_result, linfct = mcp(rounds = "Tukey")))

 Simultaneous Tests for General Linear Hypotheses

Multiple Comparisons of Means: Tukey Contrasts

Fit: aov(formula = vision ~ rounds, data = vision_roundcompare)

Linear Hypotheses:
         Estimate Std. Error t value Pr(>|t|)    
150 - 1 == 0  -0.4957     0.1260  -3.933 8.73e-05 ***
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1
(Adjusted p values reported -- single-step method)

对视觉能力的分析,同样存在更加显著的差距,最后一局和第一局所有糖人相比,视力稍差

> stomach_result <- aov(stomach ~ rounds, data = stomach_roundcompare)
> summary(glht(stomach_result, linfct = mcp(rounds = "Tukey")))

 Simultaneous Tests for General Linear Hypotheses

Multiple Comparisons of Means: Tukey Contrasts

Fit: aov(formula = stomach ~ rounds, data = stomach_roundcompare)

Linear Hypotheses:
         Estimate Std. Error t value Pr(>|t|)    
150 - 1 == 0  -0.7049     0.1305  -5.403 7.52e-08 ***
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1
(Adjusted p values reported -- single-step method)

代谢能力的显著性同样很大。并且最后一局与第一局估计值相差最多,达到-0.7049

综上,统计检验都出现了比较显著的结果,与第一局的糖人比较,最后一局的糖人有如下特点:

  1. 运动能力:与第一局个体相比,运动能力稍差
  2. 视觉:视觉较第一局的个体稍差
  3. 代谢:代谢能力要比第一局的个体要小,每次运动消耗更少的糖

统计分析的显著性拒绝了我最开始的前两个假设,即视觉能力强、运动能力强的个体更容易存活,接受了最后一个假设代谢能力小的个体更容易活到最后。

总的来说,得出这个结果让我十分惊讶,我反复运行了几次模拟,得到的结果都类似,总体表现是视觉能力和运动能力似乎对糖人的存活影响远远不如代谢能力。然而,在我的模拟参数设定中,每隔5回合就会补充新的糖,糖域的中的糖虽然是正态分布,但总体来看,有糖的区域是远远大于无糖的区域的,因此,这个模拟社会的自然条件并不是很严酷,为什么会这样呢?我至今仍然没有想明白。

后记

虽然模型的结果并不如我所想,但整个探索的过程受益颇多,从零开始一步一步搭建这个模型的过程让我学到很多,也用到了许多以前学到的知识,整个模型从12月开始初步实施,到现在已经是2月,我删删改改,从一开始的Processing展示到最后与R的结合,也算是一个迷你的研究课题了,如今这篇博文就当做我的“研究论文”,按照惯例,论文结尾总要做一点研究展望,我也写下几句吧。

  1. 模型的初始化需要进一步改善,也许需要一种更为均匀的随机化初始方式
  2. 糖人之间的交互可以作为新的研究方向,包括原始的物物交换,抢夺,分享等行为的模拟
  3. 宏观政策的模拟,进一步研究宏观调控对阶级的影响。

tags: Processing, model, R