Task6 谣言止于智者——Netlogo Simulation

使用Netlogo进行谣言传播模拟

Posted by Jiawen Wu on December 26, 2018

前言

这个…统计软件课程作业的发布贴——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

无智者的情况

  1. 当群体中不会出现智者且流言是大范围广播传播时 从模拟的结果可以看到,很快这个世界就被谣言给占领了。

  2. 当群体中不会出现智者但流言是小范围传播(影响人数为20)时 从模拟的结果可以看到,虽然保持在一个平衡状态下,但是谣言还是占据了绝对的上风。

有智者的情况

  1. 当群体中会出现智者且流言是小范围传播(影响人数为20)时 从结果来看,智者们的出现很好的控制了谣言的传并最终将谣言消灭。

  2. 当群体中会出现智者但流言是大范围广播传播时 即使对破坏性较高的广泛性传播,智者们也能从源头上解决问题。 从这个结果来看,确实可以说谣言止于智者!

补充说明录屏中出现的bug

录屏最后画Totals图时出现了画笔报错的情况。原因是在图的Edit框中和代码行框中同时写入了代码,使得画笔重复了,估计引起了它的混乱(我到底应该相信谁!)。只要任意删掉一个就好。最后在参考中给出的文件是修改好的版本,我删去了图片右键Edit框中的代码,保留了代码框中的,就没有报错啦!


参考文件下载: