Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

4.2第四章 swarm代码剖析 可选补充课程

1,080 views

Published on

Published in: Education
  • Be the first to comment

  • Be the first to like this

4.2第四章 swarm代码剖析 可选补充课程

  1. 1.   SWARM 程序实现 代码简介 SWARM
  2. 2. SWARM 程序介绍 <ul><li>HeatBug 程序代码介绍 </li></ul><ul><li>SARS 疫情模拟的程序介绍 </li></ul>
  3. 3. 回顾: Swarm  的结构 <ul><li>一个 Swarm 模型包括 </li></ul><ul><ul><li>模型 Swarm </li></ul></ul><ul><ul><li>( ModelSwarm ) </li></ul></ul><ul><ul><li>观察者 Swarm </li></ul></ul><ul><ul><li>( ObserverSwarm ) </li></ul></ul><ul><li>分层的“ Swarm” 可以将模型的数据收集和实现进行分离 . </li></ul>Swarm model swarm observerswarm
  4. 4. ModelSwarm <ul><li>ModelSwarm 是 swarm 的子类。 </li></ul><ul><li>ModelSwarm 中的 每 一个对 象 对应 模 型 世界 中的一个主 体。 </li></ul><ul><li>ModelSwarm 包括 模 型中行为的时间 表。 </li></ul><ul><li>ModelSwarm 还包括一系 列输 入和 输 出。 输 入的是 模 型 参数, 如对 象 的个 数、 初 始 值 等; 输 出的是要 观 测 的 变量 的 值 及 模 型的运行 结 果 。 </li></ul>
  5. 5. ObserverSwarm <ul><li>ObserverSwarm 同样是 swarm 的一个子类。 </li></ul><ul><li>ObserverSwarm 是一个特殊的对象,它可以通过探测器接口观察其它个体。 </li></ul><ul><li>ObserverSwarm 包括一 组 个 体 和一个行为时间 表。 </li></ul><ul><ul><li>ObserverSwarm 的个 体 是用来 观 测 的 探测 器以及 输 出 界 面,如图 表、 二 维 格 点等。 </li></ul></ul><ul><ul><li>ObserverSwarm 的 行为时间 表用来 描述 各探测 器 采 样 的间 隔 和 顺 序。 </li></ul></ul>
  6. 6. 两类 SWARM 的合并 <ul><li>先建 ObserverSwarm </li></ul><ul><li>在 ObserverSwarm 中建立 ModelSwarm 作为自身一个 subswarm ,并为它分配内存空间; </li></ul><ul><li>ModelSwarm 建立模型的主体 (agent) 以及主体的行为。 </li></ul>[modelSwarm create: self]; [modelSwarm buildObjects]; [modelSwarm buildActions]; [modelSwarm activateIn: self]; - create: aZone; -buildObjects; -buildActions; -activateIn: swarmContext; Observer Model Model
  7. 7. Integration of Swarm activities Operating System Swarm kernel GUI Model CPU Sub-Swarm ModelSwarm ObserverSwarm Swarm kernel
  8. 8. Heatbug 模型 <ul><li>这是 swarm 的经典示例之一,也是 swarm 的入门 example (与 HelloWorld 有异曲同工之妙)。 </li></ul><ul><li>我们利用这个模型来观察简单主体如何通过局部信息上的动作产生复杂的全局行为结果。 </li></ul>
  9. 9. <ul><li>模型背景 </li></ul><ul><ul><li>在这模型中,每一个 heatbug 都是一个主体( agent )。 </li></ul></ul><ul><ul><li>World 有一个特殊的属性—— heat ,热量经过一定的时间散发和消失。 </li></ul></ul><ul><ul><li>每一个 heatbug 都放射出一定的热量,并且都有自己的一个适于自身生存的理想温度。 </li></ul></ul>
  10. 10. <ul><ul><li>Heatbug 在释放热量的同时,也在向着更接近于适于自己生存的理想温度的附近的点不断移动。 </li></ul></ul><ul><ul><li>单独一个 heatbug 并不能获得足够的热量继续生存,因此它们倾向于聚成一堆的生存,以便获得足够的热量。 </li></ul></ul><ul><ul><li>模型的开始,随机分布着一定数量的 heatbug 。 </li></ul></ul>
  11. 11. 模型运行界面
  12. 12. 输出结果显示——光栅图
  13. 13. 输出结果显示——折线图
  14. 14. 代码剖析 <ul><li>程序清单 </li></ul><ul><ul><li>StartHeatbugs.java (含 main 函数) </li></ul></ul><ul><ul><li>HeatbugObserverSwarm.java (观察者 swarm ) </li></ul></ul><ul><ul><li>HeatbugModelSwarm.java (模型 swarm ) </li></ul></ul><ul><ul><li>Heatbug.java ( heatbug 个体) </li></ul></ul><ul><ul><li>HeatSpace.java ( heatspace 环境) </li></ul></ul><ul><ul><li>HeatCell.java (环境中的小单元) </li></ul></ul><ul><ul><li>HeatbugBatchSwarm.java (功能与 HeatbugObserverSwarm.java 相同) </li></ul></ul>
  15. 15. 面向对象的程序设计 (OOP) 基础 <ul><li>面向对象的程序设计与多主体建模的基本思想非常吻合。 ( 静态结构与动态结构 ) </li></ul><ul><li>掌握一门面向对象的程序设计语言,是学习多主体建模工具的必要条件 </li></ul><ul><li>程序设计中的重要概念回顾 </li></ul><ul><ul><li>对象 Objects </li></ul></ul><ul><ul><li>基本语法 </li></ul></ul><ul><ul><li>构造函数: Constructors </li></ul></ul><ul><ul><li>继承性 : Inheritance </li></ul></ul><ul><ul><li>静态变量: Static </li></ul></ul><ul><ul><li>接口: Interfaces </li></ul></ul><ul><ul><li>包和引用 : Packages & Import </li></ul></ul><ul><ul><li>主程序函数: The 'main' method </li></ul></ul><ul><ul><li>内部类 Inner classes </li></ul></ul><ul><ul><li>类路径: Class Path </li></ul></ul><ul><ul><li>JAR 文档 </li></ul></ul>
  16. 16. 结构关系总揽 <ul><li>StartHeatbugs 是起始程序,它调用 HeatbugObserverSwarm (或 HeatbugBatchSwarm ),由它再调用 HeatbugModelSwarm 及 Heatbug 实现, HeatbugModelSwarm 调用 Heatbug 与 HeatSpace , Heatbug 调用 HeatSpace 与 HeatCell , HeatSpace 调用 HeatCell 。 </li></ul><ul><li>关系框架图: </li></ul>
  17. 17. StartHeatbugs HeatbugObserverSwarm HeatbugBatchSwarm HeatbugModelSwarm Heatbug Heatbug HeatSpace HeatSpace HeatCell HeatCell
  18. 18. StartHeatbugs.java <ul><ul><ul><li>…… // (仅以图形方式为例) </li></ul></ul></ul><ul><ul><ul><li>public class StartHeatbugs { </li></ul></ul></ul><ul><ul><ul><li>//main() 函数是整个程序开始运行的顶层( top-level ),典型的 Swarm 模拟中,在 main() 函数里创建一个顶层 Swarm 对它建立并激活,然后让它运行 </li></ul></ul></ul><ul><ul><ul><li>public static void main (String[] args) { </li></ul></ul></ul><ul><ul><ul><li>// 初始化 swarm ,每个 swarm 程序都必须要先初始化 </li></ul></ul></ul><ul><ul><ul><li>Globals.env.initSwarm (……); </li></ul></ul></ul><ul><ul><ul><li>HeatbugObserverSwarm topLevelSwarm = </li></ul></ul></ul><ul><ul><ul><li>new HeatbugObserverSwarm (Globals.env.globalZone); </li></ul></ul></ul><ul><ul><ul><li>…… </li></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul>
  19. 19. <ul><ul><ul><li>topLevelSwarm.buildObjects (); // 创建对象 </li></ul></ul></ul><ul><ul><ul><li>topLevelSwarm.buildActions (); // 创建行为 </li></ul></ul></ul><ul><ul><ul><li>topLevelSwarm.activateIn (null); // 使之活动 </li></ul></ul></ul><ul><ul><ul><li>topLevelSwarm.go (); // 运行 </li></ul></ul></ul><ul><ul><ul><li>topLevelSwarm.drop (); // 结束停止 </li></ul></ul></ul>
  20. 20. HeatbugObserverSwarm.java <ul><ul><li>HeatbugObserverSwarm 是当图形接口运行时建立以观察热虫模型的一类对象集的 Swarm ,其中一个重要的对象是 heatbugModelSwarm ,同时也还有图形窗口和数据分析类的对象 </li></ul></ul><ul><ul><li>public HeatbugObserverSwarm (); // 初始化及用户接口 </li></ul></ul><ul><ul><li>public Object _worldRasterDeath_ (); // 光栅图关闭处理 </li></ul></ul><ul><ul><li>public Object _unhappyGraphDeath_ (); // 曲线图关闭处理 </li></ul></ul><ul><ul><li>public Object buildObjects (); // 创建对象 </li></ul></ul><ul><ul><li>public Object _update_ (); // 更新动作 </li></ul></ul><ul><ul><li>public Object buildActions (); // 创建行为 </li></ul></ul><ul><ul><li>public Activity activateIn(); // 使时间进度表活动 </li></ul></ul><ul><ul><li>public Object graphBug (); // 曲线图顺序获取每个 bug 的 unhappiness </li></ul></ul><ul><ul><li>public void drop (); // 结束程序前的处理 </li></ul></ul>
  21. 21. public Object buildObjects (): <ul><li>创建用于模型现实的对象。这段代码相对复杂,因为我们创建了相当多的窗口部件。因此可以很好的作为 我们学习如何实现显示相关代码的示例 </li></ul><ul><li>首先,创建我们实际观察的模型,这个模型是 observer 的 subswarm </li></ul><ul><li>然后创建探测器对象,这给出了一个可以让用户方便的修改参数的用户接口 </li></ul><ul><li>等待一个对控制面板的指令,在此之间用户可以更新参数设置 </li></ul><ul><li>下面可以准备运行 </li></ul>
  22. 22. <ul><ul><li>第一步 让 modelswarm 建立它的对象 </li></ul></ul><ul><ul><li>此后,建立自己的显示对象 </li></ul></ul><ul><ul><ul><li>创建一个全局变量: colormap 这里的信息会被许多其他的对象所利用——色彩的映射表在这里设立 </li></ul></ul></ul><ul><ul><ul><li>为每个热虫设定颜色 </li></ul></ul></ul><ul><ul><ul><li>然后创建一个二维显示窗口,设定他的大小、显示范围、因素和标题 </li></ul></ul></ul><ul><ul><ul><li>创建一个 Value2dDisplay :这个特定对象能够在给定的光栅窗口部件中显示任意的 2 维的值表。 </li></ul></ul></ul><ul><ul><ul><li>创建一个 Object2dDisplay :这个对象为我们在光栅图窗口中画出热虫,并可接受探测 </li></ul></ul></ul><ul><ul><ul><li>使光栅图将获得的鼠标点击传递给 heatbugDisplay ( Object2dDisplay 实例),使用户可以通过右键点击显示对虫子的探测。 </li></ul></ul></ul><ul><ul><ul><li>创建窗口部件显示 unhappiness 折线图 </li></ul></ul></ul><ul><ul><ul><li>在窗口被关闭时,调用执行 _unhappyGraphDeath_ 方法 </li></ul></ul></ul><ul><ul><ul><li>创建热虫平均 unhappiness 的数据 </li></ul></ul></ul><ul><ul><li>// 创建对象过程技术 </li></ul></ul>
  23. 23. <ul><li>public Object buildObjects () { </li></ul><ul><li>super.buildObjects (); // 父类的 buildObjects </li></ul><ul><li>heatbugModelSwarm = new HeatbugModelSwarm (getZone ()); </li></ul><ul><li>…… // 设置存档 probe, 以便修改参数 </li></ul><ul><li>getControlPanel ().setStateStopped (); </li></ul><ul><li>// 获得控制面板,出于 stop 状态并响应 button 事件 </li></ul><ul><li>heatbugModelSwarm.buildObjects (); </li></ul><ul><li>colormap = new ColormapImpl (getZone ()); </li></ul><ul><li>…… // 各种个体、环境、资源的颜色映射 </li></ul><ul><li>worldRaster = new ZoomRasterImpl (getZone (), &quot;worldRaster&quot;); </li></ul><ul><li>…… //2D 窗口图 </li></ul><ul><li> heatDisplay = new Value2dDisplayImpl (……); </li></ul><ul><li>…… //2Dvalue 图, display heat </li></ul><ul><li>heatbugDisplay = new Object2dDisplayImpl(……); </li></ul><ul><li>…… //2Dobject 图, display heatbug </li></ul><ul><li>worldRaster.setButton$Client$Message(……); </li></ul><ul><li>…… // 允许鼠标右键在 probe bug 上获取当前各值 </li></ul><ul><li> unhappyGraph = new EZGraphImpl(……); </li></ul><ul><li>…… //unhappy 的曲线图,设 data 为平均的 unhappiness </li></ul><ul><li>} </li></ul>
  24. 24. public Object buildActions(): <ul><li>创建仿真所必需的动作( actions )。这里是建立事件调度表( schedule )的地方。(但这里并不运行它)。 </li></ul><ul><li>这里我们创建一个显示 schedule—— 它用来显示模拟世界的状态和检测用户的输入。 </li></ul><ul><li>注意到这个 schedule 与模型是相独立的——你可以设想在每有任何显示的情况下运行模型 </li></ul>
  25. 25. <ul><li>首先,让 modelswarm 创建自身的 schedule </li></ul><ul><li>创建一个显示的 ActionGroup: 一组按特定顺序发生的动作,但都是在模拟时序的一步中发生的。其中的一些动作可以被平行的执行。 </li></ul><ul><ul><li>创建 displayActions </li></ul></ul><ul><ul><li>给 ActionGroup 中加入绘制出显示图的方法 </li></ul></ul><ul><ul><li>确定探测器显示更新的时间 </li></ul></ul><ul><ul><li>最后确定对整个用户接口代码更新的时间 . 这一步是很关键的:没有这一步,所有的图形更新和控制面板都不能被关闭。这一步最好放在显示 schedule 的结尾处。 </li></ul></ul><ul><ul><li>然后是显示 schedule. 注意重复的间隔是根据我们自己的 swarm 数据结构设定的。频繁的显示是仿真中最慢的部分,所以降低显示更新频率,可能会有所帮助 </li></ul></ul><ul><ul><li>将 ActionGroup 的实例插入重复运行的 Schedule 实例中 </li></ul></ul><ul><li>// 创建动作过程结束 </li></ul>
  26. 26. <ul><li>// 定义 display 的时间表 </li></ul><ul><li>public Object buildActions () { </li></ul><ul><li>super.buildActions(); // 父类的 buildActions </li></ul><ul><li>heatbugModelSwarm.buildActions(); </li></ul><ul><li>displayActions = new ActionGroupImpl (getZone()); </li></ul><ul><li>// 创建一个 ActionGroupImpl 对象 </li></ul><ul><li>…… // 添加两个 action ,“ _update_” 和 //“doTkEvents” </li></ul><ul><li>//doTkEvents 这个方法对所有用户接口作 update </li></ul><ul><li>displaySchedule = new ScheduleImpl (……); </li></ul><ul><li>// 以 displayFrequency 为参数创建一个 ScheduleImpl 对象, display 环节是模拟过程中最耗时的,降低显示的频率有助于模拟的运行 </li></ul><ul><li>displaySchedule.at$createAction (0, displayActions); </li></ul><ul><li>// 将 actiongroup 的实例添加到重复的 schedule 实例中 </li></ul><ul><li>…… </li></ul><ul><li>} </li></ul>
  27. 27. public Activity activateIn (Swarm swarmContext) : <ul><li>功能:激活时间表,使它们为运行作好准备 </li></ul><ul><li>The swarmContext argument has to do with what we were activated *in*. Typically the ObserverSwarm is the top-level Swarm, so it's activated in &quot;null&quot;. But other Swarms and Schedules and such will be activated inside of us. </li></ul>
  28. 28. <ul><li>// 使时间表处于活动状态,准备运行 </li></ul><ul><li>public Activity activateIn (Swarm swarmContext) { </li></ul><ul><li>// 首先激活自身 (just pass along the context). </li></ul><ul><li>super.activateIn (swarmContext); // 父类的 activateIn </li></ul><ul><li>// 在自身环境内激活 model swarm 。 Model swarm 是 observer swarm 的 subswarm </li></ul><ul><li>heatbugModelSwarm.activateIn (this); </li></ul><ul><li>// 然后在自身环境内激活自己的 schedule 。这一步安排了我们创建的时间表的执行 </li></ul><ul><li>displaySchedule.activateIn (this); </li></ul><ul><li>// 激活返回了 swarm activity - the thing that's ready to run </li></ul><ul><li>return getActivity(); </li></ul><ul><li>} </li></ul>
  29. 29. HeatbugModelSwarm.java <ul><li>封装了所有用于模拟热虫世界本身的对象(但不包括用户接口对象) </li></ul><ul><li>public List getHeatbugList () // 获得 heatbug 列表 </li></ul><ul><li>public Grid2d getWorld () // 获得 world 2D 对象实例 public HeatSpace getHeat () </li></ul><ul><li>// 获得 2D HeatSpace 对象实例 </li></ul><ul><li>public boolean toggleRandomizedOrder () </li></ul><ul><li>// 判断是否用随机顺序 </li></ul><ul><li>public Object addHeatbug (Heatbug bug) </li></ul><ul><li>// 添加 Heatbug 个体 </li></ul><ul><li>public HeatbugModelSwarm (Zone aZone) </li></ul><ul><li>// 初始化,参数界面 </li></ul><ul><li>public Object buildObjects () </li></ul><ul><li>public Object buildActions () </li></ul><ul><li>public Activity activateIn (Swarm swarmContext) </li></ul>
  30. 30. public Object buildObjects () <ul><li>首先建立代表环境的对象。 Heatspace 主体代表了热量的空间特性。他通过多种模型参数初始化。 </li></ul><ul><li>然后设定代表主体位置的栅格 </li></ul><ul><li>创建模型中主体列表以便在模拟中追踪 </li></ul><ul><li>创建热虫自身,这是相当复杂的一步:热虫是本仿真中的关键部分。 </li></ul><ul><li>利用一个循环创建一组热虫 </li></ul><ul><ul><li>选择随机的理想温度和输出热量(据参数设定范围) </li></ul></ul><ul><ul><li>用表准的构造函数创建新的热虫主体 </li></ul></ul><ul><ul><li>加入列表 </li></ul></ul><ul><ul><li>初始化热虫的其他状态(如移动概率,随机初始位置等) </li></ul></ul><ul><ul><li>// 热虫创建完毕 </li></ul></ul>
  31. 31. <ul><li>public Object buildObjects () </li></ul><ul><li>{ </li></ul><ul><li>…… </li></ul><ul><li>super.buildObjects(); </li></ul><ul><li>heat = new HeatSpace (……); </li></ul><ul><li> // 环境 </li></ul><ul><li>world = new Grid2dImpl (……); </li></ul><ul><li>//world 是一个 2D 图 </li></ul><ul><li>heatbugList = new ListImpl (getZone ()); </li></ul><ul><li>//heatbug 列表 </li></ul><ul><li>…… </li></ul><ul><li>for (i = 0; i < numBugs; i++) { </li></ul><ul><li>…… </li></ul><ul><li>hbug = new Heatbug (world, heat); // 在 world 中创建一个 Heatbug </li></ul><ul><li>heatbugList.addLast (hbug); // 添加到 heatbug 列表的最后 </li></ul><ul><li>…… </li></ul><ul><li>// 设置各参数初始值,放在 world 中的随机位置 </li></ul><ul><li>} </li></ul><ul><li>…… </li></ul><ul><li>} </li></ul>
  32. 32. public Object buildActioins () <ul><li>在这里创建模型时间表,它是定义了模型中仿真时序的数据结构。核心是一个包含了一系列动作的 actionGroup ,然后把它放入 schedule </li></ul><ul><li>创建仿真动作的列表,把它们放入一个行动组,我们希望这些动作按特定顺序执行,但是这些步骤并不消耗(模拟)时间。 </li></ul><ul><li>M(foo) means “The message called <foo>”. 可以向特定对象发送一条消息或者向一个集合中的每个对象发送一条消息。 </li></ul><ul><li>这里我们通过两个阶段更新 heatspace :首先执行 diffusion, 然后执行“ updateWorld” 来让热虫发生的变化真实的发生。这里的顺序很重要。 </li></ul>
  33. 33. <ul><li>同时注意到,利用一个布尔标记 `randomizeHeatbugUpdateOrder‘ 我们可以随机化热虫实际执行它们的步骤规则( step rule )的顺序。这能起到消除在每步对列表中热虫循环访问时带来的系统偏差( This has the effect of removing any systematic bias in the iteration throught the heatbug list from timestep to timestep ) </li></ul><ul><li>缺省的, createActionForEach 模型动作的缺省顺序是” Sequential” ,这意味着循环遍历“ heatbugList” 的顺序都是一样的(假设链的顺序没有被其他过程间接改变) </li></ul><ul><li>在 actionGroup 中 </li></ul><ul><ul><li>heat(HeatSpace 对象 ) 执行“ stepRule” </li></ul></ul><ul><ul><li>对主体列表中每个热虫执行“ step” </li></ul></ul><ul><ul><li>更新 heat 栅格(“ updateLattice” ) </li></ul></ul>
  34. 34. <ul><li>public Object buildActions () { </li></ul><ul><li>super.buildActions(); </li></ul><ul><li>modelActions = new ActionGroupImpl (……); </li></ul><ul><li>// 创建一个 ActionGroup 实例 </li></ul><ul><li>…… // 添加两个 action ,一个为 update world 中每个网格的 heat ,另一个为每个 Heatbug 创建 action——step </li></ul><ul><li>创建执行前面设定动作组的 schedule.ActionGroup 的对象自身没有时间的概念,为了让它能够按时间执行,我们创建一个 Schedule 对象,在特定的时间应用 modelActions ActionGroup 。这个时间表重复的间隔为“ 1” ,即将在每个 time step 循环。动作会在相应于循环开始的时间为“ 0” 的时间点执行。 </li></ul><ul><li>这是一个简单的时间表,只有一个动作每次重复,可以参考 jmousetrap 来看更为复杂的 schedules </li></ul><ul><li>modelSchedule = new ScheduleImpl (……); </li></ul><ul><li>// 创建一个 schedule 实例 </li></ul><ul><li>modelSchedule.at$createAction (0, modelActions); </li></ul><ul><li>// 将 actiongroup 的实例添加到重复的 schedule 实例中 </li></ul><ul><li>…… </li></ul><ul><li>} </li></ul>
  35. 35. public Activity activateIn (Swarm swarmContext ) <ul><li>Now set up the model's activation. swarmContext indicates where we're being started in - typically, this model is run as a subswarm of an observer swarm. </li></ul><ul><li>super.activateIn (swarmContext); </li></ul><ul><li>激活自身时间表 </li></ul><ul><li>modelSchedule.activateIn (this); </li></ul><ul><li>返回我们的 activity </li></ul><ul><li>return getActivity (); </li></ul><ul><li>} </li></ul>
  36. 36. Heatbug.java <ul><li>Heatbugs 是 2 维世界中具有简单行为的主体: </li></ul><ul><ul><li>如果太冷,移动至较为温暖的点 </li></ul></ul><ul><ul><li>如果太热,移动至较为凉爽的点 </li></ul></ul><ul><ul><li>有一些以外情况,比如该点被占用,试着找到一个没被占用的点。 </li></ul></ul><ul><ul><li>randomMoveProbability ,是移动到随机地点的概率 </li></ul></ul><ul><li>一些用来初始化主体状态的方法。 </li></ul><ul><li>构造函数 </li></ul><ul><ul><li>两个参数 world heat </li></ul></ul><ul><ul><li>检查和传递参数 </li></ul></ul><ul><ul><li>取得 world 的大小 </li></ul></ul><ul><li>在运行中读写热虫状态的方法。探测器机制是得到一个主体状态的底层( lowlevel )方法——还允许(并不要求)编写获得的方法当你认为必要或方便时。注意命名惯例,这样的命名对后面探测器的翻译来说很重要。(探测器优先使用方法获取而非直接获取) </li></ul><ul><li>设定热虫状态的简单方法 </li></ul>
  37. 37. <ul><ul><li>public Heatbug (Grid2d w, HeatSpace h) // 初始化及用户接口,响应 probebug 的鼠标右键的事件 </li></ul></ul><ul><ul><li>public double getUnhappiness () </li></ul></ul><ul><ul><li>// 获取当前 unhappiness 参数值 </li></ul></ul><ul><ul><li>public Object setIdealTemperature (long i) // 设置理想的温度 </li></ul></ul><ul><ul><li>public Object setOutputHeat (long o) // 设置 heatbug 自身的热量 </li></ul></ul><ul><ul><li>public Object setRandomMoveProbability (double p) </li></ul></ul><ul><ul><li>// 设置随机移动的机率 </li></ul></ul><ul><ul><li>public Object setX$Y (int inX, int inY) // 设置位置 </li></ul></ul><ul><ul><li>// 上面的代码是基本的 swarm 对象编程,真正的模拟代码在下面实现 </li></ul></ul><ul><ul><li>Heatbug 行为真正在这里实现 </li></ul></ul><ul><ul><li>public Object step () //heatbug 的行为 </li></ul></ul><ul><ul><li>public Object setBugColor(byte c) // 设置 heatbug 的颜色 </li></ul></ul><ul><ul><li>public Object drawSelfOn (Raster r) // 画图 </li></ul></ul>
  38. 38. <ul><li>Step 方法是对模型的一个很好的简化 </li></ul><ul><li>public Object step () { </li></ul><ul><li>…… </li></ul><ul><li>heatHere = heat.getValueAtX$Y (x, y); </li></ul><ul><li>// 获得当前位置的 heat </li></ul><ul><li>…… // 计算我当前的 unhappiness 值 abs(ideal - here) </li></ul><ul><li>// </li></ul><ul><li>heat.findExtremeType$X$Y (((heatHere < idealTemperature) </li></ul><ul><li>? HeatSpace.hot </li></ul><ul><li>: HeatSpace.cold), </li></ul><ul><li>heatCell);// 调用函数寻找邻居中 hottest 或 coldest 点 </li></ul><ul><li>…… // 理想的点已经找到,下一步是随机移动,找到新位置 </li></ul><ul><li>// 如果当前不满意值 0 ,则不动,改变当前位置热量 </li></ul><ul><li>// 否则移动至新位置,若所要移至的网格已被占用,则继续寻找可能位置,若也被占用,再搜寻,如 10 次还被找到适合的移动位置,则保持原来的位置 </li></ul><ul><li>} </li></ul>
  39. 39. HeatSpace.java <ul><li>代码支持扩散主体—— heat space 的定制( specialization )。大部分实际的工作在 Diffuse 内完成,它是一个 CA 的实现( implements )。这些函数使得对空间变量的访问得以简化和标准化,使 Heatbug 的代码在一个更高的层次上( higher level ) </li></ul><ul><li>HeatSpace 是一个简单的对象,代表 world( 一个空间变量 ) 中的热量。它从空间对象“ Diffuse2dImpl” 继承了大部分行为。 </li></ul><ul><ul><li>public class HeatSpace extends Diffuse2dImpl </li></ul></ul>
  40. 40. <ul><ul><li>public HeatSpace (Zone aZone, int worldXSize, int worldYSize, </li></ul></ul><ul><ul><li>double diffuseConstant, double evaporationRate) </li></ul></ul><ul><ul><li>public Object addHeat$X$Y (long moreHeat, int x, int y) </li></ul></ul><ul><ul><li>// 取出当前位置热量 </li></ul></ul><ul><ul><li>// 比较加入 moreHeat 后是否会超出最大热量界限 </li></ul></ul><ul><ul><li>// 更新当前点 heat </li></ul></ul><ul><ul><li>public long findExtremeType$X$Y (int type, HeatCell hc) </li></ul></ul><ul><ul><li>// 在 9 个相邻的 cell 中寻找合适的位置, x,y 既是输入也是输出,为了避免搜寻顺序带来的偏差,所以建立最有位置链从中随机选择 </li></ul></ul>
  41. 41. <ul><li>HeatCell.java </li></ul><ul><ul><li>public HeatCell (int theX, int theY) </li></ul></ul><ul><ul><li>public Object setX (int theX) </li></ul></ul><ul><ul><li>public Object setY (int theY) </li></ul></ul><ul><ul><li>public int getX () </li></ul></ul><ul><ul><li>public int getY () </li></ul></ul>
  42. 42. 具体程序
  43. 43. <ul><li>模拟结果 </li></ul>
  44. 46. 结果分析 <ul><li>我们可以把 heatbugs 模型看作一个最优化问题:每一个 heatbug 都试图寻找自己最理想的生存环境。 </li></ul><ul><li>每个热虫完全根据自身的需要在移动,但是所有热虫平均的不满意程度呈下降趋势,也即整个系统在不断优化。 </li></ul>
  45. 47. 关于 SARS 模型介绍 <ul><li>模型思路 </li></ul><ul><li>模型结构 </li></ul><ul><li>运行结果 </li></ul>
  46. 48. 模型运行机制 <ul><li>发病者 </li></ul><ul><li>就医 </li></ul><ul><li>在院治疗 </li></ul><ul><li>治愈出院 </li></ul><ul><li>死亡 </li></ul><ul><li>被接触者 </li></ul><ul><li>被感染者 </li></ul><ul><li>被隔离者 </li></ul><ul><li>N </li></ul><ul><li>Y </li></ul><ul><li>满足隔离条件 </li></ul><ul><li>满足隔离条件 </li></ul><ul><li>生成 </li></ul><ul><li>未被感染的接触者 </li></ul>
  47. 49. <ul><li>运行天数递加 </li></ul><ul><li>是否应改变入院延迟 </li></ul><ul><li>是否满足隔离条件 </li></ul><ul><li>计算前一天的新增病例数 </li></ul><ul><li>执行隔离操作 </li></ul><ul><li>设置新的入院延迟 </li></ul><ul><li>N </li></ul><ul><li>N </li></ul><ul><li>Y </li></ul><ul><li>Y </li></ul><ul><li>Y </li></ul><ul><li>N </li></ul><ul><li>根据前一天的新增病例数,调整活跃度 </li></ul><ul><li>系统中还有主体未处理 </li></ul><ul><li>从主体链中取一个主体 </li></ul><ul><li>执行主体动作 </li></ul><ul><li>结束 </li></ul><ul><li>图 2 模型动作的程序流程图 </li></ul>
  48. 50. <ul><li>是否痊愈 </li></ul><ul><li>产生新接触者包括一定比例的感染者 </li></ul><ul><li>是否满足就医条件 </li></ul><ul><li>判断主体是否已发病 </li></ul><ul><li>标记为已就医状态每日接触人数记为 0 </li></ul><ul><li>是否感染者 </li></ul><ul><li>感染天数达到潜伏期 </li></ul><ul><li>结束 </li></ul><ul><li>治疗天数递加 </li></ul><ul><li>标记为新发病例 </li></ul><ul><li>感染天数递加 </li></ul><ul><li>发病天数递加 </li></ul><ul><li>痊愈出院 </li></ul><ul><li>N </li></ul><ul><li>N </li></ul><ul><li>N </li></ul><ul><li>Y </li></ul><ul><li>Y </li></ul><ul><li>Y </li></ul><ul><li>图 3 主体动作程序流程图 </li></ul>
  49. 51. <ul><li>模型中关键的三个部分分别是主体类的建立, ModelSwarm 类的建立,和 ObserverSwarm 类的建立。 </li></ul><ul><li>此模型中考虑的主体是人, “接触者”(状态也会变化)。 </li></ul>
  50. 52. 主体类 <ul><li>其中包括主要的属性和方法(这为后面介绍的运行机制提供了基础)包括: </li></ul><ul><ul><li>int infect_state 描述该主体状态,包括的情况有 4 种:接触未被感染;接触被感染还未发病;确诊发病;经过治疗已经康复; </li></ul></ul><ul><ul><li>int touche_num 反映该主体具体每日平均能接触到的人数,为总体平均日接触人数与下面的活跃变量结合求出 </li></ul></ul><ul><ul><li>double activity_degree 反映该主体的活跃程度 </li></ul></ul><ul><ul><li>int seperate_flag 隔离或就医标志,可能情况有:未被隔离,被隔离,已就医 </li></ul></ul>
  51. 53. <ul><li>主体类中主要的方法(函数)就是判断主体的状态,实现根据主体不同的状态在每个时间步(这里是 1 天)做出的相应的行动。 **Step </li></ul>
  52. 54. ModelSwarm 类 <ul><li>主要设置了模型中系统级的参数 ( 构造函数中 ) ,这些参数可以显示给用户,并可以被修改来实现对不同条件下模型运行结果进行比较研究。 </li></ul><ul><li>生成了预定个数主体构成主体链( Build Object ) </li></ul><ul><li>还设置了每个时间步模型的动作序列。 (Build Action) </li></ul>
  53. 55. <ul><li>系统及的参数包括: </li></ul><ul><ul><li>int initInfected 系统中最初的发病人数 </li></ul></ul><ul><ul><li>double infect_probability 被接触后可能发病的概率 </li></ul></ul><ul><ul><li>int touchPerson_num 整体上平均的日接触人数 </li></ul></ul><ul><ul><li>int infectDelay_exp 被感染到发病的平均时间延迟(潜伏期期望) </li></ul></ul><ul><ul><li>int hospitalChange 述了改变就医习惯的时机,即系统运行天数满足这个值后人从发病到就医的时间间隔将减小 </li></ul></ul><ul><ul><li>int hospitalDelay 主体从发病(具有传染能力)到就医的时间间隔 </li></ul></ul><ul><ul><li>double seperatePower 隔离力度,大于等于 0 小于等于 100 的实型数,表示了被隔离人数的比重,如此值为 70 时 70% 的人被隔离 </li></ul></ul><ul><ul><li>int seperateDelay 系统采取隔离措施的时间,描述运行多少天后采取隔离 </li></ul></ul><ul><ul><li>double becured_probabilit 接受治疗后的平均治愈率 </li></ul></ul><ul><ul><li>int recover_delay; 从入院接受治疗到痊愈的平均时间延迟 </li></ul></ul>
  54. 56. ObserverSwarm 类 <ul><li>实现了对运行结果数据的采集以及显示的工作。 </li></ul><ul><li>在这个模型中主要显示了四组数据随时间变化的折线图:累计发病人数,每日新增发病人数,累计治愈人数,每日新增治愈人数。 </li></ul>
  55. 57. 运行结果分析 <ul><li>1. 及时就医的重要性 </li></ul><ul><ul><li>系统中最初具有感染性(患者)的人数为 1 ; </li></ul></ul><ul><ul><li>最初每人平均每日接触 10 人; </li></ul></ul><ul><ul><li>发病潜伏期为 4 天; </li></ul></ul><ul><ul><li>最初前 25 天从发病到就医间隔为 3 天, 25 天 后改为 2 天; </li></ul></ul><ul><ul><li>接触后被传染的概率为 0.1 </li></ul></ul>
  56. 58. 累计(左)与每日新增(右)发病人数随时间变化曲线( 25 天变化)
  57. 59. 累计(左)与每日新增(右)发病人数随时间变化曲线( 35 天变化)
  58. 60. 最初患者个数对病情发展的影响 <ul><li>只考虑输入型病例。我们对比初始病例有 5 例, 25 天后改变就医速度的情况,这时系统在 150 天左右稳定在大约 3800 人 </li></ul>
  59. 61. 隔离的效果 <ul><li>对比不采取缩减就医间隔的措施这种情况下,隔离措施的效果。假设我们在运行的 40 天后采取措施,使 60% 有过接触的人接受隔离,而就医间隔始终为 3 天。 </li></ul>
  60. 63. <ul><li>从累计发病人数随时间变化图中可以看出在运行 110 天左右,累计发病人数稳定在 2500 人左右。每日新增病例图中可以看出在第 40 天采取隔离措施后,下降的趋势比较明显,而不像前面那种减少就医间隔的措施采取后,还要经过一段时间的滞后才能取得效果。 </li></ul><ul><li>模拟一种与上面的情况完全相同只是在第 20 天就对 60% 的接触者采取隔离,这时系统运行 80 天左右,累计发病人数在 420 人左右就达到了稳定。 </li></ul>
  61. 64. <ul><li>目前模型还存在许多过于简化不很周全的地方 </li></ul><ul><li>模型机制需要真实数据的验证 </li></ul><ul><li>基于有效模型可方便的做更多的比较研究,加深我们对现实世界的认识 </li></ul>

×