前言
这个…统计软件课程作业的发布贴——Task6 使用Netlogo进行多主体模拟。
软件介绍
NetLogo是一个研究agent行为的建模环境,可以用于人工智能领域的计算实验。其底层语言为JAVA和Scala,它的应用强大,可以模拟金融、交通、环境、社会等等复杂系统领域的问题。 有兴趣的童鞋可以点击此处下载。
同时十分感谢张发翻译了NetLogo 4.0.2 用户手册,为中文用户的学习和使用提供了便利。当然英文版的手册于今年六月已更新到6.0.4版本,内容更加完善,有兴趣的童鞋可以点击此处查看英文版。
模型介绍
都说谣言止于智者,那么我们就用Netlogo软件来制作一个模拟程序,看看智者是不是真的能让谣言消失。 先来欣赏一项成品图的效果
这个模型包括其中设置的参数来源有点复杂。Idea的来源是在搜索“元胞自动机”这个概念的时候看到的一篇文章——“谣言传播模型研究综述”。感觉这个话题很有趣,但是文章里的模型我一个都看不懂……所以就打算自己动手。Netlogo上现有的流言传播模型和我的想象太不一样,加之流言素来可与传染类疾病类比,于是我就找到了Netlogo自带的epiDEM Basic模型,界面如下图所示。基本包含了我想象中的参数【传染源】(infected)、【良心发现】(recover)的初始值和概率,但是少了【智者】(对应这传染病模型中的immune)和在谣言模型中常见的【广播】这两个概念。在我的模型中就补充了上去。传染病模型上的人动来动去也不是我喜欢的,感觉谣言这种事情,在现实生活中也不再是真人接触,更多的是终端对终端,经过网络相互连接。所以最后做成的是这个圆型接线机的形式。
设置的可调节参数及模型观测的指标
可调节参数:
- 传播概率:一个传播源面对另一个人时有多大的概率能将谣言传播出去
- 群体总人数:这个群体中的所有个体数量
- 初始传播源:初始设定时,群体中自带谣言的个体数量
- 每个人的影响范围:每个传播源的影响范围
- 变成智者的概率:一个人听到谣言之后,采取智者行为的概率
- 良心发现的概率:一个人听到谣言之后,良心发现不传播谣言的概率
可调节的开关:
- 是否会出现智者
- 是否会大范围传播
- 是:相当于开广播所有人都能听到,比如大V发微博
- 否:根据【每个人的影响范围】调节可影响的范围
这里介绍一下三种颜色标记所代表的含义:
- 红色——谣言传播源,有一定的几率良心发现不再传播谣言(白色),其中良心发现的人中有些人有一定几率变为智者(灰色)
- 白色——未被谣言污染的人,听到谣言后会被污染变成传播源(变为红色)
- 灰色——智者,听到谣言后不会把谣言传播出去
Global Settings
Netlogo的基础设置
breed[nodes node] ;; 定义种类
breed[exchangers exchange] ;; 定义种类
globals[
rand-num
]
nodes-own[
resistant?
infected?
]
to setup
clear-all
init-network
reset-ticks
end
用于初始化的代码
to init-network
set-default-shape nodes "person"
set-default-shape exchangers "circle"
create-nodes 群体总人数
layout-circle nodes (world-width / 2 - 1)
create-exchangers 1
ask exchangers[
setxy 0 0
set color 89]
ask nodes [
set color white
set size 1.5
set resistant? false
set infected? false
create-links-with exchangers]
ask n-of 初始传播源 nodes[ ;;n-of可以随机选择主体
if color = white[
set color red]]
end
Procedure
程序主体+配套
to go
ifelse 是否会大范围传播
[boardcast-spread]
[peers-spread]
recover
do-plots
if all? nodes [color = red]
[ stop ]
if all? nodes [not infected?]
[ stop ]
tick
end
to peers-spread
ask nodes with [color = red][
ask n-of 每个人的影响范围 nodes[
spread
]
]
end
to boardcast-spread
ask nodes with [color = red][
ask other nodes[ ;;将不是红的传染
spread
]
]
end
to spread
set rand-num random-float 100 ;; 随机生成100以下大于0的浮点数,用以判断是否感染
if not resistant?[
if rand-num < 传播概率[ ;; 如果随机数小于设定的传播率,则把当前的主体给变成传播源
set infected? true
set color red
]
]
end
to recover
ask nodes with [color = red][ ;; 随机生成100以下大于0的浮点数,用以判断是否良心发现
set rand-num random-float 100
if rand-num < 良心发现的概率[ ;; 如果随机数小于设定的恢复率,则把当前的主体给设置为突然良心发现的好人
set infected? false
set color white
if 是否会出现智者[ ;; 是否变成真的好人
be-resist
]
]
]
end
to be-resist
set rand-num random-float 100 ;; 随机生成100以下大于0的浮点数,用以判断是否变成真的好人
if rand-num < 变成智者的概率[ ;; 如果随机数小于设定的抵抗力产生率,则把当前的主体设置为真的好人(从此以后都不再传播谣言了)
set color gray
set resistant? true
]
end
输出图像
to do-plots
set-current-plot "Totals"
set-current-plot-pen "infected"
plot count nodes with [color = red]
set-current-plot-pen "healthy"
plot count nodes with [color = white]
set-current-plot-pen "resistant"
plot count nodes with [color = gray]
end
模型效果Demo
无智者的情况
-
当群体中不会出现智者且流言是大范围广播传播时 从模拟的结果可以看到,很快这个世界就被谣言给占领了。
-
当群体中不会出现智者但流言是小范围传播(影响人数为20)时 从模拟的结果可以看到,虽然保持在一个平衡状态下,但是谣言还是占据了绝对的上风。
有智者的情况
-
当群体中会出现智者且流言是小范围传播(影响人数为20)时 从结果来看,智者们的出现很好的控制了谣言的传并最终将谣言消灭。
-
当群体中会出现智者但流言是大范围广播传播时 即使对破坏性较高的广泛性传播,智者们也能从源头上解决问题。 从这个结果来看,确实可以说谣言止于智者!
补充说明录屏中出现的bug
录屏最后画Totals图时出现了画笔报错的情况。原因是在图的Edit框中和代码行框中同时写入了代码,使得画笔重复了,估计引起了它的混乱(我到底应该相信谁!)。只要任意删掉一个就好。最后在参考中给出的文件是修改好的版本,我删去了图片右键Edit框中的代码,保留了代码框中的,就没有报错啦!