《JADE中文教程包还一个真实系统5889》由会员分享,可在线阅读,更多相关《JADE中文教程包还一个真实系统5889(115页珍藏版)》请在金锄头文库上搜索。
1、目录 第一章 绪论 . 3 1.1 问题概述 . 3 1.2 该领域技术发展现状 . 3 1.3 全文安排 . 5 第二章 AGENT 简介 . 6 2.1Agent 技术的起源与发展 . 6 2.2Agent 定义 . 7 2.3Agent 的适用领域 . 10 2.4agent 技术的标准化 . 10 第三章 JADE 平台介绍 . 12 3.1JADE 平台简介 . 12 3.2JADE 的特点. 14 3.3 用 JADE 创建多 Agent 系统 . 15 3.3.1Agent 平台 . 15 3.3.2Agent 类 . 17 3.3.3Agent 任务.执行 Agent 行为 .
2、 19 3.4 交互协议 . 21 3.5 对移动 Agent 的支持 . 22 第四章 基于 JADE 平台上的图书交易系统 . 23 4.1图书交易系统要实现的功能 . 23 4.1.1 买方 Agent . 23 4.1.2 卖方 Agent . 23 4.2 建立 JADE Agent-Agent 类 . 24 4.2.1agent 标识符 . 24 4.2.2 结束 Agent . 25 4.2.3 向 Agent 中传递参数 . 25 4.3Agent 执行的任务-Behaviour 类 . 27 4.3.1 行为调度和执行 . 28 4.3.2 在特定的时间点执行某个操作 . 3
3、1 4.4图书交易系统执行的行为 . 32 4.4.1 买方 Agent 的行为 . 33 4.4.2 卖方 Agent 的行为 . 34 4.5Agent 间通讯-ACLMessage 类 . 37 4.5.1 发送消息 . 37 4.5.2图书交易系统中的各类消息 . 37 中文翻译 . 95 1 介 绍 . 95 2 JADE 特点. 99 3 用 JADE 创建多 agent 系统 . 100 3.1 Agent 平台 . 100 3.2 Agent 类 . 105 第一章 绪论 1.1 问题概述 多 Agent 系统是由多个可以相互交互的,称为 Agent 的计算单元所组成的系统.A
4、gent 作为计算机系统具有两种重要的能力.首先,每个 Agent 至少在某种程度上可以自治行动,由它们自己决定需要采取什么行动以实现其设计目标.其次,每个Agent可以与其他Agent进行交互,这种交互不是简单地交换数据,而是参与某种社会行为,就像我们在每天的生活中发生的那样:合作,协作和协商等. 多 Agent 系统是计算机科学中比较新的一个分支,从 20 世纪 80年代才开始研究,而直到20世纪90年代中才得到广泛的认同.从此以后国际上对这个领域的兴趣大为增加.这种研究热情的快速增加至少部分的是由于认识到 Agent 是一种合适的软件范例,这种范例为研究大规模分布式开放系统(如 Inte
5、rnet)提供了可能性.尽管多 Agent 系统在探索Internet的潜力方面能起到关键的作用,但是多Agent系统的作用远不止如此.对于理解和构造各种所谓的人工社会系统来说,多 Agent 系统似乎是一个自然的比喻.多 Agent 的思想并不局限在某个特定的领域,像在此前出现的对象一样,多 Agent 系统会在许多不同的应用领域中广泛出现. 1.2 该领域技术发展现状 近年来,随着计算机技术的不断发展和应用的广泛普及,随着国际互联网络的出现和发展,计算机软件系统结构和计算机组织结构的复杂性不断增加,从而为软件系统的开发提出了更多,更复杂的要求,如可伸缩性,多功能性,可重用性,鲁棒性,一致性
6、.传统的整体设计和集中控制的软件开发方法越来越显示出其固有的局限性.同时软件系统的设计越来越向个性化,智能化方向发展,一些大型软件系统纷纷采用了人工智能的技术.因此可以说智能化,分布式是未来软件设计的方向. 作为人工智能和分布式计算的结合,分布式人工智能正逐渐收到人们的重视.分布式人工智能研究的目标是要创建描述自然和社会系统精确的概念模型.在分布式人工智能中,由于智能本质上不是一个独立存在的概念,而智能在团体中实现,因此分布式人工智能研究感兴趣的主要是几个 Agent 之间的合作,交互等方面.分布式问题求解考虑怎样将一个特殊问题求解工作在多个合作的,知识共享的模块或节点之间划分;在多Agent
7、系统中,主要研究一组自治的智能Agent之间智能行为的协调.知识,规划,不同技能和自身动作的协调是一个过程,在多 Agent 系统非常重要. 目前对 Agent 和多 Agent 系统的研究主要集中在以下几个方面:Agent 和多 Agent 的理论,Agent 的体系结构和组织,Agent 语言,Agent 之间的协作和协调,通信和交互技术,多 Agent 学习以及多Agent 系统应用等.关于多 Agent 系统的应用已经有人做了许多工作,甚至应用于一些大型,复杂的系统,例如机场管理,自动驾驶,高级机器人系统,分布式电力管理,信息检索等. 现在,关于 Agent 的研究不仅得到了人工智能研
8、究人员的关注,也吸引了数据通讯,人机界面设计,机器人,并行工程等各个领域的研究人员的兴趣.有人认为:基于 Agent 的计算(Agent-based Computing,简称 ABC)将成为软件开发的下一个重要的突破. 1.3 全文安排 本文首先简单的介绍了 Agent 特点,接着引出一个用于开发多Agent 系统的平台-JADE.并结合一个图书交易系统,分析如何利用JADE 平台创建多 Agent 系统,以及 Agent 是如何在平台上执行任务,进行通讯的.内容概要如下: 第二章 Agent 简介 第三章 JADE 平台介绍 第四章 基于 JADE 平台的图书交易系统 第五章 全文总结 最后
9、是附录,参考书目以及致谢. 第二章 Agent 简介 2.1Agent 技术的起源与发展 进入 20 世纪 90 年代以来,在各种计算机文献和众多公司的技术发展规划中,Agent 正日渐成为使用频率最高的词汇之一.下面就对Agent 技术的发展做一个简要的阐述. 智能 Agent 技术的诞生和发展是人工智能 技术(AI)和网络技术发展的必然结果.从 20 世纪 60 年代起,传统的 AI 技术开始致力于对知识表达,推理,机器学习等技术的研究,其主要成果是专家系统.专家系统把专业领域知识与推理有机的组合在一起,为应用程序的智能化提供了一个低级而实用的解决办法.作为人工智能的一个分支,AI计划理论
10、的研究成果使应用程序有了初步的面向目标和特征,即应用程序具有了某种意义上的主动性;而人工智能的另一个分支-决策理论和方法则使应用程序具有了自主判断和选择的行为的能力.人工智能围绕着知识所进行的广泛研究和应用正逐步形成一门新的学科,这就是知识工程,它涉及的知识的获取,存储和管理等许多课题.所有这些技术的发展加快了应用程序智能化的进程. 随着网络技术的发展,多个应用程序间相互作用的模式正从单一的集成式系统向分布式系统演化.一个在物理上和地理上分布的应用程序之间通信与合作的网络地层基础结构正逐渐建立起来.分布式对象技术(如 CORBA 或 DCOM 技术)则进一步使分布且异构的应用程序之间能以一种共
11、同的方式提供和获得服务,实现了在分布式状态下的软集成. 智能化和网络化的发展促成了 Agent 技术的发展,Agent 技术正是为解决复杂,动态,分布式智能应用而提供的一种新的计算手段. 2.2Agent 定义 目前并不存在一个被普遍接受的 Agent 的定义,事实上,对这个问题尚有争论,并存在不同的看法.尽管把自治性作为 Agent 的核心概念已经达成了普遍的共识,但除此之外很少有一致的看法. Wooldridge 和 Jennings 在总结了前人在 Agent 领域的一些工作后认为,可以从狭义和广义两个方面去理解 Agent 的特性 (1)Agent 弱概念 这是从广义的角度来规定 Ag
12、ent 的特性.几乎所有被称为 Agent的软件或硬件系统都具有以下的特性: 自治性(Autonomy):Agent 运行时不直接由人或者其它东西控制,它对它们自己的行为和内部状态有一定的控制权. 社会能力(Social Ability)或称可通信性:Agent 能够通过某种Agent 通信语言(agent communication language)与其它 Agent 进行信息交换. 反应能力(Reactivity):即对环境的感知和影响.无论 Agent 生存在现实的世界中(如机器人,Internet 上的通讯 Agent,用户界面Agent 等)还是虚拟的世界中(如虚拟商场中的 Age
13、nt,交互式游戏中的 Agent 等),它们都应该可以感知它们所处的环境,并通过行为改变环境.一个不能对环境做出影响的物体不能被称作 Agent. 自发行为(Pro-activeness):传统的应用程序是被动地由用户来运行的,而且机械地完成用户的指令;而 Agent 的行为应该是主动的,或者说自发的.Agent 感知周围环境的变化,并作出基于目标的行为(goal-directed behaviour). 在这种定义下,最简单的 Agent 就是具有上述特性的一个计算机进程,这个进程可以简单到只是个具有某种智能的子程序,能够与别的 Agent 交换消息.Agent 弱概念使 Agent 不仅仅
14、只应用于人工智能领域,而且广泛地应用在诸如人机界面,通信,并行工程,软件工程,搜索引擎等.因此很多计算机软件都可以纳入 Agent 的范畴里来,例如处理 Internet 事务,帮助用户处理 E-mail 的助理 Agent 等. Marvin Minsky 从多 Agent 系统的社会智能的角度给出 Agent 的一个定义:这些进程我们称之为 Agent,每个 Agent 本身只会做一些简单的事情,但当我们用特定的方法将这些 Agent 组成一个 Agent 群(society),就产生了真正的智能. Minsky 的定义显然也是一种广义的定义. (2)Agent 强概念 对某些研究者,尤其
15、是人工智能的研究者来说,Agent 除了应具有上面这些特性以外,还应该具有某些通常人类具有的特性.例如知识,信念,意图,承诺等心智状态.有的学者甚至提出了有情感的 Agent. 当前对强概念 Agent 的研究主要集中在理论方面.例如,Shoham提出的面向 Agent 编程(AOP Agent-Oriented Programming)使用的就是强概念的 Agent 定义:一个 Agent 是这样一个实体,它的状态可以看作是由信念(belief),能力(capability),选择(choice),承诺(commitment)等心智构件(mental component)组成. (3)Age
16、nt 的其它属性 长寿性(Longevity):传统应用程序在用户需要时激活,不需要时或者运算结束后停止.Agent与之不同,它应该至少在相当长的时间内连续地运行. 移动性(Mobility):Agent 可以从一个地方移动到另一个地方而保持其内部状态不变.Agent 可以携带数据和能够在远处执行智能指令. 推理能力(Reasoning):Agent 可以根据其当前的知识和经验,以理性的,可再生的方式推理或推测. 规划能力(Planning):根据目标,环境等的要求,Agent 应该至少对自己的短期行为作出规划.虽然程序设计人员可以提供一些常见情况的处理策略,但这些策略不可能覆盖 Agent
17、将遇到的所有情况.所以,Agent 应该有生成规划的能力. 学习和适应能力(Learning and Adaptability):Agent 可以根据过去的经验积累知识,并且修改其行为以适应新的环境.另外,有些学者还提出 Agent 应该具有自适应性,个性等特性. 诚实(Veracity):假定 Agent 不会故意提供错误信息. 善意(Benevolence):假定在 Agent 之间不会存在相互冲突的目标,且 Agent 总是尽力去帮助其它 Agent. 理性(Rationality):假定 Agent 总是尽力去实现自己的目标. 2.3Agent 的适用领域 与用户有灵活的相互作用,在互
18、相作用中智能地协助用户完成琐碎的工作. 在对海量分布式信息搜索中,建立快速智能的搜索机制. 在高度动态的环境下,要求应用程序能对多边的环境作出响应或自适应. 需要应用程序能自主处理失效或冲突,以进行在调度,再计划或资源再分配. 需要应用程序既能进行长期计划驱动的行为,又能从事短期试试响应行为. 在复杂的或安全性很重要的应用程序中,保证适宜的反应和应答时间. 在地理上或逻辑上分布,自主或异构的节点间提供应用服务或中间件服务. 在不完全信息下的复杂或分散的资源分配问题. 2.4agent 技术的标准化 FIPA(Foundation for Intelligent Physical Agents)
19、是一个由IBM,NHK,BT 等公司和政府,学术机构组成的权威的 Agent 标准化组织(http:/www.fipa.org),目前该组织正致力于以下三个主要领域的标准制定: Agent 管理需要认同和发现 Agent(白,黄页服务),需要定义它们的各种状态以及哪些角色能与它们相互作用. Agent相互作用覆盖最高层Agent间相互作用的标准,包括Agent间传递的信息的意义,命令,请求,义务等. Agent 与软件的接口. 此外FIPA还制定了4个参考应用领域的标准,包括个人旅行助手,个人助手,声/视娱乐广播,网络管理等.正在制定的标准包括人类Agent 的相互作用,产品设计与制造 Age
20、nt,Agent 安全管理,支持移动性的Agent管理,Ontology(共享语汇)服务,Agent消息传送,Agent命名,内容语言库等.尽管 FIPA 标准仍在制定和发展之中,但是随着越来越多组织的加入,它必将称为促进 Agent 应用和发展的主要推动力. 第三章 JADE 平台介绍 3.1JADE 平台简介 JADE(Java Agent Development Framework)是一个软件开发框架,用于开发多Agent系统和符合FIPA 标准的智能Agent应用程序.它包含两个主要的产品:一个符合FIPA标准的Agent平台和一个开发JAVA Agent 的包. JADE 完全是由
21、JAVA 编写的,由各种 JAVA 包组成,它为应用程序员既提供现成的功能片断,同时也为自定义的应用程序任务提供抽象接口.由于 JAVA 的许多良好的特性,它是一种很特别的编程语言,特别是它在分布式的不同环境中的面向对象编程方法,例如对象序列化(Object Serialization),反映性 API(Reflection API)和远程方法唤醒(Remote Method Invocation RMI). JADE 主要由下面的包组成: jade.core 实现系统的核心.它包含必须被应用程序员继承的Agent 类 , 除 此 以 外 ,jade.core.behaviours 子 包 还
22、 包 含 一 个Behaviour 类层次结构.行为实现了一个 Agent 的任务或意图.它们是逻辑活动单元,并且可以以不同的方式组合,以获取不同的执行方式,当然,它们是可以并行执行的.应用程序员定义 Agent 的操作,编写行为以及 Agent 的执行路径. jade.lang.acl 子包用于依照 FIPA 标准规定处理 Agent 通讯语言(ACL). jade.content 包包含了一组类用于支持用户定义的概念和语言. jade.domain 包包含了所有那些由 FIPA 标准定义的,描述 Agent管理实体的 JAVA 类,特别是 AMS 和 DF Agent, 它 们 提 供 生
23、 命 周 期 服 务 和 白 黄 页 服 务 . 子 包jade.domain.FIPAAgentManagement 包含了 FIPA Agent 管理的概念和描述其概念的类.子包 jade.domain.JADEAgentManagement 则包含了 JADE 对 Agent 管理的扩展(例如,对消息的探测以及控制 Agent 的生命周期).子包 jade.domain.introspection 包含了用于描述在JADE工 具 和JADE内 核 之 间 沟 通 领 域 的 概 念 . 子 包jade.domain.mobility 包含了描述移动通信的概念. 子包 Jade.gui 包
24、含了一组一般的类,用于建立用户图形界面,用来显示和编辑 Agent 标识符,Agent 描述,ACL 消息 jade.mtp 包包含了一个 JAVA 接口.为了容易用 JADE 框架集成,每个消息传送协议必须利用这个接口,它还包含了一组这些协议的执行. jade.proto 包包含了建模标准交互协议的类(如:fipa-request, fipa-query, fipa-contract-net, fipa-subscribe 和其他一些被FIPA 定义的类),同时也包含了帮助应用程序员建立自定义的协议的类. 3.2JADE 的特点 下面是 JADE 提供给 Agent 编程人员的 JADE 特
25、点列表: -分布式 Agent 平台.Agent 平台可以分散在几个主机上(假设它们可以通过 RMI 连接起来). -从远方主机用图形用户界面来管理 Agent 和 Agent 容器. -在开发基于 JADE 的多 Agent 应用程序时,可以利用调试工具. -平台内的 Agent 移动性,包括传递 Agent 的状态和代码(当需要的时候). -通过行为模型,对多个平行,并行的 Agent 活动的支持.JADE 以无优先权的方式对 Agent 行为进行调度. -FIPA 标准的 Agent 平台,包括 AMS (Agent 管理系统),DF(目录服务),和 ACC(Agent 通讯通道).这三
26、个组成部分在 Agent 平台启动时被自动激活. -为了多域的应用程序,许多FIPA标准的DF在运行时可以被启动.在程序中,每个域是一组逻辑Agent,它们提供的服务通过一个公共的设备被公布出来.每个 DF 继承了 GUI 和所有由 FIPA 定义的标准功能(即,注册,注销,修改,搜索Agent标识符的功能和在网内连接DF的功能). -在同一个 Agent 平台内有效率的 ACL 消息传输.事实上,消息在传送时是以 JAVA 对象被编码,而不是字符串,这样是为了避开编组和未编组的程序.当消息跨越平台边界的时候,它们被自动转换为 FIPA标准的语法,编码方式,传输协议或反之.这种转换对于 Age
27、nt 执行者来说是透明的,它们只需要处理 JAVA 对象. -FIPA 交互协议库是现成可用的. -通过 AMS,Agent 可以自动进行注册和注销. -符合 FIPA 标准的命名服务:在启动时,Agent 从平台上获取它们的 GUID(全球唯一标识). -对应用程序定义的相关语言和概念的支持. -程序内接口,它允许外部应用程序启动自治的 Agent. 3.3 用 JADE 创建多 Agent 系统 3.3.1Agent 平台 由 FIPA 定义的标准的 Agent 平台模式由以下几部分组成: Agent 管理系统(AMS)是负责监督管理对 Agent 平台的访问和使用的 Agent.在一个单
28、独的平台上,只能有一个 AMS.AMS 提供白黄页服务,以及生命周期服务,它保留了一个 Agent 标识符目录(AID)和Agent 状态信息.每个Agent必须在AMS 注册,以获得一个有效的AID. 目录服务(DF)是在平台上提供默认的黄页服务的 Agent. 消息传输系统,又叫做 Agent 通信通道(ACC),是控制平台内所有的信息交换,包括与远端平台进行信息交换的软件. 图 3-1JADE 完全参照这个标准体系结构.因此,当一个 JADE 平台启动的时候,AMS 和 DF 就自动被建立了,同时 ACC 模块允许消息进行传输.Agent 平台允许建立在几个主机上.在每个主机上只有一个J
29、AVA 应用程序,当然也只有一个 JAVA 虚拟机(JVM)被执行.每个 JAVA虚拟机是一个基本的 Agent 容器,它为 Agent 的执行提供一个运行环境,同时它允许几个 Agent 在同一个主机上并行的执行.主容器(main-container)是 Agent 容器,它包括 AMS 和 DF,在那里注册RMI(它由 JADE 在内部使用).与主容器相关的其它容器,为任何一组JADE Agent 的执行提供一个完整的运行环境. 图 3-2 3.3.1.1DF 服务 jade.domain.DFService 利用一组静态方法来实现与一个标准的FIPA DF 服务进行交互.它包含了从 DF
30、 请求注册,注销,修改,搜索行为的方法.每个方法都有一个带有所有所需参数的版本,以及一个所有省略参数都是默认值的版本. 注意,这些方法将会阻塞每个 Agent 活动直至行为被成功的执行或者掷出了一个 jade.domain.FIPAException 违例,也就是说直到会话的结束.在某些情况下,以不阻塞的方式执行这些方法可能会更方便.在这些情况下,jade.proto.AchieveREInitiator 或者jade.proto.SubscriptionInitiator将与createRequestMessage(), createSubscriptionMessage(),decodeD
31、one(), decodeResult() 和 decodeNotification()联合使用,这将简化向 DF 发送消息的准备,以及从 DF 接受消息时的解码. 3.3.1.2AMS 服务 这个类与 DFService 类是成对的,它的服务是由一个标准的 FIPA AMS Agent 提供的,并且它的界面是与 DFService 完全一致的.注意JADE 在调用 setup()前和 takeDown()返回以后分别自动调用注册和注销方法,所以一般的程序员不用去调用它们.但是在某些特定的环境下,程序员可能需要调用它们. 3.3.2Agent 类 Agent 类是用户自定义 Agent 的公共
32、基类.因此,从程序员的角度看,一个 JADE Agent 仅仅是用户自定义的继承了 Agent 类的一个实例.这表现了特性的继承性,这种继承性主要体现在 Agent 平台间交互(注册,配置,远程管理),以及用以实现自定义的 Agent 行为的一组基本方法(如收发消息,使用标准交互协议,注册域,.).Agent 的计算模型是多任务的,任务(或是行为)是并行执行的.每个由 Agent 提供的功能/服务应该作为一个或者多个行为被执行(参考 3.4 行为的执行).Agent基类内的调度对程序员是透明的,它自动管理行为的调度. 3.3.2.1Agent 生命周期 图 3-3 根据 FIPA 中的 Age
33、nt 平台生命周期,JADE Agent 可以处于这几个状态之一,它们在 Agent 类中用几个常量来表示.这些状态分别是: 初始状态 AP_INITIATED:Agent 对象已经建立,但是还没有由 AMS注册,既没有名字,也没有地址,而且不能与其它 Agent 进行通讯. 激活状态 AP_ACTIVE:Agent 对象已经由 AMS 注册,有正规的名字和地址,而且具有 JADE 的各种特性. 挂起状态 AP_SUSPENDED:Agent 对象当前被停止.内部的线程被挂起,没有 Agent 行为被执行. 等待状态 AP_WAITING:Agent 对象被阻塞,等待其它事件.内部的线程在JA
34、VA 监控器上休眠,当条件满足时被唤醒(典型的情形是消息到达). 删除状态 AP_DELETED:Agent 死亡.内部的线程的执行被终结,Agent 不再在 AMS 上有注册信息. 传送状态 AP_TRANSIT:移动 Agent 移动至一个新的位置时进入这个状态.系统继续缓存将被送到这个新位置的消息. 拷贝状态 AP_COPY:这是 JADE 在 Agent 克隆时的一个内部状态. 离开状态 AP_GONE:这是 JADE 在移动 Agent 移至一个新的地点时的一个内部稳定状态. 注意 Agent 只有在激活状态时才允许执行行为(也就是任务).注意如果任何一个行为调用 doWait()方
35、法,那么整个 Agent 及其所有的活动都被阻塞,而不仅仅是调用这个方法的行为.而 block()方法是Behaviour 类的一部分,这是为了挂起一个单独的 Agent 行为. 3.3.2.2Agent 内的通讯 Agent 类同样提供了一组用于 Agent 内通讯的方法.根据 FIPA 说明,Agent 通过异步消息传输进行通讯,ACL 消息的对象是交换的有效载荷.一些由FIPA定义的交互协议也是可由Agent活动调度的现成可用的行为,它们是 jade.proto 包的一部分. Agent.send()方法可以发送 ACL 消息.接收槽保留了正在接收消息的 Agent 的 ID.这种方法调
36、用对于 Agent 的位置来说是透明的,也就是说无论是本地或是远程的 Agent,是平台负责选择最合适的地址和传输机制. 3.3.2.3 带有图形用户界面(GUI)的 Agent 一个构造为多 Agent 系统的应用程序仍然需要与它的用户进行交互.因此,在应用程序中有必要至少在某些 Agent 上提供 GUI.虽然这可能引起一些问题,这主要是因为 Agent 自治特性和普通用户图形界面的反映性间的不匹配造成的.使用 JADE 时,JADE Agent 采用的每个 Agent 一个线程的并发模式必须要与 Swing 并发机制配合使用. 3.3.3Agent 任务.执行 Agent 行为 为了响应
37、不同的外部事件,Agent 必须能够执行几个并行的任务.为了使 Agent 管理更加有效率,每个 JADE Agent 都由一个单独的执行线程组成,并且它的任务都是模型化的,可以作为 Behaviour 的对象来执行.同样可以执行多线程的 Agent,但是 JADE 并没有对此提供特别的支持. 想要执行一个基于 Agent 的任务的开发者应该定义一个或者更多 Behaviours 子类,实例化它们,并把任务对象添加到 Agent 任务列表中.类 Agent 是必须由 Agent 程序员继承的,提供了两个方法:addBehaviour(Behaviour)和removeBehaviour(Beh
38、aviour),它们允许用来管理一个具体任务的就绪队列.注意行为和子行为可以在需要的时候添加进来,而不仅仅是在Agent.setup()方法内部.添加一个行为应该被看做在 Agent 内产生一个新的(合作)执行线程的方式. 由 Agent 基类执行的调度程序对于程序员来说是透明的,对于就绪队列中所有有效的行为,它的调度策略是无优先权的时间片轮转法,执行 Behaviour-derived 类,直至释放控制权(这在 action()方法返回时执行).如果任务没有放弃控制权,它将在下一次轮转是被重新调度.在等待消息到达时,行为同样可以被阻塞.具体的说,Agent调度程序执行就绪行为队列中每个行为的
39、 action()方法.当 action()返回时,done()方法被调度,它用来检测行为是否完成.如果完成了,行为对象将从队列中删除. 行为像合作线程一样工作,但是,没有保存任何栈.因此,整个运行状态必须被保留在 Behaviour 和它相关的 Agent 的临时变量中. 为了防止在激活状态等待消息(这样会浪费 CPU 的时间),允许每个 Behaviour 阻塞它自己的运行.当 action()方法返回时,block()方法就把行为放到阻塞行为队列中.注意,因此,阻塞的结果并不是在调用 block()方法后立即体现出来,而是在 action()方法返回后. 在新的消息到达后,所有被阻塞的行
40、为将重新被调度,因此程序员必须考虑再次阻塞与到达的消息不相关的行为.此外,一个行为对象可以通过向block()方法传递一个时间域值把自己阻塞一段有限的时间.在 JADE 后来的版本中,考虑了更多的唤醒事件. 因为从 Agent 行为中进行选择时,采用的是无优先权的多任务模型,Agent 程序员必须注意避免使用无限循环,以及在 action()方法内部执行长的操作.记住,当某个行为的action()运行时,其它的行为都不能执行,直至 action()结束(这当然只是考虑同一个 Agent 内的行为,其它 Agent 的行为是运行在不同的 java 线程内,当然可以继续独立的运行). 除此以外,既
41、然没有保存任何堆栈,每次 action()方法都是从头开始运行,action()方法不可以在中间打断,也不可以把 CPU 让给其它的行为,然后从行为离开的位置,启动最初的那个行为. 3.4 交互协议 FIPA 规定了一组标准的交互协议,可以以它们作为标准模板来建立 Agent 间的对话.对于 Agent 间的每一次对话,JADE 都区分了发起者(发起会话的 Agent)和回应者(在与其它 Agent 取得联系后参与到会话中的Agent).JADE依据大部分的FIPA交互协议,为会话中的两个角色都提供了行为类.正如在这节中所描述的,这些类都可以在jade.proto 包中找到.它们通过一个同类的
42、 API 提供了回叫方法来处理协议的各个状态. 所有的发起者行为一达到交互协议的某个最终状态,就会立即结束,并从 Agent 的任务队列中删除.为了不必重新建立新的 java 对象就能再次使用代表这些行为的 java 对象,所有的发起者都包含了一些带有合适参数的复位方法.此外,所有的发起者行为,不只是FipaRequestInitiatorBehaviour 都可以进行一对多的会话,也就是说可以在同一时间处理几个回应者. 所有的回应者行为则是循环的,并且它们在达到交互协议的某个最终状态时将被重新调度.注意,这个特性允许程序员限制 Agent 应该并行执行的回应者的最大数量. 3.5 对移动 A
43、gent 的支持 使用 JADE,应用程序的开发者能够建立移动 Agent,它能够在多网络主机结见移动或复制自己.在 JADE 的这个版本中,只支持intra-platform 移动性,这是一个能够在不同的 Agent 的 container间移动的 JADE 移动 Agent,但是它被限制于一个单独的 JADE 平台内. 移动或者克隆被视为 Agent 生命周期状态转换过程的一个状态.如同所有的其它生命周期的操作一样,Agent 移动或是克隆可以由Agent 自己或是 AMS 发起.Agent 类提供了一个合适的 API,而 AMS Agent 能够通过 FIPA ACL 访问. 移动 Ag
44、ent 为了能够决定什么时间以及向哪里移动,它们需要记住自己的位置.因此,JADE 提供了一个所有者的概念,命名为jade-mobility-ontology,它保留了必要的概念和行动. 第四章 基于 JADE 平台上的图书交易系统 图书交易系统是一个利用JADE创建Agent的例子,利用这个例子来分析 Agent 是如何执行任务以及彼此间通讯的. 4.1图书交易系统要实现的功能 这个图书交易系统包括了一些代表个各自用户的售书Agent和买书Agent. 4.1.1 买方 Agent 买方 Agent 不带有 GUI,用户将要购买的书目(target book)以命令行参数的方式传递给买方 A
45、gent.买方 Agent 接着定期的向已知的卖方 Agent 发送购书请求.当有卖方 Agent 提供(offer)该书时,买方 Agent 接受该消息,并执行买的动作.如果不止一个卖方Agent提供这本书,买方Agent将接受最优(也就是最便宜)的一个.在交易完成后,买方 Agent 结束. 4.1.2 卖方 Agent 卖方 Agent 启动了一个简单的 GUI,通过它,用户可以向本地的书目列表(catalogue)中添加新的书目.卖方 Agent 将一直运行,不断的等待来自买方Agent的购书请求.当收到买方Agent的请求时,它们先要检查请求的书目是否在本地的书目列表中.如果在,它们
46、该书的价格作为回应发送给请求该书的买方Agent;如果不在,它们将发送拒绝(refuse)消息.当收到购买(purchase)命令时,卖方 Agent 将执行这个操作,并将请求的图书从本地的图书列表中删除. 4.2 建立 JADE Agent-Agent 类 建 立 一 个JADE Agent, 最 主 要 的 是 要 定 一 个 继 承 了jade.core.Agent 类的类.并且该类还要执行 setup()方法.代码如下: import jade.core.Agent; public class BookBuyerAgent extends Agent protected void se
47、tup() / 打印问候语 System.out.println(Hallo! Buyer-agent +getAID().getName()+ is ready.); setup()方法主要是用于Agent的初始化.而Agent实际上要完成的任务将在行为(behaviours)中执行. 4.2.1agent 标识符 前面已经介绍了 Agent 标识符的表示方法.每个 Agent 标识符都是 jade.core.AID 的一个实例.Agent 类的 getAID()方法可以用来获取Agent的标识符.如果知道了Agent的昵称(nickname),可以通过下面的方式获取它的 AID: Stri
48、ng nickname = Peter; AID id = new AID(nickname, AID.ISLOCALNAME); ISLOCALNAME 常量表明,方法的第一个参数代表的只是一个昵称,并不是一个全球唯一的标识. 4.2.2 结束 Agent 在上面给出的简单的代码中,Agent 即使执行完了打印问候语的任务,Agent 仍然是继续运行的.如果想结束这个 Agent,必须调用这个 Agent 类的 doDelete()方法.takeDown()在 Agent 结束前被调用,它的作用是进行一些 Agent 的清除工作,比如释放 Agent 占用的各种资源. 4.2.3 向 Age
49、nt 中传递参数 在 Agent 启动时,我们可以通过命令行向 Agent 传递一些参数,参数在命令行要用小括号括起来.这些参数可以作为 Object 数组,通过 Agent 类的 getArguments()方法获得.正如在前面提到的,我们希望把用户要买的书目以命令行参数的方式传递给买方Agent.为此,代码可以扩展如下: import jade.core.Agent; import jade.core.AID; public class BookBuyerAgent extends Agent / 想要买的书目 private String targetBookTitle; /已知卖方列表
50、 private AID sellerAgents = new AID(seller1, AID.ISLOCALNAME), new AID(seller2, AID.ISLOCALNAME); /agent 初始化 protected void setup() / 打印问候语 System.out.println(Hallo! Buyer-agent +getAID().getName()+ is ready.); / 获取启动参数,以便得到要买的书目名, Object args = getArguments(); if (args != null & args.length 0) targ
51、etBookTitle = (String) args0; System.out.println(Trying to buy +targetBookTitle); else /立即结束买方 Agent System.out.println(No book title specified); doDelete(); / 把 Agent 的清除操作放在这里 protected void takeDown() /打印结束信息 System.out.println(Buyer-agent +getAID().getName()+ terminating.); 4.3Agent 执行的任务-Behavi
52、our类 Agent 实际上要完成的任务(task)应该在行为(behaviours)中被执行.每个行为都代表了 Agent 要执行的一个任务.每个行为都是一个继承了 jade.core.behaviours.Behaviour.的类的对象.可以通过Agent 类的 addBehaviour 方法把行为添加到 Agent 中.在任何地方都可以把行为添加到 Agent 中,比如在用来初始化 Agent 的 setup()方法中,甚至在其它行为内部再添加一个行为. 每个继承了 Behaviour 的类,都必须执行 action()方法,这个方法实际上定义了这个行为运行时执行的操作.done()方法
53、的返回值是布尔型的.这个返回值表明了该行为是否已经结束,行为一旦结束,就必须从 Agent 的行为池中删除. 4.3.1 行为调度和执行 Agent 可以同时执行几个行为.行为一旦被调度执行了它的action()方法,那么它将一直运行下去直到该方法返回.因此什么时候从一个行为的执行切换到下一个行为的执行是由程序员来决定的.图 4-1 描述了 Agent 线程的执行流程: 图 4-1 从上图可以看出来,下面示例的行为的 action()方法是永远不会返回的: public class OverbearingBehaviour extends Behaviour public void actio
54、n() while (true) /执行某个任务 public boolean done() return true; 如果没有什么行为需要执行,那么 Agent 线程将要休眠,因为这样可以提高 CPU 的利用率.一旦有行为需要执行时,该线程将立即被唤醒. 4.3.2 只执行一次的行为(One-shot behaviours),循环执行的行为(cyclic behaviours)和一般的行为(generic behaviours) 这里主要讲讲三种主要类型的行为. 只执行一次的行为:这种行为的 action()方法只执行一次,并且行为立即结束.jade.core.behaviours.OneS
55、hotBehaviour 类已经把done()方法的返回值设为 true,我们可以继承这个类,来完成我们自己定义的只执行一次的行为,举例如下: public class MyOneShotBehaviour extends OneShotBehaviour public void action() /执行某个操作 X 操作 X 只能执行一次 循环执行的行为:这种类型的行为从来不会结束,它的 action()方法每次被调用时执行相同的操作,jade.core.behaviours.CyclicBehaviour 类已经把 done()方法的返回值设为false,我们可以通过继承这个类,来完成我们
56、自己定义的循环执行的行为,举例如下: public class MyCyclicBehaviour extends CyclicBehaviour public void action() / 执行某个操作 Y 操作 Y 将永远被执行下去,直到执行这个行为的 Agent 结束. 一般的行为:这种类型的行为都包含了一个状态值,并依据这个状态值执行不同的操作.这种行为通常是一个大的 switch 语句,当满足某个条件时,这个行为就结束了. 举例如下: public class MyThreeStepBehaviour extends Behaviour private int step = 0;
57、public void action() switch (step) case 0: / 执行操作 X step+; break; case 1: /执行操作 Y step+;, break; case 2: / 执行操作 Z step+; break; public boolean done() return step = 3; 操作 X,Y,Z 将一次被执行,接着这个行为结束了. JADE 也提供了将这些简单的行为组合成更复杂的行为的功能. 4.3.2 在特定的时间点执行某个操作 JADE提供了两个现成的类Wakerbehaviour和TickerBehaviour,通过这两个类,我们可以
58、使行为在特定的时间点执行某个操作. Wakerbehaviour:它的 action()方法和 done()方法在给定的一段 时 间 后 执 行handleElapsedTimeout() 抽 象 方 法 , 在handleElapsedTimeout()方法结束后,行为也将结束.在下面的例子中,操作 X 在屏幕上打印Adding waker behaviour后十秒钟被执行. public class MyAgent extends Agent protected void setup() System.out.println(Adding waker behaviour); addBeha
59、viour(new WakerBehaviour(this, 10000) protected void handleElapsedTimeout() / 执行操作 X ); TickerBehaviour:这个类的 action()方法和 done()方法在间隔给 定 的 一 段 时 间 后 重 复 地 执 行 onTick() 抽 象 方 法 . 一 个TickerBehaviour 是永远不会结束的.在下面的例子中,操作 Y 每个十秒钟执行一次: public class MyAgent extends Agent protected void setup() addBehaviour(
60、new TickerBehaviour(this, 10000) protected void onTick() /执行操作 Y ); 4.4图书交易系统执行的行为 已经描述了行为的一些基本类型,现在分析一下图书交易系统执行了哪些行为. 4.4.1 买方 Agent 的行为 前面已经讲过,买方Agent间歇的向卖方Agent请求要买的书目.为此,需要使用一个TickerBehaviour,每一次(tick)添加一个真正负责向卖方 Agent 发送请求的行为.因此可以如下修改 BookBuyerAgent类的 setup()方法: protected void setup() /打印问候语 Sy
61、stem.out.println(Hallo! Buyer-agent +getAID().getName()+ is ready.); /获取启动参数,以便得到要买的书目名 Object args = getArguments(); if (args != null & args.length 0) targetBookTitle = (String) args0; System.out.println(Trying to buy +targetBookTitle); /添加一个 TickerBehaviour 负责每分钟调度一个向卖方 Agent发送的请求 addBehaviour(new
62、 TickerBehaviour(this, 60000) protected void onTick() myAgent.addBehaviour(new RequestPerformer(); ); else /结束 Agent System.out.println(No target book title specified); doDelete(); 注意:myAgent 变量是在 Behaviour 类中定义的,它指向正在执行这个行为的 Agent.事实上 RequestPerformer 行为是负责向卖方Agent发送购书请求,这将在下面进行讲述. 4.4.2 卖方 Agent 的
63、行为 前面已经讲过,每个卖方 Agent 都在等待卖方 Agent 发送来的购书请求,并尽可能的提供服务.买方 Agent 发送来的请求可以分为两种类型:一种是询问是否有想要购买的书;一种是请求购买图书.因此,可以这样来设计卖方 Agent:卖方 Agent 执行两个循环执行的行为,分别用来处理买方 Agent 发送来的两种不同类型的请求 收到的请求消息是如何检测到,并被处理的将在下面进行讲述,这里主要是讲述 Agent 间的通讯问题.除此之外,我们还需要在卖方Agent 中增加一个只执行一次的行为.当用户通过 GUI 向 Agent 中添加新的书目时,这个行为用来更新卖方 Agent 的书目
64、列表.下面的代码讲述了 BookSellerAgent 类是如何执行的(OfferRequestsServer类和 PurchaseOrdersServer 类的代码将在下面进行讲述): import jade.core.Agent; import jade.core.behaviours.*; import java.util.*; public class BookSellerAgent extends Agent / 书目列表是一个哈希表,把书目名映射到价格 private Hashtable catalogue; /一个 GUI,通过它,用户可以向书目列表中添加新的书目 private
65、 BookSellerGui myGui; / Agent 初始化 protected void setup() /建立书目列表,它是一个哈希表 catalogue = new Hashtable(); / 建立并显示这个 GUI myGui = new BookSellerGui(this); myGui.show(); /添加负责处理买方 Agent 发来的查询信息的行为 addBehaviour(new OfferRequestsServer(); / 添加负责处理买方 Agent 发来的购书请求的行为 addBehaviour(new PurchaseOrdersServer(); /
66、 Agent 清除 protected void takeDown() / 关闭 GUI myGui.dispose(); / 打印 Agent 结束消息 System.out.println(Seller-agent +getAID().getName()+ terminating.); /* 当用户向书目向书目列表中添加新书时,将激活下面的方法 */ public void updateCatalogue(final String title, final int price) addBehaviour(new OneShotBehaviour() public void action()
67、 catalogue.put(title, new Integer(price); ); BookSellerGUI 类就是一个 Swing GUI,代码在附录描述. 4.5Agent 间通讯-ACLMessage 类 JADE 提供的最重要的特性就是 Agent 间的通讯能力,并采用异步通讯传输.每个 Agent 有一个信箱(mailbox),JADE 把其它 Agent 发送来的信息发送到 Agent 的信箱中.只要有消息被发送到消息队列中,那么收到的 Agent 都会得到提示.但是,Agent 是否以及合适处理队列中的消息对于程序员来说是透明的. 图 4-2 4.5.1 发送消息 向其它
68、 Agent 发送消息,只要填好 ACLMessage 对象的各个域,然后调用Agent类的send方法即可.比如向一个昵称为Peter的Agent发送消息Today its raining代码如下所示: ACLMessage msg = new ACLMessage(ACLMessage.INFORM); msg.addReceiver(new AID(Peter, AID.ISLOCALNAME); msg.setLanguage(English); msg.setOntology(Weather-forecast-ontology); msg.setContent(Today its r
69、aining); send(msg); 4.5.2图书交易系统中的各类消息 在我们的这个图书交易实例中,当买方 Agent 向卖方 Agent 第一次提出购书请求,即询问是否出售想买的书目时,可以设定消息的类型为 CFP(call for proposal),如果卖方 Agent 有这本书的话,将发送带有 PROPOSE的消息给买方 Agent,接着,如果买方 Agent 决定买 Agent A 的书,它将向 Agent A 发送带有 ACCEPT_PROPOSAL 的消息.当然,如果卖方 Agent 的书目列表中没有买方Agent请求的书目,它将发送一个带有REFUSE的消息. 在买方 Ag
70、ent 发送的两种类型的消息中,我们假设消息的内容都是书名.PROPOSE消息必须要带有请求书目的价格.下面是一个建立并发送 CFP 消息的例子: / 查询书目的消息 ACLMessage cfp = new ACLMessage(ACLMessage.CFP); for (int i = 0; i 0) targetBookTitle = (String) args0; System.out.println(Trying to buy +targetBookTitle); /添加一个 TickerBehaviour,它每分钟调度向卖方 Agent 发送的请求 addBehaviour(new
71、 TickerBehaviour(this, 60000) protected void onTick() /更新卖方 Agent 列表 DFAgentDescription template = new DFAgentDescription(); ServiceDescription sd = new ServiceDescription(); sd.setType(book-selling); template.addServices(sd); try DFAgentDescription result = DFService.search(myAgent, template); sell
72、erAgents = new AIDresult.length; for (int i = 0; i 0) /取第一个参数作为书名,并将它强制转化为字符串类型 targetBookTitle = (String) args0; /打印Target book is XX System.out.println(Target book is +targetBookTitle); /添加一个 TickerBehaviour,每分钟调度向卖方主体发送的购书请求 addBehaviour(new TickerBehaviour(this, 60000) protected void onTick() Sy
73、stem.out.println(Trying to buy +targetBookTitle); /更新卖方主体列表 /定义买方主体需要的服务类型 DFAgentDescription template = new DFAgentDescription(); ServiceDescription sd = new ServiceDescription(); sd.setType(book-selling); template.addServices(sd); /搜索买方主体需要的服务 try DFAgentDescription result = DFService.search(myAge
74、nt, template); /搜索到需要的卖书服务 System.out.println(Found the following seller agents:); /定义卖方主体列表 sellerAgents = new AIDresult.length; /打印买方主体列表 for (int i = 0; i result.length; +i) sellerAgentsi = resulti.getName(); System.out.println(sellerAgentsi.getName(); catch (FIPAException fe) fe.printStackTrace(
75、); /向卖方主体发送请求,通过添加 RequestPerformer 行为 myAgent.addBehaviour(new RequestPerformer(); ); /如果参数为空,即没有想买的书目 else /结束主体 System.out.println(No target book title specified); doDelete(); /执行一些主体清除工作 protected void takeDown() /打印主体已经结束的消息 System.out.println(Buyer-agent +getAID().getName()+ terminating.); /*内
76、部类 RequestPerformer.这是买方主体用来向卖方主体请求购书的行为,这个行为要继承 Behaviour 类 */ private class RequestPerformer extends Behaviour private AID bestSeller; /提供最低价格的主体 private int bestPrice; /最低价 private int repliesCnt = 0; /计数从卖方主体接收到的回应数目的计/数器 private MessageTemplate mt; /用来接收回应信息的模板 private int step = 0;/一个状态变量,用来控制
77、 SWITCH 语句 public void action() switch (step) case 0: /向所有的卖方主体发送带有 CFP 的消息,询问卖方主体是否有想买/的书目 ACLMessage cfp = new ACLMessage(ACLMessage.CFP); for (int i = 0; i sellerAgents.length; +i) cfp.addReceiver(sellerAgentsi); cfp.setContent(targetBookTitle); cfp.setConversationId(book-trade); cfp.setReplyWith
78、(cfp+System.currentTimeMillis(); /一个/唯一值 myAgent.send(cfp); /建立模板用来接收建议 mt = MessageTemplate.and( MessageTemplate.MatchConversationId(book-trade), MessageTemplate.MatchInReplyTo(cfp.getReplyWith(); step = 1; break; case 1: /从所有的卖方主体接收建议或者拒绝消息 ACLMessage reply = myAgent.receive(mt); if (reply != null
79、) /收到符合模板的回应消息 if (reply.getPerformative() = ACLMessage.PROPOSE) /如果是建议,也就是说该主体有需要的书目 /取价格 int price = Integer.parseInt(reply.getContent(); if (bestSeller = null | price = sellerAgents.length) /如果已经收到所有的卖方主体发送的回应消息 step = 2; /如果没有收到回应消息则阻塞 else block(); break; case 2: /向提供最低价格的卖方主体发送购书请求 /创建 ACL 消息
80、ACLMessage order = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL); order.addReceiver(bestSeller); order.setContent(targetBookTitle); order.setConversationId(book-trade); order.setReplyWith(order+System.currentTimeMillis(); myAgent.send(order); /建立合适的模板用来接收卖方主体发送来的回应 mt = MessageTemplate.and( MessageTemp
81、late.MatchConversationId(book-trade), MessageTemplate.MatchInReplyTo(order.getReplyWith(); step = 3; break; case 3: /接收购书请求的回应 reply = myAgent.receive(mt); if (reply != null) /收到购书请求的回应 if (reply.getPerformative() = ACLMessage.INFORM) /成功进行了交易,结束 System.out.println(targetBookTitle+ successfully purc
82、hased from agent +reply.getSender().getName(); System.out.println(Price = +bestPrice); /结束主体 myAgent.doDelete(); /如果收到的回应消息不是 INFORM,则卖方主体已经把该书出售 else System.out.println(Attempt failed: requested book already sold.); step = 4; / /如果没有收到卖方主体发送来的回应消息,则阻塞 else block(); break; /行为的 done()方法 public boole
83、an done() /收到所有的回应消息,但是没有一个卖方主体可以出售这本书, if (step = 2 & bestSeller = null) /打印购书失败的消息 System.out.println(Attempt failed: +targetBookTitle+ not available for sale); /没有任何主体出售该书或者交易成功,则 done()方法返回真,/RequestPerformer 行为结束 return (step = 2 & bestSeller = null) | step = 4); / RequestPerformer 类结束 (2)用来实现卖
84、方主体 GUI 的 BookSellerGui.java: 代码如下: package jade.bookTrading; import jade.core.AID; import java.awt.*; import java.awt.event.*; import javax.swing.*; class BookSellerGui extends JFrame private BookSellerAgent myAgent; private JTextField titleField, priceField; BookSellerGui(BookSellerAgent a) super(
85、a.getLocalName(); myAgent = a; JPanel p = new JPanel(); p.setLayout(new GridLayout(2, 2); p.add(new JLabel(Book title:); titleField = new JTextField(15); p.add(titleField); p.add(new JLabel(Price:); priceField = new JTextField(15); p.add(priceField); getContentPane().add(p, BorderLayout.CENTER); JBu
86、tton addButton = new JButton(Add); addButton.addActionListener( new ActionListener() public void actionPerformed(ActionEvent ev) try String title = titleField.getText().trim(); String price = priceField.getText().trim(); myAgent.updateCatalogue(title, Integer.parseInt(price); titleField.setText(); p
87、riceField.setText(); catch (Exception e) JOptionPane.showMessageDialog(BookSellerGui.this, Invalid values. +e.getMessage(), Error, JOptionPane.ERROR_MESSAGE); ); p = new JPanel(); p.add(addButton); getContentPane().add(p, BorderLayout.SOUTH); /当用户关闭时,结束主体 /用户使用右上角的按钮关闭主体的用户图形界面 addWindowListener(new
88、 WindowAdapter() public void windowClosing(WindowEvent e) myAgent.doDelete(); ); setResizable(false); public void show() pack(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int centerX = (int)screenSize.getWidth() / 2; int centerY = (int)screenSize.getHeight() / 2; setLocatio
89、n(centerX - getWidth() / 2, centerY - getHeight() / 2); super.show(); 用来实现卖方主体的 BookSellerAgent.java: 代码如下: package jade.bookTrading; import jade.core.Agent; import jade.core.behaviours.*; import jade.lang.acl.ACLMessage; import jade.lang.acl.MessageTemplate; import jade.domain.DFService; import jad
90、e.domain.FIPAException; import jade.domain.FIPAAgentManagement.DFAgentDescription; import jade.domain.FIPAAgentManagement.ServiceDescription; import java.util.*;/ public class BookSellerAgent extends Agent /代售书目列表,哈希表,把书目映射到价格上 private Hashtable catalogue; /卖方主体的用户图形界面,通过它用户可以向书目列表添加新的书目 private Boo
91、kSellerGui myGui; /主体初始化 protected void setup() /创建书目列表 catalogue = new Hashtable(); /创建并显示 GUI myGui = new BookSellerGui(this); myGui.show(); /在黄页上注册售书服务 DFAgentDescription dfd = new DFAgentDescription(); dfd.setName(getAID(); ServiceDescription sd = new ServiceDescription(); sd.setType(book-sellin
92、g); sd.setName(JADE-book-trading); dfd.addServices(sd); try DFService.register(this, dfd); catch (FIPAException fe) fe.printStackTrace(); /添加服务买方主体查询的行为 addBehaviour(new OfferRequestsServer(); /添加处理买方主体购书请求的行为, addBehaviour(new PurchaseOrdersServer(); /主体清除工作 protected void takeDown() /从黄页上注销该服务 try
93、 DFService.deregister(this); catch (FIPAException fe) fe.printStackTrace(); /关闭 GUI myGui.dispose(); /打印主体已经结束的消息 System.out.println(Seller-agent +getAID().getName()+ terminating.); /* 下面的函数是在用户想通过 GUI 向代售书目中添加新书时被激活的 */ public void updateCatalogue(final String title, final int price) addBehaviour(n
94、ew OneShotBehaviour() public void action() catalogue.put(title, new Integer(price); System.out.println(title+ inserted into catalogue. Price = +price); ); /* 内部类 OfferRequestsServer. 这个行为是卖方主体用来处理买方主体发送来的查询消息的 如果查询的书目在本地的代售书目中,卖方主体回应一个PROPOSE 消息,如果不在,则发送 REFUSEIf */ private class OfferRequestsServer
95、 extends CyclicBehaviour public void action() MessageTemplate mt = MessageTemplate.MatchPerformative( ACLMessage.CFP); ACLMessage msg = myAgent.receive(mt); if (msg != null) / 如果收到 CFP 消息,则处理 String title = msg.getContent(); ACLMessage reply = msg.createReply(); /读取价格 Integer price = (Integer) catal
96、ogue.get(title); if (price != null) / 如果查询的书目在代售书目中,则读取它的价格 reply.setPerformative(ACLMessage.PROPOSE); reply.setContent(String.valueOf(price.intValue(); else /查询的书目不出售 reply.setPerformative(ACLMessage.REFUSE); reply.setContent(not-available); myAgent.send(reply); else block(); / OfferRequestsServer
97、结束 /* 内部类 PurchaseOrdersServer. 这个类用于处理买方主体发送来的购书请求,卖方主体从代售书目列表中删除该书目,并向买方主体发送一个 INFORM 消息,用于告诉买方主体,交易已经成功的进行了. */ private class PurchaseOrdersServer extends CyclicBehaviour public void action() MessageTemplate mt = MessageTemplate.MatchPerformative( ACLMessage.ACCEPT_PROPOSAL); ACLMessage msg = myA
98、gent.receive(mt); if (msg != null) /收到 ACCEPT_PROPOSAL 消息,并进行处理 String title = msg.getContent(); ACLMessage reply = msg.createReply(); Integer price = (Integer) catalogue.remove(title); if (price != null) reply.setPerformative(ACLMessage.INFORM); System.out.println(title+ sold to agent +msg.getSende
99、r().getName(); else /请求的书目同时被卖出去了 reply.setPerformative(ACLMessage.FAILURE); reply.setContent(not-available); myAgent.send(reply); else block(); / OfferRequestsServer 类结束 (4) /* 内部类 RequestPerformer. 这个行为是买方 Agent 用来向卖方 Agent 发送请求的. */ private class RequestPerformer extends Behaviour private AID bes
100、tSeller; / 提供最优选择(即书价最便宜)的卖方 Agent private int bestPrice; / 最低的价格 private int repliesCnt = 0; / 从卖方 Agent 收到的回应消息数 private MessageTemplate mt; / 接受消息的模板 private int step = 0; /这是一个状态变量,依据它采取不同的操作 public void action() switch (step) case 0: /向所有的卖方 Agent 发送 CFP 消息 ACLMessage cfp = new ACLMessage(ACLMe
101、ssage.CFP); for (int i = 0; i sellerAgents.length; +i) cfp.addReceiver(sellerAgentsi); cfp.setContent(targetBookTitle); cfp.setConversationId(book-trade); cfp.setReplyWith(cfp+System.currentTimeMillis(); / Unique value myAgent.send(cfp); / 定义消息的模板,以便收到 PROPASE 类型的消息 mt = MessageTemplate.and(MessageT
102、emplate.MatchConversationId(book-trade), MessageTemplate.MatchInReplyTo(cfp.getReplyWith(); step = 1; break; case 1: /接收所有的 PROPOSE 或 REFUSDER 类型的消息 ACLMessage reply = myAgent.receive(mt); if (reply != null) / 收到回应消息 if (reply.getPerformative() = ACLMessage.PROPOSE) /这是一个供应者 int price = Integer.pars
103、eInt(reply.getContent(); /将其转化为整型 if (bestSeller = null | price = sellerAgents.length) / 已经收到所有回应信息 step = 2; else block(); break; case 2: / 向出价最便宜的售书者发送购买请求 ACLMessage order = new ACLMessage(ACLMessage.ACCEPT_PROPOSAL); /以正确的值填充消息的各个域 order.addReceiver(bestSeller); order.setContent(targetBookTitle)
104、; order.setConversationId(book-trade); order.setReplyWith(order+System.currentTimeMillis(); myAgent.send(order); / 定义合适的消息模板用来接受合适的回应消息 mt = MessageTemplate.and( MessageTemplate.MatchConversationId(book-trade), MessageTemplate.MatchInReplyTo(order.getReplyWith(); step = 3; break; case 3: / 接受请求购买消息的
105、回应 reply = myAgent.receive(mt); if (reply != null) / 收到请求购买消息的回应 if (reply.getPerformative() = ACLMessage.INFORM) /成功购买,此时买方 Agent 可以结束了 System.out.println(targetBookTitle+ successfully purchased.); System.out.println(Price = +bestPrice); myAgent.doDelete(); step = 4; else block(); break; public boo
106、lean done() return (step = 2 & bestSeller = null) | step = 4); /结束 外文资料 1 INTRODUCTION This programmers guide is complemented by the administrators guide and the HTML documentation available in the directory jade/doc. If and where conflict arises between what is reported in the HTML documentation an
107、d this guide, preference should be given to the HTML documentation that is updated more frequently. JADE (Java Agent Development Framework) is a software development framework aimed at developing multi-agent systems and applications conforming to FIPA standards for intelligent agents. It includes tw
108、o main products: a FIPA-compliant agent platform and a package to develop Java agents. JADE has been fully coded in Java and an agent programmer, in order to exploit the framework, should code his/her agents in Java, following the implementation guidelines described in this programmers guide. This g
109、uide supposes the reader to be familiar with the FIPA standards1, at least with the Agent Management specifications (FIPA no. 23), the Agent Communication Language, and the ACL Message Structure (FIPA no. 61). JADE is written in Java language and is made of various Java packages, giving application
110、programmers both ready-made pieces of functionality and abstract interfaces for custom, application dependent tasks. Java was the programming language of choice because of its many attractive features, particularly geared towards object-oriented programming in distributed heterogeneous environments;
111、 some of these features are Object Serialization, Reflection API and Remote Method Invocation (RMI). JADE is composed of the following main packages. jade.core implements the kernel of the system. It includes the Agent class that must be extended by application programmers; besides, a Behaviour clas
112、s hierarchy is contained in jade.core.behaviours sub-package. Behaviours implement the tasks, or intentions, of an agent. They are logical activity units that can be composed in various ways to achieve complex execution patterns and that can be concurrently executed. Application programmers define a
113、gent operations writing behaviours and agent execution paths interconnecting them. The jade.lang.acl sub-package is provided to process Agent Communication Language according to FIPA standard specifications. The jade.content package contains a set of classes to support user-defined ontologies and co
114、ntent-languages. A separate tutorial describes how to use the JADE support to message content. In particular jade.content.lang.sl contains the SL codec2, both the parser and the encoder. The jade.domain package contains all those Java classes that represent the Agent Management entities defined by t
115、he FIPA standard, in particular the AMS and DF agents, that provide life-cycle, white and yellow page services. The subpackage jade.domain.FIPAAgentManagement contains the FIPA-Agent-Management Ontology and all the classes representing its concepts. The subpackage jade.domain.JADEAgentManagement con
116、tains, instead, the JADE extensions for Agent- Management (e.g. for sniffing messages, controlling the life-cycle of agents, ), including the Ontology and all the classes representing its concepts. The subpackage jade.domain.introspection contains the concepts used for the domain of discourse betwee
117、n the JADE tools (e.g. the Sniffer and the Introspector) and the JADE kernel. The subpackage jade.domain.mobility contains all concepts used to communicate about mobility. The jade.gui package contains a set of generic classes useful to create GUIs to display and edit Agent-Identifiers, Agent Descri
118、ptions, ACLMessages, The jade.mtp package contains a Java interface that every Message Transport Protocol should implement in order to be readily integrated with the JADE framework, and the implementation of a set of these protocols. jade.proto is the package that contains classes to model standard
119、interaction protocols (i.e. fipa-request, fipa-query, fipa-contract-net, fipa-subscribe and soon others defined by FIPA), as well as classes to help application programmers to create protocols of their own. The FIPA package contains the IDL module defined by FIPA for IIOP-based message transport. Fi
120、nally, the jade.wrapper package provides wrappers of the JADE higher-level functionalities that allows the usage of JADE as a library, where external Java applications launch JADE agents and agent containers (see also section 3.8). JADE comes bundled with some tools that simplify platform administra
121、tion and application development. Each tool is contained in a separate sub-package of jade.tools. Currently, the following tools are available: Remote Management Agent, RMA for short, acting as a graphical console for platform management and control. A first instance of an RMA can be started with a
122、command line option (-gui) , but then more than one GUI can be activated. JADE maintains coherence among multiple RMAs by simply multicasting events to all of them. Moreover, the RMA console is able to start other JADE tools. The Dummy Agent is a monitoring and debugging tool, made of a graphical us
123、er interface and an underlying JADE agent. Using the GUI it is possible to compose ACL messages and send them to other agents; it is also possible to display the list of all the ACL messages sent or received, completed with timestamp information in order to allow agent conversation recording and reh
124、earsal. The Sniffer is an agent that can intercept ACL messages while they are in flight, and displays them graphically using a notation similar to UML sequence diagrams. It is useful for debugging your agent societies by observing how they exchange ACL messages. The IntrospectorAgent is a very usef
125、ul tool that allows to monitor the life cycle of an agent, its exchanged ACL messages and the behaviours in execution. The SocketProxyAgent is a simple agent, acting as a bidirectional gateway between a JADE platform and an ordinary TCP/IP connection. ACL messages, travelling over JADE proprietary t
126、ransport service, are converted to simple ASCII strings and sent over a socket connection. Viceversa, ACL messages can be tunnelled via this TCP/IP connection into the JADE platform. This agent is useful, e.g. to handle network firewalls or to provide platform interactions with Java applets within a
127、 web browser. The DF GUI is a complete graphical user interface that is used by the default Directory Facilitator (DF) of JADE and that can also be used by every other DF that the user might need. In such a way, the user might create a complex network of domains and sub-domains of yellow pages. This
128、 GUI allows in a simple and intuitive way to control the knowledge base of a DF, to federate a DF with other DFs, and to remotely control (register/deregister/modify/search) the knowledge base of the parent DFs and also the children DFs (implementing the network of domains and subdomains). JADE. is
129、a trade mark registered by CSELT3. 2 JADE FEATURES The following is the list of features that JADE offers to the agent programmer: - Distributed agent platform. The agent platform can be split among several hosts (provided they can be connected via RMI). Only one Java application, and therefore only
130、 one Java Virtual Machine, is executed on each host. Agents are implemented as Java threads and live within Agent Containers that provide the runtime support to the agent execution. - Graphical user interface to manage several agents and agent containers from a remote host. - Debugging tools to help
131、 in developing multi agents applications based on JADE. - Intra-platform agent mobility, including transfer of both the state and the code (when necessary) of the agent. - Support to the execution of multiple, parallel and concurrent agent activities via the behaviour model. JADE schedules the agent
132、 behaviours in a non-preemptive fashion. - FIPA-compliant Agent Platform, which includes the AMS (Agent Management System), the DF (Directory Facilitator), and the ACC (Agent Communication Channel). All these three components are automatically activated at the agent platform start-up. - Many FIPA-co
133、mpliant DFs can be started at run time in order to implement multi-domain applications, where a domain is a logical set of agents, whose services are advertised through a common facilitator. Each DF inherits a GUI and all the standard capabilities defined by FIPA (i.e. capability of registering, der
134、egistering, modifying and searching for agent descriptions; and capability of federating within a network of DFs). - Efficient transport of ACL messages inside the same agent platform. Infact, messages are transferred encoded as Java objects, rather than strings, in order to avoid marshalling and un
135、marshalling procedures. When crossing platform boundaries, the message is automatically converted to/from the FIPA compliant syntax, encoding, and transport protocol. This conversion is transparent to the agent implementers that only need to deal with Java objects. - Library of FIPA interaction prot
136、ocols ready to be used. - Automatic registration and deregistration of agents with the AMS. - FIPA-compliant naming service: at start-up agents obtain their GUID (Globally Unique Identifier) from the platform. - Support for application-defined content languages and ontologies. - InProcess Interface
137、to allow external applications to launch autonomous agents. 3 CREATING MULTI-AGENT SYSTEMS WITH JADE This chapter describes the JADE classes that support the development of multi-agent systems. JADE warrants syntactical compliance and, where possible, semantic compliance with FIPA specifications. 3.
138、1 The Agent Platform The standard model of an agent platform, as defined by FIPA, is represented in the following figure. The Agent Management System (AMS) is the agent who exerts supervisory control over access to and use of the Agent Platform. Only one AMS will exist in a single platform. The AMS
139、provides white-page and life-cycle service, maintaining a directory of agent identifiers (AID) and agent state. Each agent must register with an AMS in order to get a valid AID. The Directory Facilitator (DF) is the agent who provides the default yellow page service in the platform. The Message Tran
140、sport System, also called Agent Communication Channel (ACC), is the software component controlling all the exchange of messages within the platform, including messages to/from remote platforms. JADE fully complies with this reference architecture and when a JADE platform is launched, the AMS and DF
141、are immediately created and the ACC module is set to allow message communication. The agent platform can be split on several hosts. Only one Java application, and therefore only one Java Virtual Machine (JVM), is executed on each host. Each JVM is a basic container of agents that provides a complete
142、 run time environment for agent execution and allows several agents to concurrently execute on the same host. The main-container, or front-end, is the agent container where the AMS and DF lives and where the RMI registry, that is used internally by JADE, is created. The other agent containers, inste
143、ad, connect to the main container and provide a complete run-time environment for the execution of any set of JADE agents. According to the FIPA specifications, DF and AMS agents communicate by using the FIPA-SL0 content language, the fipa-agent-management ontology, and the fiparequest interaction p
144、rotocol. JADE provides compliant implementations for all these components: - the SL-0 content language is implemented by the class jade.content.lang.sl.SLCodec. Automatic capability of using this language can be added to any agent by using the method getContentManager().registerLanguage(SL0Codec.NAM
145、E, new SLCodec(0); - concepts of the ontology (apart from Agent Identifier, implemented by jade.core.AID) are implemented by classes in the jade.domain.FIPAAgentManagement package. The FIPAManagementOntology class defines the vocabulary with all the constant symbols of the ontology. Automatic capabi
146、lity of using this ontology can be added to any agent by using the fillowing code: getContentManager().registerOntology(FIPAManagementOntology.NA ME, FIPAManagementOntology.getInstance(); - finally, the fipa-request interaction protocol is implemented as ready-to-use behaviours in the package jade.p
147、roto. 3.1.1 FIPA-Agent-Management ontology Every class implementing a concept of the fipa-agent-management ontology is a simple collection of attributes, with public methods to read and write them, according to the frame based model that represents FIPA fipa-agent-management ontology concepts. The f
148、ollowing convention has been used. For each attribute of the class, named attrName and of type attrType, two cases are possible: 1) The attribute type is a single value; then it can be read with attrType getAttrName() and written with void setAttrName(attrType a), where every call to setAttrName() o
149、verwrites any previous value of the attribute. 2) The attribute type is a set or a sequence of values; then there is an void addAttrName(attrType a) method to insert a new value and a void clearAllAttrName() method to remove all the values (the list becomes empty). Reading is performed by a Iterator
150、 getAllAttrName() method that returns an Iterator object that allows the programmer to walk through the List and cast its elements to the appropriate type. Refer to the HTML documentation for a complete list of these classes and their interface. 3.1.1.1 Basic concepts of the ontology The package jad
151、e.content.onto.basic includes a set of classes that are commonly part of every ontology, such as Action, TrueProposition, Result, , The BasicOntology can be joined to any user-defined ontology as described in section 3.6. Notice that the Action class should be used to represent actions. It has a cou
152、ple of methods to set/get the AID of the actor (i.e. the agent who should perform the action) and the action itself (e.g. Register/Deregister/Modify). 3.1.2 Simplified API to access DF and AMS services JADE features described so far allow complete interactions between FIPA system agents and user def
153、ined agents, simply by sending and receiving messages as defined by the standard. However, because those interactions have been fully standardized and because they are very common, the following classes allow to successfully accomplish this task with a simplified interface. Two methods are implement
154、ed by the class Agent to get the AID of the default DF and AMS of the platform: getDefaultDF() and getAMS(). 3.1.2.1 DFService jade.domain.DFService implements a set of static methods to communicate with a standard FIPA DF service (i.e. a yellow pages agent). It includes methods to request register,
155、 deregister, modify and search actions from a DF. Each of this method has a version with all the needed parameters, and one with a subset of them where the omitted parameters are given default values. Notice that these methods block every agent activity until the action is successfully executed or a
156、 jade.domain.FIPAException exception is thrown (e.g. because a failure message has been received by the DF), that is, until the end of the conversation. In some cases, instead, it is more convenient to execute these tasks in a non-blocking way. In these cases a jade.proto.AchieveREInitiator or jade.
157、proto.SubscriptionInitiator (see 3.5) should be used in conjunction with the createRequestMessage(), createSubscriptionMessage(), decodeDone(), decodeResult() and decodeNotification() methods thatfacilitate the preparation and decoding of messages to be sent/received to/from the DF. The following pi
158、ece of code exemplifies that in the case of an agent subscribing to the default DF. DFAgentDescription template = / fill the template AID df = getDefaultDF(); ACLMessage subs = DFService.createSubscriptionMessage(this, df, template, null) Behaviour b = new SubscriptionInitiator(this, subs) protected
159、 void handleInform(ACLMessage inform) try DFAgentDescription dfds = DFService.decodeNotification(inform.getContent(); / do something catch (FIPAException fe) fe.printStackTrace(); ; addBehaviour(b); 3.1.2.2 AMSService This class is dual of DFService class, accessing services provided by a standard F
160、IPA AMS agent and its interface completely corresponds the the DFService one. Notice that JADE calls automatically the register and deregister methods with the default AMS respectively before calling setup() method and just after takeDown() method returns; so there is no need for a normal programmer
161、 to call them. However, under certain circumstances, a programmer might need to call its methods. To give some examples: when an agent wishes to register with the AMS of a remote agent platform, or when an agent wishes to modify its description by adding a private address to the set of its addresses
162、, 3.2 The Agent class The Agent class represents a common base class for user defined agents. Therefore, from the programmers point of view, a JADE agent is simply an instance of a user defined Java class that extends the base Agent class. This implies the inheritance of features to accomplish basic
163、 interactions with the agent platform (registration, configuration, remote management, ) and a basic set of methods that can be called to implement the custom behaviour of the agent (e.g. send/receive messages, use standard interaction protocols, register with several domains, ). The computational m
164、odel of an agent is multitask, where tasks (or behaviours) are executed concurrently. Each functionality/service provided by an agent should be implemented as one or more behaviours (refer to section 3.4 for implementation of behaviours). A scheduler, internal to the base Agent class and hidden to t
165、he programmer, automatically manages the scheduling of behaviours. 3.2.1 Agent life cycle A JADE agent can be in one of several states, according to Agent Platform Life Cycle in FIPA specification; these are represented by some constants in Agent class. The states are: - AP_INITIATED : the Agent obj
166、ect is built, but hasnt registered itself yet with the AMS, has neither a name nor an address and cannot communicate with other agents. - AP_ACTIVE : the Agent object is registered with the AMS, has a regular name and address and can access all the various JADE features. - AP_SUSPENDED : the Agent o
167、bject is currently stopped. Its internal thread is suspended and no agent behaviour is being executed. - AP_WAITING : the Agent object is blocked, waiting for something. Its internal thread is sleeping on a Java monitor and will wake up when some condition is met (typically when a message arrives).
168、- AP_DELETED : the Agent is definitely dead. The internal thread has terminated its execution and the Agent is no more registered with the AMS. - AP_TRANSIT: a mobile agent enters this state while it is migrating to the new location. The system continues to buffer messages that will then be sent to
169、its new location. - AP_COPY: this state is internally used by JADE for agent being cloned. - AP_GONE: this state is internally used by JADE when a mobile agent has migrated to a new location and has a stable state. The Agent class provides public methods to perform transitions between the various st
170、ates; these methods take their names from a suitable transition in the Finite State Machine shown in FIPA specification Agent Management. For example, doWait() method puts the agent into AP_WAITING state from AP_ACTIVE state, doSuspend()method puts the agent into 12 AP_SUSPENDED state from AP_ACTIVE
171、 or AP_WAITING state, Refer to the HTML documentation of the Agent class for a complete list of these doXXX() methods. Notice that an agent is allowed to execute its behaviours (i.e. its tasks) only when it is in the AP_ACTIVE state. Take care that if any behaviours call the doWait() method, then th
172、e whole agent and all its activities are blocked and not just the calling behaviour. Instead, the block() method is part of the Behaviour class in order to allow suspending a single agent behaviour (see section 3.4 for details on the usage of behaviours). 3.2.1.1 Starting the agent execution The JAD
173、E framework controls the birth of a new agent according to the following steps: the agent constructor is executed, the agent is given an identifier (see the HTML documentation for the jade.core.AID class), it is registered with the AMS, it is put in the AP_ACTIVE state, and finally the setup() metho
174、d is executed. According to the FIPA specifications, an agent identifier has the following attributes: - a globally unique name. By default JADE composes this name as the concatenation of the local name i.e. the agent name provided on the command line plus the symbol, plus the home agent platform id
175、entifier i.e. : / JADE); Tough in the case that the name of the platform is specified on the command line the agent name is constructed as a concatenation of the local name plus the symbol plus the specified platform name. - a set of agent addresses. Each agent inherits the transport addresses of it
176、s home agent platform; - a set of resolvers, i.e. white page services with which the agent is registered. The setup() method is therefore the point where any application-defined agent activity starts. The programmer has to implement the setup()method in order to initialise the agent. When the setup(
177、) method is executed, the agent has been already registered with the AMS and its Agent Platform state is AP_ACTIVE. The programmer should use this initialisation procedure to: - (optional) if necessary, modify the data registered with the AMS (see section 3.1.2); - (optional) set the description of
178、the agent and its provided services and, if necessary, register the agent with one or more domains, i.e. DFs (see section 3.1.2); - (necessary) add tasks to the queue of ready tasks using the method addBehaviour(). These behaviours are scheduled as soon as the setup() method ends; The setup() method
179、 should add at least one behaviour to the agent. At the end of the setup() method, JADE automatically executes the first behaviour in the queue of ready tasks and then switches to the other behaviours in the queue by using a round-robin non-preemptive scheduler. The addBehaviour(Behaviour) and remov
180、eBehaviour(Behaviour) methods of the Agent class can be used to manage the task queue. 3.2.1.2 Stopping agent execution Any behaviour can call the Agent.doDelete() method in order to stop agent execution. The Agent.takeDown() method is executed when the agent is about to go to AP_DELETED state, i.e.
181、 it is going to be destroyed. The takeDown() method can be overridden by the programmers in order to implement any necessary cleanup. When this method is executed the agent is still registered with the AMS and can therefore send messages to other agents, but just after the takeDown()method is comple
182、ted, the agent will be de-registered and its thread destroyed. The intended purpose of this method is to perform application specific cleanup operations, such as de-registering with DF agents. 3.2.2 Inter-agent communication. The Agent class also provides a set of methods for inter-agent communicati
183、on. According to the FIPA specification, agents communicate via asynchronous message passing, where objects of the ACLMessage class are the exchanged payloads. See also section 3.3 for a description of the ACLMessage class. Some of the interaction protocols defined by FIPA are also available as read
184、y-to-use behaviours that can be scheduled for agent activities; they are part of the jade.proto package. The Agent.send() method allows to send an ACLMessage. The value of the receiver slot holds the list of the receiving agent IDs. The method call is completely transparent to where the agent reside
185、s, i.e. be it local or remote, it is the platform that takes care of selecting the most appropriate address and transport mechanism. 3.2.2.1 Accessing the private queue of messages. The platform puts all the messages received by an agent into the agents private queue. By default (since JADE 2.5) the
186、 size of this queue is unlimited, however, in case of limited resources, this default can be changed via the method setQueueSize(). Several access modes have been implemented in order to get messages from this private queue: - The message queue can be accessed in a blocking (using blockingReceive()
187、method) or non-blocking way (using receive() method). The blocking version must be used very carefully because it causes the suspension of all the agent activities and in particular of all its Behaviours. The non-blocking version returns immediately null when the requested message is not present in
188、the queue; - both methods can be augmented with a pattern-matching capability where a parameter is passed that describes the pattern of the requested ACLMessage. Section 3.3.4 describes the MessageTemplate class; - the blocking access can have a timeout parameter. It is a long that describes the max
189、imum number of milliseconds that the agent activity should remain blocked waiting for the requested message. If the timeout elapses before the message arrives, the method returns null; - the two behaviours ReceiverBehaviour and SenderBehaviour can be used to schedule agent tasks that requires receiv
190、ing or sending messages. 3.2.3 Agents with a graphical user interface (GUI). An application, that is structured as a Multi Agent System, still needs to interact with its users. So, it is often necessary to provide a GUI for at least some agents in the application. This need raises some problems, tho
191、ugh, stemming from the mismatch between the autonomous nature of agents and the reactive nature of ordinary graphical user interfaces. When JADE is used, the thread-per-agent concurrency model of JADE agents must work together with the Swing concurrency model. 3.2.3.1 Java GUI concurrency model In a
192、 Java Virtual Machine there is a single thread, called Event Dispatcher Thread, whose task is to continuously pick event objects (i.e. instances of java.awt.AWTEvent class) from the System Event Queue (which is an instance of java.awt.EventQueue class). Then the event dispatcher thread, among other
193、things, calls the various listeners registered with the event source. The important observation is that all event listeners are executed within a single thread of control (the event dispatcher); from this follows the well known rule that the execution time of an event listener should be short (less
194、than 0.1 s) to ensure interface responsiveness. A very important Swing feature is the Model/View system to manage GUI updates. When a Swing control has some state (a JCheckBox has a checked flag, a JList holds elements, etc.), this state is kept in a Model object (of class DefaultButtonModel, ListMo
195、del, etc.). The model object provides commands to modify the state (e.g. to check or uncheck the checkbox, to add and remove elements from the list, etc.) and the Swing built-in notification mechanism updates the visual appearance of the GUI to reflect the state change. So, a JCheckBox object can ch
196、ange its look in two cases: An event from the user is received (e.g. a MouseClick event). Some other part of the program modifies the model object associated with the JCheckBox. As stated in the Java Tutorial (JFC/Swing trail, Threads and Swing section), the Swing framework is not thread-safe, so an
197、y code that updates the GUI elements must be executed within the event dispatcher thread; since modifying a model object triggers an update of the GUI, it follows from the above that model objects also have to be manipulated just by the event dispatcher thread. The Swing framework provides a simple
198、but general way to pass some user defined code to the Event Dispatcher thread: the SwingUtilities class exposes two static methods that accept a Runnable object, wrap it with a RunnableEvent and push it into the System Event Queue. The invokeLater() method puts the Runnable into the System Event Que
199、ue and returns immediately (behaving like an asynchronous inter-thread call), whereas the invokeAndWait() method puts the Runnable into the System Event Queue and blocks until the Event Dispatcher thread has processed the RunnableEvent (behaving like a synchronous inter-thread call). Moreover, the i
200、nvokeAndWait() method can catch exceptions thrown within the Runnable object. 中文翻译 1 介 绍 这个程序员指导有管理员指导作为补充,并且 HTML 文档保存在jade/doc 目录下.如果 HTML 文档中的内容和这个指导中的内容有冲突的话,应该参照 HTML 文档中的内容,因为这个文档的更新更频繁. JADE(Java Agent Development Framework)是一个软件开发框架,用于开发多 agent 系统和符合FIPA 标准的智能主体应用程序.它包含两个主要的产品:一个符合FIPA 标准的 a
201、gent 平台和一个开发 JAVA agent 的包.JADE 完全是由 JAVA 编写的.一个 agent 程序员要是想使用这个框架就必须用 JAVA 来给他的主体编码,并且,要遵照这个程序员指导中规定的执行方针. 这个指导假设读者熟悉 FIPA 标准,至少熟悉 Agent Management规范(FIPA no.23),Agent 通讯语言(ACL)和 ACL 消息的结构(FIPA no. 61). JADE 使用 JAVA 语言编写的,由各种 JAVA 包组成,它为应用程序员既提供现成的功能片断,同时也为自定义的应用程序任务提供抽象接口.由于 JAVA 的许多良好的特性,它是一种很特别
202、的编程语言,特别是它在分布式的不同环境中的面向对象编程方法,例如对象序列化(Object Serialization),反映性 API(Reflection API)和远程方法唤醒(Remote Method Invocation RMI). JADE 主要由下面的包组成: jade.core 实现系统的核心.它包含必须被应用程序员继承的Agent 类 , 除 此 以 外 ,jade.core.behaviours 子 包 还 包 含 一 个Behaviour类层次结构.行为实现了一个主体的任务或意图.它们是逻辑活动单元,并且可以以不同的方式组合,以获取不同的执行方式,当然,它们是可以并行执行
203、的.应用程序员定义主体的操作,编写行为以及主体的执行路径. jade.lang.acl 子包用于依照 FIPA 标准规定处理主体通讯语言(ACL). jade.content 包包含了一组类用于支持用户定义的概念和语言.一 个 单 独 的 指 南 描 述 了 JADE 对 消 息 内 容 的 支 持 . 特 别的,jade.content.lang.sl 包包含了 SL 编码解码器,既有剖析器,也有编码器. jade.domain 包包含了所有那些由 FIPA 标准定义的,描述 Agent管理实体的JAVA 类,特别是AMS和DF主体,它们提供生命周期服务和白黄页服务.子包jade.domai
204、n.FIPAAgentManagement包含了FIPA主体管理的概念和描述其概念的类.子包jade.domain.JADEAgentManagement 则包含了 JADE 对 Agent 管理的扩展(例如,对消息的探测以及控制主体的生命周期),包括概念和所有描述其概念的类.子包 jade.domain.introspection 包含了用于描述 在 JADE 工 具 和 JADE 内 核 之 间 沟 通 领 域 的 概 念 . 子 包jade.domain.mobility 包含了描述移动通信的概念. 子包 Jade.gui 包含了一组一般的类,用于建立用户图形界面,用来显示和编辑 Age
205、nt 标识符,Agent 描述,ACL 消息 jade.mtp 包包含了一个 JAVA 接口.为了容易用 JADE 框架集成,每个消息传送协议必须利用这个接口,它还包含了一组这些协议的执行. jade.proto 包包含了建模标准交互协议的类(如:fipa-request, fipa-query, fipa-contract-net, fipa-subscribe 和其他一些被 FIPA 定义的类),同时也包含了帮助应用程序员建立自定义的协议的类. FIPA 包包含了由 FIPA 为基于 IIOP 的消息传送定义的 IDL 模块. 最后,jade.wrapper 包包含了 JADE 高级功能的
206、包装,这些功能允许把JADE 当做一个库,在那里外部JAVA 应用启动JADE 主体和主体的容器(3.8 也有讲述). JADE 还附带了一些用以简化平台管理和应用开发的工具.每个工具包含在 jade.tools 的单独的子包中.目前,下列工具是可用的: *远程管理主体(Remote Management Agent, RMA)简而言之,它起到了一个平台管理和控制的图形控制台的作用.RMA的第一个实例可以用命令行参数-gui来启动,但接下来可以激活更多的 GUI 界面.JADE 通过向它们进行多点传送来维持一致性.此外,RMA 控制台还能够启动其它的 JADE 工具. *哑元主体(Dummy
207、Agent)是一个监视和调试的工具,由一个图形界面和一个潜在的JADE 主体组成.使用用户图形界面,就可以组织 ACL 消息,把它们发送到其它的主体,还可以显示发送或收到的消息的列表,同时带有时间戳,这样可以允许对主体间对话进行记录和预演. *嗅探器(Sniffer Agent)是一个主体,它在 ACL 消息传递的是时候翻译它们,并用一个类似 UML 序列图表的符号图形化的显示它们.观察它们是如何交换 ACL 消息对于调试你的主体群是很有用的. *内测主体(IntrospectorAgent)是一个非常有用的工具,它允许检测主体的生命周期,交换的 ACL 消息,以及主体正在执行的行为. *套接
208、字代理主体(SocketProxyAgent)是一个很简单的主体,它在JADE平台和普通的TCP/IP连接之间起到一个双向门的作用.当ACL消息在JADE传送装置传输的时候,它们被转换成简单的ASCII字符串,然后通过套接字连接传送出去.反之亦然,ACL 消息可以通过这个TCP/IP 连接传输到 JADE 平台.这个主体是很有用的,比如负责网络防火墙,或是在浏览器内通过 JAVA 小程序提供平台交互. *目录服务用户图形界面(DF GUI)就是一个用户图形界面,它是由 JADE 目录服务主体自带的,当然它也可以由用户可能需要的其它目录服务主体使用.通过这种方式,使用者可以建立一个域和子域网络的
209、黄页.这个用户图形界面用一种简单直观的方式来控制一个目录服务的信息,把一个目录服务同其它的目录服务联系起来,并远程控制(注册/注销/修改/搜索)其父目录服务和子目录服务(负责域和子域网络)的信息内容. 2 JADE 特点 下面是 JADE 提供给 agent 编程人员的 JADE 特点列表: -分布式主体平台.主体平台可以分散在几个主机上(假设它们可以通过 RMI 连接起来).这样,在每个主机上只有一个 JAVA 应用程序,当然也只有一个 JAVA 虚拟机被执行.Agent 作为 JAVA 线程存在于Agent 容器中,这个容器对于主体的执行提供了运行时的支持. -从远方主机用图形用户界面来管
210、理主体和主体容器. -在开发基于 JADE 的多 agent 应用程序时,可以利用调试工具. -平台内的 agent 移动性,包括传递 agent 的状态和代码(当需要的时候). -通过行为模型,对多个平行,并行的 agent 活动的支持.JADE 以无优先权的方式对 agent 行为进行调度. -FIPA 标准的 Agent 平台,包括 AMS (主体管理系统),DF (目录服务), 和 ACC (主体通讯通道).这三个组成部分在 agent 平台启动时被自动激活. -为了多域的应用程序,许多FIPA标准的DF在运行时可以被启动.在程序中,每个域是一组逻辑主体,它们提供的服务通过一个公共的设
211、备被公布出来.每个 DF 继承了 GUI 和所有由 FIPA 定义的标准功能(即,注册,注销,修改,搜索主体标识符的功能和在网内连接 DF 的功能). -在同一个主体平台内有效率的 ACL 消息传输.事实上,消息在传送时是以 JAVA 对象被编码,而不是字符串,这样是为了避开编组和未编组的程序.当消息跨越平台边界的时候,它们被自动转换为 FIPA 标准的语法,编码方式,传输协议或反之.这种转换对于主体执行者来说是透明的,它们只需要处理 JAVA 对象. -FIPA 交互协议库是现成可用的. -通过 AMS,主体可以自动进行注册和注销. -符合 FIPA 标准的命名服务:在启动时,主体从平台上获
212、取它们的 GUID(全球唯一标识). -对应用程序定义的相关语言和概念的支持. -程序内接口,它允许外部应用程序启动自治的主体. 3 用 JADE 创建多 agent 系统 这一章描述了用以支持多 agent 系统开发的 JADE 类.JADE 遵守FIPA 标准规定的语法,可能地方也会遵守规定的语义. 3.1 Agent 平台 由 FIPA 定义的标准的主体平台模式由以下几部分组成: Agent 管理系统(AMS)是负责监督管理对 Agent 平台的访问和使用的主体.在一个单独的平台上,只能有一个 AMS.AMS 提供白黄页服务,以及生命周期服务,它保留了一个主体标识符目录(AID)和主体状
213、态信息.每个主体必须在 AMS 注册,以获得一个有效的 AID. 目录服务(DF)是在平台上提供默认的黄页服务的主体. 消息传输系统,又叫做 Agent 通信通道(ACC),是控制平台内所有的信息交换,包括与远端平台进行信息交换的软件. JADE 完全参照这个标准体系结构.因此,当一个 JADE 平台启动的时候,AMS 和 DF 就自动被建立了,同时 ACC 模块允许消息进行传输.Agent 平台允许建立在几个主机上.在每个主机上只有一个 JAVA应用程序,当然也只有一个 JAVA 虚拟机(JVM)被执行.每个 JAVA 虚拟机是一个基本的主体容器,它为主体的执行提供一个运行环境,同时它 允
214、许 几 个 主 体 在 同 一 个 主 机 上 并 行 的 执 行 . 主 容 器(main-container)是主体容器,它包括 AMS 和 DF,在那里注册 RMI(它由 JADE 在内部使用).与主容器相关的其它容器,为任何一组 JADE 主体的执行提供一个完整的运行环境. 根据 FIPA 的规定,DF 和 AMS 主体必须使用 FIPA-SL0 语言,FIPA主体管理概念和 FIPA 请求交互协议进行通讯,JADE 对以下组成部分提供符合 FIIPA 标准的执行方式: -SL-0 语言是由类 jade.content.lang.sl.SLCODE 执行的.通过下面的方式,可以向任何一
215、个主体添加自动使用这种语言的能力: getContentManager().registerLanguage(SL0Codec.NAME, newSLCodec(0). -定义的概念(除了由 jade.core.AID 使用的主体标示符)由jade.domain.FIPAAgentManagement包中的类执行.FIPAManagementOntology类定义了存在的词汇以及所有常用的符号.可以通过下面的方法把自动使用它的能力添加到任何一个主体中:getContentManager().registerOntology(FIPAManagementOntology.NAME,FIPAMan
216、agementOntology.getInstance() -最后,FIPA 请求交互协议在 jade.proto 包中作为现成的行为被执行. 3.1.1 FIPA 标准的主体管理概念 每个执行 fipa-agent-management 概念的类都是一个简单的属性的集合,根据基于体现FIPA标准的fipa-agent-management概念的框架模式,可以用公共的方法对它们进行读写.通常使用下面的约定.对类的每个属性,要有属性名和属性类型,可能有两种情况是: 1)属性类型是单值的.那么可以通过 attrType getAttrName()方法得到,并通过 void setAttrName(
217、attrType a) 来 写 , 每 一 次 对void setAttrName(attrType a)的调用都将覆盖前面的属性值. 2) 属 性 的 类 型 上 一 组 或 者 一 系 列 值 ,void addAttrName(attrType a)方法可以用来插入一个新的值,void clearAllAttrName()方法可以用来删除所有的值.读是通过Iterator 类 的 getAllAttrName() 方 法 实 现 的 , 它 将 返 回 一 个Iterator 对象,这个对象允许程序员在 List 类之间移动,并为它的元素设置合适的类型. 参考 HTML 文档来获得这些类
218、的列表以及它们的接口. 3.1.1.1 定义的基本概念 jade.content.onto.basic 包包含了一组类,它们通常是每个定义概念的一部分,比如 Action,TrueProposition, Result, , BasicOntology 可以被添加到任何用户定义的概念中,正如在 3.6 中所述的. 注意 Action 类应该可以用来实现行为.它有一对用来设置和获取行动者 AID 的方法. 3.1.2 简化了的,用来访问 DF 和 AMS 服务的 API 目前定义的 JADE 特性允许通过发送和接收由标准定义的消息来实现简单的在 FIPA 系统主体和用户定义的主体间的交互. 但是
219、,因为那些交互已经是标准化的,通用的,下面的类可以成功的通过一个简化的接口完成这个任务. 这两个方法是通过Agent类实现的,它可以获取平台默认的DF和AMS 的 AID,这两个方法是:getDefaultDF() 和 getAMS(). 3.1.2.1DF 服务 jade.domain.DFService 利用一组静态方法来实现与一个标准的FIPA DF 服务进行交互.它包含了从 DF 请求注册,注销,修改,搜索行为的方法.每个方法都有一个带有所有所需参数的版本,以及一个所有省略参数都是默认值的版本. 注意,这些方法将会阻塞每个主体活动直至行为被成功的执行或者掷出了一个 jade.domai
220、n.FIPAException 违例,也就是说直到会话的结束.在某些情况下,以不阻塞的方式执行这些方法可能会更方便.在这些情况下,jade.proto.AchieveREInitiator 或者jade.proto.SubscriptionInitiator将createRequestMessage(),createSubscriptionMessage(),decodeDone(), decodeResult() 和 decodeNotification()联合使用,这将简化向 DF 发送消息的准备,以及从 DF 接受消息时的解码.下面的代码片断示例了主体到默认 DF 的情况. DFAgen
221、tDescription template = / fill the template AID df = getDefaultDF(); ACLMessage subs = DFService.createSubscriptionMessage(this, df, template, null) Behaviour b = new SubscriptionInitiator(this, subs) protected void handleInform(ACLMessage inform) try DFAgentDescription dfds =DFService.decodeNotific
222、ation(inform.getContent(); / do something catch (FIPAException fe) fe.printStackTrace(); ; addBehaviour(b); 3.1.2.2 AMS 服务 这个类与 DFService 类是成对的,它的服务是由一个标准的 FIPA AMS 主体提供的,并且它的界面是与 DFService 完全一致的.注意JADE 在调用 setup()前和 takeDown()返回以后分别自动调用注册和注销方法,所以一般的程序员不用去调用它们.但是在某些特定的环境下,程序员可能需要调用它们.举个例子,当一个主体想到远方主
223、体t 平台的 AMS 注册的时候,或这当一个主体希望通过向它的地址组中加入一个私人地址来修改它的描述时 3.2 Agent 类 Agent 类是用户自定义主体的公共基类.因此,从程序员的角度看,一个JADE主体仅仅是用户自定义的继承了Agent类的一个实例.这表现了特性的继承性,这种继承行主要体现在主体平台间交互(注册,配置,远程管理),以及用以实现自定义的主体行为的一组基本方法(如收发消息,使用标准交互协议,注册域,.).主体的计算模型是多任务的,任务(或是行为)是并行执行的.每个由主体提供的功能/服务应该作为一个或者多个行为被执行(参考 3.4 行为的执行).Agent 基类内的调度对程序
224、员是透明的,它自动管理行为的调度 3.2.1 Agent 生命周期 根据 FIPA 中的 Agent 平台生命周期,JADE 主体可以处于这几个状态之一,它们在 Agent 类中用几个常量来表示.这些状态分别是: -初始状态 AP_INITIATED:Agent 对象已经建立,但是还没有由AMS 注册,既没有名字,也没有地址,而且不能与其它主体进行通讯. -激活状态AP_ACTIVE:Agent对象已经由AMS注册,有正规的名字和地址,而且具有 JADE 的各种特性. -挂起状态 AP_SUSPENDED:Agent 对象当前被停止.内部的线程被挂起,没有主体行为被执行. -等待状态 AP_W
225、AITING:Agent 对象被阻塞,等待其它事件.内部的线程在JAVA 监控器上休眠,当条件满足时被唤醒(典型的情形是消息到达). -删除状态 AP_DELETED:Agent 死亡.内部的线程的执行被终结,Agent 不再在 AMS 上有注册信息. -传送状态 AP_TRANSIT:移动主体移动至一个新的位置时进入这个状态.系统继续缓存将被送到这个新位置的消息. -拷贝状态 AP_COPY:这是 JADE 在主体克隆时的一个内部状态. -离开状态 AP_GONE:这是 JADE 在移动主体 t 移至一个新的地点时的一个内部稳定状态. Agent 类提供了公共方法用于这些状态间的转换.FIP
226、A 说明Agent 管理中定义了一个有穷自动机,而这些方法就是从这个自动机的转换状态中命名的.如,doWait()把主体从激活状态转变为等待状态.doSuspend()把主体从激活状态或等待状态转变为挂起状态. doXXX()方法的全部列表可以参见 Agent 类的 HTML 文档. 注意 agent 只有在激活状态时才允许执行行为(也就是任务).注意如果任何一个行为调用doWait()方法,那么整个主体及其所有的活动都被阻塞,而不仅仅是调用这个方法的行为.而 block()方法是Behaviour 类的一部分,这是为了挂起一个单独的主体行为(详见3.4). 3.2.1.1 启动主体执行 JA
227、DE 框架遵循以下步骤控制一个新的主体的产生:运行主体构造器,给主体一个标识符(参见 jade.core.AID 的 HTML 文档),它由 AMS注册,置为激活状态,最后执行 setup().根据 FIPA 说明,主体标识符有如下属性: - 一个全球唯一的名字.JADE 默认的方式是:本地名字,即命令行上提供的主体名,加上符号,再加上主体平台标识符(即 : / JADE).虽然有时平台名在命令行列出,但是主体名仍然是本地名加上,再加上具体的平台名. - 一组主体地址.每个主体继承了它本地主体平台的传输地址. - 一组解析器,也就是主体进行注册的白页服务. 因此 setup()方法是任何应用程
228、序定义的主体活动启动的起始点.程序员为了初始化一个主体必须执行 setup()方法.当 setup()方法执行时,主体已经由 AMS 注册,并且 Agent 平台的状态是激活状态.程序员应该使用这个初始化过程来: -(可选)必要时,修改 AMS 注册的信息(见 3.1.2 节); -(可选)设置主体的描述信息和它所提供的服务.必要时向一个或者更多的域,即 DF,注册该主体.(参见 3.1.2 节). -(必须)使用 addBehavior()方法把任务添加到就绪任务队列.setup()方法运行一结束,这些行为就会被调度. Setup()方法应该至少添加一个行为到主体中.在 setup()方法结
229、束时,JADE 自动执行就绪任务队列中的第一个行为,然后按照无优先权 的 时 间 片 轮 转 法 切 换 到 队 列 中 的 其 它 任 务 .Agent 类 的addBehavior(行为)方法和removeBehavior(行为)方法用于管理任务队列. 3.2.1.2 停止 agent 执行 任何行为都可以调用 Agent.doDelete()方法来停止一个主体的执行. 当主体将要转变为删除状态时,也就是将被删除时,执行Agent.takeDown()方法.程序员在执行必要的清除时,可以重载takeDown()方法.当 takeDown()方法执行时,主体仍然是在 AMS 注册过的,因此能
230、够向其它主体发送消息,但是在 takeDown()方法执行完毕的时候,主体将不再是注册过的,并且它的线程将被撤销.这个方法的主要作用是执行程序特定的清除操作,比如在 DF 主体注销某个主体. 3.2.2 主体内的通讯 Agent 类同样提供了一组用于主体内通讯的方法.根据 FIPA 说明,主体通过异步消息传输进行通讯,ACL 消息的对象是交换的有效载荷.ACLmessage 类的描述详间 3.3 节.一些由 FIPA 定义的交互协议也是可由主体活动调度的现成可用的行为,它们是 jade.proto 包的一部分. Agent.send()方法可以发送 ACL 消息.接收槽保留了正在接收消息的主体
231、的 ID.这种方法调用对于主体的位置来说是透明的,也就是说无论是本地或是远程的主体,是平台负责选择最合适的地址和传输机制. 3.2.2.1 访问私有消息队列 平台把主体接收到的所有消息放到主体的私有消息队列.(从JADE2.5起)消息队列的默认长度是无限的,但是在资源有限的情况下,可以通过setQueueSize()方法来改变这个默认值.有几种访问模式用以从这个消息队列获取消息: -消息队列可以以阻塞(调用 blockingReceive()方法)和非阻塞方式(调用 receive()方法)进行访问.必须小心的使用阻塞方式 ,因为它回引起所有主体活动的挂起,特别是它所有的任务将会被挂起.在非阻
232、塞方式,当请求的消息不在队列时,将立即返回空. -这两种方式都可以扩展成具有模式匹配的能力,此时,必须传递一个描述了请求的 ACLMessage 的模式的参数.3.3.4 节描述了MessageTemplate 类. -阻塞方式的访问可以有一个时间域值作为参数,它是长型的整数,它描述了主体在等待请求的消息时保持阻塞状态的最大毫秒数.如果在消息到达前时间域值到了,该方法将自动返回空值. -可以通过 ReceiverBehaviour 和 SenderBehaviour 两种方法来调度主体用来请求接收或发送消息的行为. 3.2.3 带有图形用户界面(GUI)的主体 一个构造为多 Agent 系统的
233、应用程序仍然需要与它的用户进行交互.因此,在应用程序中有必要至少在某些主体上提供 GUI.虽然这可能引起一些问题,这主要是因为主体自治特性和普通用户图形界面的反映性间的不匹配造成的.使用 JADE 时,JADE 主体采用的每个主体一个线程的并发模式必须要与 Swing 并发机制配合使用. 3.2.3.1 Java GUI 并发模式 在 Java 虚拟机中有一个单独的线程,叫做事件发报线程(Event Dispatcher Thread), 它 的 任 务 就 是 不 断 地 从 系 统 事 件 队 列 ( 它 是java.awt.EventQueue 类的一个实例)中选出事件对象(也就是jav
234、a.awt.AWTEvent类的实例).接着事件发报线程调用在事件源注册过的各个收听者.一个重要的观察结果是所有的事件收听者都是在一个单独的控制线程内执行的,还有一个明显的规则是事件收听者的执行时间应该较短,这样可以保证界面的响应.一个很重要的 Swing 特性是管理GUI更新的模型/视图系统.当一个Swing控制处于某个状态时(jCheckBox 有一个检测标记,jList 持有元素,等),这个状态保存在 Model 对象中.Model 对象提供修改状态(如,检查或是反检查checkbox,或是从列表中添加或删除元素等)的命令,并且 Swing 固定的通告机制能够更新 GUI 的可视化界面来
235、反映状态的改变.因此,一个 JCheckBox 对象能够在下面两种情况下改变它的外观: *接收到用户的事件(如,点击鼠标) *程序的其它部分修改了与 jCheckBox 相关的模型对象. 正如在 Java Tutorial 中所述,Swing 结构不是线程安全的,因此任何更新 GUI元素的代码都必须在事件发报线程内执行.既然修改一个模型对象将触发 GUI 的一次更新,由上面可以得知,模型对象也只能由事件发报线程操控.Swing 结构提供了一个简单但是通用的方法向事件发报线程传递某些用户定义的代码:SwingUtilities 类提供两个接收Runnable 对象的静态方法,这两个静态方法把类封
236、装在可运行事件(RunnableEvent)中并把他们放入系统事件队列.invokeLater()方法把 Runnable 放至系统事件队列中并立即返回(如同一次异步线程内调用),然而 invokeAndWait()方法把 Runnable 放入系统事件队列并阻塞直至事件发报线程处理(如同一次同步线程内调用 )完 RunnableEvent.除此以外,invokeAndWait()这个方法能够捕获 Runnable 对象内掷出的违例. 致 谢 在刚刚选择这个题目时,Agent 技术对于连 java 都不熟悉的我来说,是一个完全陌生的领域.从开学初对这个题目一窍不通,到今天能够完成这篇 2 万多
237、字的论文,半个学期的努力,一点一滴的积累,感觉自己慢慢地走进了这个全新的世界,也有很大的收获.当然这是一个比较长的过程.但是在每天的研究中,我也渐渐对这方面的研究产生了浓厚的兴趣.我想在这里我首先要感谢我的老师冯志勇能在百忙之中抽出时间对我进行的指导,并为我的研究提出各种宝贵的意见,以及对我生活上的关心.冯老师在学习上给我的建议使我收益匪浅.冯老师深厚的科研功底确实是值得我们这些学生好好学习的. 当然我还要感谢我的师兄蒋威,感谢他在这半学期来对我的指导以及对我生活上的关心.每当我有问题的时候,他都耐心的给我讲解,并给我提出许多宝贵的意见.最后还要感谢我的父母在这段时间对我的鼓励和支持. 王兴华
238、 2004 年 6 月于天津大学 天津大学 2004 届本科生毕业设计(论文) setup() Agent 是否被杀死(即 doDelete()是否被调用) 从可执行(active)行为池中获取下一个行为 b.action() b.done() 把当前行为从可运行行为池中删除 takeDown() 是 否 否 是 初始化 添加一些初始的行为 红色标记的方法是需要由程序员来补充的 行为的执行 一些清除操作 A1 A2 分布式 JADE 运行环境 发送消息 准备向 A2 发送的消息 把消息放到 A2 的消息队列中 从消息队列中取消息 并进行处理 A1:-服务 X -服务 Y A2:-服务 Z A3:-服务 W -服务 K -服务 H A3 A2 A1 A6 A5 A4 公布提供的服务 搜索需要的服务 进行需要的服务