RePast如何使用,中文版,非常全面的翻译
ARePastTutorialbyJohnT.Murphy,UniversityofArizona&ArizonaStateUniversity(contact)
(请尊重作者版权)译者:Brian Yang, Anhui Normal University (brianyang1106@ymail.com)
原文链接:http://www.perfectknowledgedb.com/Tutorials/H2R/main.htm
1.如何生成一个 RePast 模型
RePast 仿真工具箱是一个预先制作好的编程元素的集合,这些元素可以让你相对容易地构建
基于主体(Agent-Based)的仿真模型。但是,有些步骤,明显不是直觉上的,却也没有在任何
我所找到的文档里解释清楚;这个简短的向导能让你按照步骤一点一点实现我们的目标。
概要
/*译者注:为了使用 RePast,你的电脑需要配备 JDK(安装后最好配置一下环境,如果装有
Apple 的 QuickTime,那么恭喜你,请卸载 QT 吧,否则配置会出问题;不配置也行~),再下
载 Eclipse 和 RePast J,给出三个下载的页面链接(2011/7/28):
JDK ,Eclipse: 点击直接下载
RePast J: (点击直接下载)
注意这里并没有使用 RePast 官网主页面的 RePast Simphony 的链接,因为我们做的例子是基
于 Java 的,Repast J 足够了,注结束*/
一个基本的 RePast 模型包括以下几个元素(这个太重要了!):
1. 一个 Model 对象,它用来作为模型本身,运行也是从这个文件运行
2. 一个 Space 对象,即空间对象,它控制行为发生的环境
3. 一个 Agent 对象,即行为主体对象
其实理论上有的时候是可以忽略掉详细的 Space 对象的,即不去创建这个 Space.java,但是
我们很少去这么做。因为一旦它被忽略,那么 agents 就可能被默认在一个无限的空间内生
存,或者是默认在一个极小的空间内,以至于无法和别的 agents 进行交互,那么就丧失了
仿真的意义。
在这几个元素当中,建立起来最复杂的是 Model 对象,它会被第一个执行并且控制着整个
仿真过程,因此我们从 Model 对象来一步一步往下说比较合理。
2.The SimModel Object (Repast J 中的一个对象)
Model 对象会继承 RePast 的 SimModelImpl 对象。我想,你绝对不会看许多 SimModelImpl
对象实现的代码,但是事实上这些代码是最重要的,因为它控制了整个 RePast 环境和仿真
的过程。而且,它预期在你创建的 Model 对象中找到一些东西 ——不幸的是这些东西没有
一个真正的 Interface(接口)正式,但是思路是差不多的。
你创建的 Model 对象将会被分块在 Eclipse 上设计,其实就是一个功能一个功能往上加,并
且最终由 RePast J 的工具条上的按钮触发运行。
第一个按钮用来打开一个模型,红叉用来关闭一个模型,红叉左边的小灯泡用来设置参数;
最重要的是第三、四、五个按钮,第三个表示运行,第四个表示单步运行,第五个表示初始
化模型;第六个表示停止,第七个表示暂停,第八个按钮(循环箭头)表示截断并将仿真恢复
到未初始化状态。(这些按钮的名称务必记住,后面讲到时不再附图)
我们先做一个小小的测试模型,下面译者一步一步实现给大家看:/*译者注
1. 打开 Eclipse,文件,新,Java 项目,项目名填上 MyFirstRePastModel,Next
此时界面应该是:
2. 选择第三个标签:库,右边按钮“添加外部 JAR”
3.
(3,4 两步很重要)选择安装 RePast 的文件夹 RePast 3,进入后打开 RePast J,单击选中
repast.jar 文件,点击打开
4. 重复步骤 2,进入 RePast J 文件夹后,直接双击打开 lib 文件夹,Ctrl+A 实现全选,点击
打开,然后完成 (如果以后写代码时出现包未导入的提示,说明这两步你没有导入成
功,这两步其实很 no-brainer 的:就是把 repast.jar 和 lib 文件夹下所有的 jar 文件都导
入就行了)
5. 最后点击完成
不要管我其他的项目
此时,就完成了与 RePast J 的连接,说白了就是在 Eclipse 中写代码,然后让 RePast J 环境运
行,导入外部的这些 jar 文件,目的是写程序时需要导入诸多 Repast 包,此时再回头看看教
程 1 里的第一句话:RePast 仿真工具箱是一个预先制作好的编程元素的集合。
6. 双击打开 MyFirstRePastModel,右键 src,新建,包,包名填上 demo(随意),完成
7. 右键 demo,新建,类 (分别新建三个类,我这里分别取名为 Model,Space,Agent)
8. 对于 Model.java,仅保留第一行代码(如右上图所示),然后开始在 Model 里,请一步
一步添加代码,自己敲一遍的过程可以把我们以后要用到的基本方法都熟悉一遍 */
9. 我们的模型,主类首先继承 SimModelImpl,还必须自己扩充一些方法(methods)。比如,
必须有一个 getName 方法来返回正在仿真模型的名字,这个名字出现在设置参数的面板
的工具栏里。
这里默认你懂得 Java 基本的知识,虽然译者对于 Java 也只能算是初级的水平。下面是
getName 实现的代码,注意,为加深大家印象,我特意截图,你们不得不自己敲。这里
说明一下,教程 2 的代码全部在 package demo; 这一句下方添加。
10. 但是,这里还有更多的需要。当你在 RePast 工具栏上点初始化按钮的时候,RePast 将
会触发一个在你模型当中叫做 begin 的方法,这个方法是为了初始化仿真器。注意,从
这里开始,每新加入的代码都用红色粗体标注。
11. 用技术上的术语来说,SimModelImpl 类是一个抽象类,它实现了一个接口;接口需要实
现某些方法,我们已经看到的 begin()和 getName()就是其中的两个需要实现的方法,马
上还会看到更多;然而,有一个附加的框架,虽然不是 Java 也不是 RePast 包必须要求
的,但是它是更加简单更加传统的方法,用来组织程序。就是将 begin()方法分块:
buildModel,buildSchedule 和 buildDisplay。因此,此时代码变为:
我前面说了,这种结构不是必须的,你可以按照你自己的方法来。但是,unfortunately,当
你发现许多其他 RePast 模型都这么写的时候,你就不淡定了。而且事实上这样写有很多优
点,所以你以后也这么写吧。
12. 没有必须的、明确的方法用来实现运行、暂停和停止函数,尽管他们依赖于模型中核心
的成分。但是有另外的三个函数是必须实现的。
第一个是 setup 函数,当循环箭头被按下时调用该函数,我通常把这个 setup 函数放在
begin 函数前面,个人喜好。
13. 第二个是 getSchedule 函数,它必须返回一个 Schedule 类型的对象。每一个 RePast 模型
将至少有一个 schedule 对象。一般的,通过加一个 schedule 对象作为类变量来生成。注
意:Schedule 是一个对象,schedule 是一个变量,这是 Java 传统规范规定的。因此:
注意到,为了添加一个 schedule 对象,必须导入该类的包,一个 schedule 变量在变量域声
明,其方法在下方添加。
/*到这里,译者简单说下,schedule 主要是运行方法,尤其指时间上的安排*/
这里有一点奇怪,schedule 对象是 model 的内部的,却被声明为 private,这样的话,就不能
直接被外部程序或者是对象获取。然后,getSchedule 方法作为公共方法被给出,从而间接
的将 schedule 对象传递给外部程序或者是其他对象。显然,直接把 schedule 给它们似乎更
高效,所以把 schedule 声明为 public 类型的岂不是更好?当然不行,这简直糟透了。马上
RePast 引擎就要启动了,它必须要获得模型的 schedule,这就必须通过调用 getSchedule 方
法,而这个方法有时 SimModelImpl 接口所必须实现的。所以,编译器强迫你得这么写。好
吧,如果你真的把 schedule 设成 public 类型的了,那么 RePast 引擎就会直接找 schedule,
这就无法确保编译器是不是温柔了,改了值也不一定。更加重要的是,通过遵守内部变量一
律设置成 private 而且有对应的方法可以间接存取,程序员就轻松了,想怎么实现内部
schedule 就怎么实现,they are free~ 在这个例子中,我命名我的 schedule 对象为‘schedule’,
但是这不是必须的,可能有更加间接的名字,比如 sch 等等。更更更加重要的是,我可以生
成一个 Schedule 类的子类并且添加更多的功能函数,或者干点其他的事来满足我的需要;
只要 getSchedule 方法返回一个合适类型的对象就行了,根本不用管它是不是还做了其他额
外的工作,RePast 引擎都会很开心,因为 getSchedule 的工作圆满完成了。最后,我们注意
到 public/private 在这里的重要性并没有它应该有的那么大;我们可以让我们的 schedule 对
象是 public 的,并且不用太在意它,因为相对于使用我们构建的 API 的其他程序员来说,我
们更加懂得这个模型是怎么使用的,因为模型就是我们做的。
14. 最后一个必须的函数比较复杂,它叫做 getInitParam,它返回一个字符串变量数组,该
数组列出了一组特殊变量的名字。你将在 RePast 控制面板设置这些变量。
假设你想要一个实现了 N 个实体的仿真器,但是你又想能够通过点击 setup 和 initialize
按钮来运行不同的 N 个实体来进行仿真实验,巧了,RePast 允许这样,但是:
你必须提供给 RePast 一个参数列表,这个例子里叫做 numAgents
你必须为每一个列表中的参数创建 get 和 set 方法,注意,是每一个
下面是控制面板和这一步的代码:
15. 典型的编程实例和特殊的 RePast 结构需要我们提供 get 和 set 方法;最后,你得告诉RePast
你想能够通过控制面板来设置这些变量,你需要实现 getInitParam 方法,完整代码:
其实你们不知道,大写是件很难搞的问题,因为变量是 NumAgents 但是 get 和 set 方法变成
了 getNumAgents(注意这里 N 是大写)和 setNumAgents。事实上,RePast 到时候会自动寻找
名 为 ”get” + ”NumAgents” 和 ”set” + “NumAgents” 的 方 法 , 因 此 找 到 了 ”getNumAgents”
和”setNumAgents”方法,具体的你们不必深究。
注意:getInitParams 返回的是一个字符串数组;但是到目前为止我们只有一个字符串会被返
回,那就是”NumAgents”;我们学到后面会发现要返回的有很多,绝对不止一个,那么可以
这么写:
即使只有一个返回的参数名,返回类型也必须是数组类型。其中的[]告诉我们,返回的其实
是一个指向字符串数组的指针。
/*译者注:到这里为止,原作的教程 2 部分就完全结束了。我想大家跟我第一次看这个
的时候心情是一样的,估计早就已经迫不及待的点了运行,然后发现竟然要配置运行环境,
然后又不管三七二十一直接点了运行,发现 Eclipse 在苦苦的找 main 函数,最后弹出个令你
灰心丧气的窗口,不得不放弃了。这时候你心想,这不坑爹呢嘛!!!我敲了那么久的代码,
压根不能运行啊。这时候请你回想当初说 RePast 需要的三个因素,我们到底实现了几个?