概述
作为一名软件开发人员,我相信大家都对面向对象技术有个比较深刻的认识。面向对象技术的确为提高软件开发效率做出了巨大的贡献。但是在我们的开发过程中,面向对象也暴露了一些不足,其中最主要的不足可以归纳为:面向对象技术并不是对现实世界的最贴切的模拟。既然出现了不足,那么在这种特定的背景下,必然会出现一种软件开发理论和技术来解决软件开发中的问题。这就是智能体Agent。本文首先介绍一下智能体的基本概念,然后开发了一个应用程序演示了利用智能体开发平台JADE来开发多智能体系统的过程。
智能体简介
所谓智能体是指驻留在某一环境下能够自主(autonomous)﹑灵活(flexible)地执行动作以满足设计目标的行为实体。针对上述定义,下面对智能体的概念作进一步分析:
1. 智能体驻留在环境中并需要与环境进行交互
任何智能体都不是孤立和封闭的,它驻留在一定的环境之中,需要与环境持续不断地进行交互。图1给出了智能体与环境交互的抽象视图。
图1
2. 智能体是行为实体
智能体是一个行为实体,它具有一组动作并能执行这些动作,是动作执行的决策者和实施者。智能体的动作反应了其所具有的能力,这种能力主要体现在:智能体动作的实施有助于实现其设计目标并对其所驻留的环境产生影响。
3. 智能体能够自主地实施行为
智能体具有属于其自身的计算资源和局部于自身的行为控制机制,能在没有人类或其他智能体的直接干涉和指导的情况下运行,并能根据其内部状态和感知到的环境输入决定自身的状态,控制自身的行为。
4. 智能体有其设计目标
系统中的每个智能体都有其特定的设计目标。在其生命周期和持续运行过程中,智能体根据其设计目标和感知到的环境输入自主地决定自身行为。所以智能体的设计目标对其行为决策产生直接的影响。
在我们的日常现实生活中,有许多控制系统都可以视为智能体。例如,房间恒温调控系统中的恒温调节器就是一个智能体。恒温调节器智能体的设计目标是要将房间的温度维持在用户设定的范围。它驻留于物理环境(房间)之中,具有温度感应器以感知环境输入(房间的温度),并能对感知到的房间温度作出适时反应,从而影响所处的环境(调高或者降低房间的温度)。
回页首
初识JADE
JADE (Java Agent Development Framework)是一个完全由Java语言开发的一个软件框架,并且符合FIPA规范。通过这个中间件,极大地简化了我们程序员开发多智能体系统。JADE主要包括以下几个组成部分:
- 智能体赖以生存的一个运行时环境
- 程序员用来开发智能体应用的一个运行时库
- 一系列图形工具,帮助用户管理和监控运行时智能体的状态
安装
在进行一系列的开发之前,我们需要先下载并且安装JADE环境。您可以从JADE的官方网站http://jade.tilab.com/ 上下载JADE的最新版本,目前为3.4发布版本。一旦你下载完毕,请解压缩安装包,把其中lib目录下的4个jar文件放入您的ClassPath系统环境变量中。打开命令行,输入Java jade.Boot -gui,您将看到如图2所示的图形化用户界面。
图2
JADE基本概念
1. JADE平台利用容器去容纳智能体。一个平台可以有多个容器,并且这些容器可以在不同的主机上。在一个JADE平台中,有且仅有一个叫做主容器的容器。当其他的容器启动时,他们必须在主容器中注册。图3显示了在网络中,存在两个不同的JADE平台。其中一个平台由3个容器构成,另一个平台由1个容器构成。JADE智能体在平台上用独一无二的名字来标识。一旦一个智能体知道网络上另一个智能体的名字,它们便可以进行透明的通信,而不需要了解实际的位置。
图3
2. 主容器除了可以提供其他一般容器注册功能之外,它还包含了两个特殊的智能体。AMS(Agent Management System)提供一些智能体管理功能。例如:它给智能体提供命名服务,并且它也可以从容器中创建和删除智能体。DF(Directory Facilitator)提供了黄页功能。当一个智能体需要利用其他智能体提供的服务时,它便可以到DF中去查找。
回页首
一个简单的多智能体系统
这个简单的实例主要介绍的是智能体如何在DF中注册,并且对其他智能体的请求做出响应。智能体之间的具体交互过程如下:首先Ping Agent在DF中注册,等待接收ACL消息。如果接收到了QUERY_REF类型的消息,并且消息内容为"ping",那么它就用内容为"pong"的INFORM类型的消息响应。 创造JADE智能体-Agent 在JADE平台中,每个智能体都需要从其父类jade.core.Agent类派生,并且实现其setup方法。
import jade.core.Agent;
Public Class BookBuyerAgent extends Agent
{
protected void setup()
{
System.out.println("Hello! Buyer-agent "+getAID().getName()+" is ready.");
}
}
import jade.core.Agent; Public Class BookBuyerAgent extends Agent { protected void setup() { System.out.println("Hello! Buyer-agent "+getAID().getName()+" is ready."); } }
每个智能体都由一个jade.core.AID类的实例唯一标识。Agent类中的方法getAID就是用来获取智能体标识的。一个AID对象包括一个唯一的名字和一系列地址。JADE平台中智能体名字有如下格式:<nickname>@<platform-name>。
智能体任务-Behaviour
一个行为就代表了智能体能够执行的任务。在JADE中,行为必须从其父类jade.core.behaviours.Behaviour派生。为了使智能体具有某种行为,编程人员必须利用Agent类的addBehaviour方法向智能体中显示的加入。行为可以在任何时候加入到智能体中。 每个从Behaviour派生的行为类必须实现action和done方法。Action方法定义了一系列智能体执行的操作,而done方法表明行为是否结束完毕。如果done方法返回的值为真,那表示这个行为已经执行完毕,可以从智能体的行为池删除。
图4表明了智能体行为的执行方式:
图4
JADE为我们预定义了几种行为类型,主要包括:
1. jade.core.behaviours.OneShotBehaviour
这种类型的行为只执行一次,然后就从智能体的行为池中被删除。例如:
public class MyOneShotBehaviour extends OneShotBehaviour
{
public void action()
{
//perform operation X
}
}
public class MyOneShotBehaviour extends OneShotBehaviour { public void action() { //perform operation X } }
操作X仅被执行一次。
2. jde.core.behaviours.CyclicBehaviour
这种类型的行为将循环执行。
3. Generic behaviours
一般行为包含一个状态位,并且由状态位决定执行不同的操作。当满足所给定条件时,行为结束。例如:
public class MyTwoStepBehaviour extends Behaviors
{
private int step=0;
public void action()
{
switch(step)
{
case 0:
//perform operation X
step++;
break;
case 1:
//perform operation Y
step++;
break;
}
}
public Boolean done()
{
return step==2;
}
}
public class MyTwoStepBehaviour extends Behaviors { private int step=0; public void action() { switch(step) { case 0: //perform operation X step++; break; case 1: //perform operation Y step++; break; } } public Boolean done() { return step==2; } }
操作X和Y依次执行一次,然后行为结束。JADE也提供了把以上几种简单的行为组合成复杂行为的能力。例如:顺序行为SequentialBehaviour, 并发行为ParallelBehaviour和有限状态机行为FSMBehaviou。
智能体通信
JADE智能体提供的最重要的特征之一就是其通信能力。通信过程中所采用的通信模式为图5所示的异步消息传递。也就是说,每个智能体都有一个消息队列,如果其他智能体需要与其通信时,JADE runtime就把相应消息投递到其队列中。当消息队列中出现消息时,相应的智能体被通知。这时是否对消息做出响应那就是程序员的事了。
图5
1. ACL语言
智能体是通过ACL(Agent Communication Language)语言进行通信的,而ACL是由FIPA制定的智能体互操作国际标准。ACL消息格式主要包括消息发送方﹑消息接收方﹑通信原语以及消息内容。在JADE中,消息是由jade.lang.acl.ACMessage类对象表示。
2. 发送消息
在JADE中发送消息非常简单,您只需使用Agent类的send方法即可。以下代码表明了如何向别名为Peter的智能体发出通知消息,告诉其今天下雨。
ACLMessage msg=new ACLMessage(ACLMessage.INFORM);
Msg.addReceiver(new AID("Peter",AID.ISLOCALNAME));
Msg.setLanguage("English");
Msg.setContent("Today it's raining");
Send(msg);
ACLMessage msg=new ACLMessage(ACLMessage.INFORM); Msg.addReceiver(new AID("Peter",AID.ISLOCALNAME)); Msg.setLanguage("English"); Msg.setContent("Today it's raining"); Send(msg);
3. 接收消息
智能体通过receive方法就可以从其消息队列中接收消息。这个方法返回消息队列中第一条消息。如果队列为空,则返回null。
构造PingAgent 通过以上的一系列介绍,我们就开始建立PingAgent,清单一给出了部分源代码。
package examples.PingAgent;
public class PingAgent extends Agent {
class WaitPingAndReplyBehaviour extends SimpleBehaviour {
private boolean finished = false;
public WaitPingAndReplyBehaviour(Agent a) {
super(a);
}
public void action() {
ACLMessage msg = blockingReceive();
if(msg != null){
ACLMessage reply = msg.createReply();
if(msg.getPerformative()== ACLMessage.QUERY_REF){
String content = msg.getContent();
if ((content != null) && (content.indexOf("ping") != -1)){
reply.setPerformative(ACLMessage.INFORM);
reply.setContent("pong");
}
}
send(reply);
}
}else{
System.out.println("No message received");
}
}
public boolean done() {
return finished;
}
}
protected void setup() {
DFAgentDescription dfd = new DFAgentDescription();
ServiceDescription sd = new ServiceDescription();
sd.setType("AgentcitiesPingAgent");
sd.setName(getName());
sd.setOwnership("TILAB");
dfd.setName(getAID());
dfd.addServices(sd);
try {
DFService.register(this,dfd);
} catch (FIPAException e) {
System.err.println(getLocalName()+" registration with DF unsucceeded.
Reason: "+e.getMessage());
doDelete();
}
WaitPingAndReplyBehaviour PingBehaviour = new
WaitPingAndReplyBehaviour(this);
addBehaviour(PingBehaviour);
}
}
package examples.PingAgent; public class PingAgent extends Agent { class WaitPingAndReplyBehaviour extends SimpleBehaviour { private boolean finished = false; public WaitPingAndReplyBehaviour(Agent a) { super(a); } public void action() { ACLMessage msg = blockingReceive(); if(msg != null){ ACLMessage reply = msg.createReply(); if(msg.getPerformative()== ACLMessage.QUERY_REF){ String content = msg.getContent(); if ((content != null) && (content.indexOf("ping") != -1)){ reply.setPerformative(ACLMessage.INFORM); reply.setContent("pong"); } } send(reply); } }else{ System.out.println("No message received"); } } public boolean done() { return finished; } } protected void setup() { DFAgentDescription dfd = new DFAgentDescription(); ServiceDescription sd = new ServiceDescription(); sd.setType("AgentcitiesPingAgent"); sd.setName(getName()); sd.setOwnership("TILAB"); dfd.setName(getAID()); dfd.addServices(sd); try { DFService.register(this,dfd); } catch (FIPAException e) { System.err.println(getLocalName()+" registration with DF unsucceeded. Reason: "+e.getMessage()); doDelete(); } WaitPingAndReplyBehaviour PingBehaviour = new WaitPingAndReplyBehaviour(this); addBehaviour(PingBehaviour); } }
在清单1中,我们注意到PingAgent拥有一个WaitPingAndReplyBehaviour行为。这个行为的action方法很简单,它的逻辑主要是判断智能体是否收到了类型为QUERY_REF并且内容为"ping"的消息。在setup方法中,主要的操作是在DF中注册智能体。
部署运行 PingAgent
在编译 PingAgent 之前,请确保 JADE 所需的 jar 文件在您系统的 CLASSPATH 环境变量中。在命令行下定位到 PingAgent 所在目录,键入 javac examples.PingAgent.PingAgent。编译完成后,在命令行下输入 java jade.Boot -gui,出现图 2 所示的主界面,此时表明 JADE平台已经成功启动。鼠标右击图 2 左边树状的 Main-Container 项,选择 Start New Agent,出现图6所示的界面。在 Agent Name 中输入智能体的名称,在 Class Name 中输入智能体的类名,点击 OK 按钮。此时 PingAgent 已经正常启动,并且等待其它智能体的通知消息。
图6
为了模拟智能体之间的通信,我们利用 JADE 平台提供的 Dummy Agent。点击菜单 Tools,选择 Start DummyAgent,出现图7所示的界面。按照图7所示输入相应字段信息,点击工具条中的 ,此时 DummyAgent 向 PingAgent 发送了一条类型为 QUERY_REF 的ACL 消息了,并且 PingAgent 也向 DummyAgent 返回了一条 INFORM 类型的消息。
图7
回页首
总结
我希望本文已经向你展示了利用 JADE 平台构建和开发多智能体系统是多么容易。您也可以发挥您自己的想象,开发更加实用的多智能体系统。
最后
以上就是凶狠冬天为你收集整理的使用 JADE 平台进行智能体开发的全部内容,希望文章能够帮你解决使用 JADE 平台进行智能体开发所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复