RePast如何使用,中文版,非常全面的翻译ARePastTutorialbyJohnT.Murphy,UniversityofArizona&ArizonaStateUniversity(contact)(请尊重作者版权)译者:BrianYang,AnhuiNormalUniversity(brianyang1106@ymail.com)原文链接:如何生成一个RePast模型RePast仿真工具箱是一个预先制作好的编程元素的集合,这些元素可以让你相对容易地构建基于主体(Agent-Based)的仿真模型。但是,有些步骤,明显不是直觉上的,却也没有在任何我所找到的文档里解释清楚;这个简短的向导能让你按照步骤一点一点实现我们的目标。概要/*译者注:为了使用RePast,你的电脑需要配备JDK(安装后最好配置一下环境,如果装有Apple的QuickTime,那么恭喜你,请卸载QT吧,否则配置会出问题;不配置也行~),再下载Eclipse和RePastJ,给出三个下载的页面链接(2011/7/28):JDK,Eclipse:点击直接下载RePastJ:(点击直接下载)注意这里并没有使用RePast官网主页面的RePastSimphony的链接,因为我们做的例子是基于Java的,RepastJ足够了,注结束*/一个基本的RePast模型包括以下几个元素(这个太重要了!):1.一个Model对象,它用来作为模型本身,运行也是从这个文件运行2.一个Space对象,即空间对象,它控制行为发生的环境3.一个Agent对象,即行为主体对象其实理论上有的时候是可以忽略掉详细的Space对象的,即不去创建这个Space.java,但是我们很少去这么做。因为一旦它被忽略,那么agents就可能被默认在一个无限的空间内生存,或者是默认在一个极小的空间内,以至于无法和别的agents进行交互,那么就丧失了仿真的意义。在这几个元素当中,建立起来最复杂的是Model对象,它会被第一个执行并且控制着整个仿真过程,因此我们从Model对象来一步一步往下说比较合理。2.TheSimModelObject(RepastJ中的一个对象)Model对象会继承RePast的SimModelImpl对象。我想,你绝对不会看许多SimModelImpl对象实现的代码,但是事实上这些代码是最重要的,因为它控制了整个RePast环境和仿真的过程。而且,它预期在你创建的Model对象中找到一些东西——不幸的是这些东西没有一个真正的Interface(接口)正式,但是思路是差不多的。你创建的Model对象将会被分块在Eclipse上设计,其实就是一个功能一个功能往上加,并且最终由RePastJ的工具条上的按钮触发运行。第一个按钮用来打开一个模型,红叉用来关闭一个模型,红叉左边的小灯泡用来设置参数;最重要的是第三、四、五个按钮,第三个表示运行,第四个表示单步运行,第五个表示初始化模型;第六个表示停止,第七个表示暂停,第八个按钮(循环箭头)表示截断并将仿真恢复到未初始化状态。(这些按钮的名称务必记住,后面讲到时不再附图)我们先做一个小小的测试模型,下面译者一步一步实现给大家看:/*译者注1.打开Eclipse,文件,新,Java项目,项目名填上MyFirstRePastModel,Next此时界面应该是:2.选择第三个标签:库,右边按钮“添加外部JAR”3.(3,4两步很重要)选择安装RePast的文件夹RePast3,进入后打开RePastJ,单击选中repast.jar文件,点击打开4.重复步骤2,进入RePastJ文件夹后,直接双击打开lib文件夹,Ctrl+A实现全选,点击打开,然后完成(如果以后写代码时出现包未导入的提示,说明这两步你没有导入成功,这两步其实很no-brainer的:就是把repast.jar和lib文件夹下所有的jar文件都导入就行了)5.最后点击完成不要管我其他的项目此时,就完成了与RePastJ的连接,说白了就是在Eclipse中写代码,然后让RePastJ环境运行,导入外部的这些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的代码全部在packagedemo;这一句下方添加。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就怎么实现,theyarefree~在这个例子中,我命名我的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需要的三个因素,我们到底实现了几个?即使是Model我们也没有实现啊同志们!这个教程2只是为了让我们了解我们今后为Model编程时一些必须的参数或者是方法,这些只是基础中的基础。或者可以说,这些是任何Model的框架,我们今后写项目,就是往这里面填内容,RePast很难的,等你继续往后再学个十几个教程你就知道了。等到学完了教程,实现了那个例子,你又跃跃欲试想写个新的,你又会发现自己什么都不会!就是这样的,哪有随随便便就学会一个新工具的,何况主要的部分是在扩充别人的东西,如果你对那些预先做好的元素不熟,做一个新项目简直就是自杀行为。到这里,我现在把主要的内容总结一下,求求你们了,一定要耐着性子再看几分钟:继承SimpleModel类a)