JADE学习笔记【1】


JADE Agent 类可以不包含main()函数,但是必须包含setup()函数,由setup()来启动Agent并完成一些初始化工作。

Agent运行命令解析

Agent运行命令解析:java jade.Boot [options] [AgentSpecifier list]

Options含义
-container表明Agent运行时将启动一个外部容器,Agent生存在这个容器下,这个容器必须在主容器中注册
-guiJADE的RMA图形界面将被打开
-port指明主容器运行的端口号,缺省端口号为1099,知名端口号后,一台机器上可以启动多个主容器,例如java jade.Boot -gui -port 1088
-container-name给容器命名。例如,第一次启动,输入:java jade.Boot -gui-container-name yuyu,则将主容器命名为yuyu,再打开一个命令窗口,输入java jade.Boot -gui-container-container-name haha,则将新启动的外围容器命名为haha
-platform-id该选项为Agent平台命名,将默认的平台标识符命名为用户喜欢的标识符
-name作用同-platform-id

[AgentSpecifier list]定义启动的Agent列表,其中AgentSpecifier的形式为:AgentName:ClassName,ClassName中必须指出包名。可以启动多个Agent,每个Agent之间用;分隔。

熟悉Agent标识符

Agent类的getAID()用来获取本地Agent的标识符。Agent标识符由全局唯一标识(GUID)和平台地址组成。GUID命名形式为< local-name >@< platform-name >。AID中包含的地址是
Agent所在平台的地址,这些地址在该agent与其他平台上的Agent通信时使用。
AID类提供了获取Agent本地名称、标识符、地址等一系列方法。如getLocalName()、getName()、getAllAddresses()

package MyFirstAgent;

import jade.core.Agent;

import java.util.Arrays;
import java.util.Iterator;

public class DemoAgent extends Agent {
    @Override
    protected  void  setup(){
        System.out.println("AgentOne的AID:"+getAID());
        System.out.println("AgentOne的local-name:"+getAID().getLocalName());
        System.out.println("AgentOne的GUID:"+getAID().getName());
        Iterator it=getAID().getAllAddresses();
        while (it.hasNext())
        {
            System.out.println("-"+it.next());
        }
    
    }
}
输出:
E:\Develop\Java\jdk-12.0.2\bin\java.exe -Didea.launcher.port=2275 "-Didea.launcher.bin.path=E:\intellij idea2018\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "E:\学习笔记\yuguo\target\classes;E:\intellij idea2018\IntelliJ IDEA 2018.2.4\plugins\maven\repository\com\tilab\jade\jade\4.5.0\jade-4.5.0.jar;E:\intellij idea2018\IntelliJ IDEA 2018.2.4\plugins\maven\repository\commons-codec\commons-codec\1.3\commons-codec-1.3.jar;E:\intellij idea2018\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMainV2 jade.Boot -gui AgentOne:MyFirstAgent.DemoAgent
704, 2020 3:55:04 下午 jade.core.Runtime beginContainer
信息: ----------------------------------
    This is JADE 4.5.0 - revision 6825 of 23-05-2017 10:06:04
    downloaded in Open Source, under LGPL restrictions,
    at http://jade.tilab.com/
----------------------------------------
704, 2020 3:55:04 下午 jade.imtp.leap.LEAPIMTPManager initialize
信息: Listening for intra-platform commands on address:
- jicp://172.168.1.142:1099

704, 2020 3:55:05 下午 jade.core.BaseService init
信息: Service jade.core.management.AgentManagement initialized
704, 2020 3:55:05 下午 jade.core.BaseService init
信息: Service jade.core.messaging.Messaging initialized
704, 2020 3:55:05 下午 jade.core.BaseService init
信息: Service jade.core.resource.ResourceManagement initialized
704, 2020 3:55:05 下午 jade.core.BaseService init
信息: Service jade.core.mobility.AgentMobility initialized
704, 2020 3:55:05 下午 jade.core.BaseService init
信息: Service jade.core.event.Notification initialized
704, 2020 3:55:05 下午 jade.mtp.http.HTTPServer <init>
信息: HTTP-MTP Using XML parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
704, 2020 3:55:05 下午 jade.core.messaging.MessagingService boot
信息: MTP addresses:
http://PC-20191102IUIM:7778/acc
704, 2020 3:55:05 下午 jade.core.AgentContainerImpl joinPlatform
信息: --------------------------------------
Agent container Main-Container@172.168.1.142 is ready.
--------------------------------------------
AgentOne的AID:( agent-identifier :name AgentOne@172.168.1.142:1099/JADE  :addresses (sequence http://PC-20191102IUIM:7778/acc ))
AgentOne的local-name:AgentOne
AgentOne的GUID:AgentOne@172.168.1.142:1099/JADE
-http://PC-20191102IUIM:7778/acc

通过以下的方式获得已知本地名称Agent的AID:

String localname = "Peter";

AID id =new AID (localname,AID.ISLOCALNAME);

类似的已知Agent的GUID后,我们可以用如下的方式获得其AID

String guid = "Peter@foo-platform";
AID id = new AID(guid,AID.ISGUID);

可以向Agent传递参数:

在这里插入图片描述

System.out.println("My arguments are:");
        Object[] args = getArguments();
        if (args!=null){
            for (int i = 0; i < args.length; i++) {
                System.out.println("-"+args[i]);
            }
        }

Agent终止:

takeDown()方法清理,doDelete()终止

为Agent添加行为

setup()方法执行后,Agent就在AMS中注册成功。它的实际工作任务通常在所添加的行为Behaviour中执行,也就是说,一个活动的Agent相当于一个完成任务的主体,而真正的任务载体时Behaviour类的实例。
每一个Behaviour都是jade.core.behaviours.Behaviours类的子类,一个Behaviour可以嵌套另一个Behaviour。在Agent生命周期的任何时刻都可以调用Behaviour执行某种任务,方法是使用Agent类的addBehaviout(Behaviour)方法。而且要实现两个抽象方法:action()done()action()中定义Agent需要实现的任务;done()方法返回一个布尔值来判断这个Behaviour是否完成其任务,是否应该将其移出其所在的Agent所管理的行为队列,每个Agent可与i并行执行多个Behaviour。
编写一个FirstBehaviour类,将类添加到Agent的行为队列中

package MyFirstAgent;

import jade.core.behaviours.Behaviour;

public class FirstBehaviour extends Behaviour {
   private int numA=5;
   @Override
   public boolean done() {
       return true;
   }
   @Override
   public void action() {
       if ((numA%2)!=0){
           System.out.println("numA is an odd number");
       }
       else {
           System.out.println("numA is an even number");
       }
   }
}

package MyFirstAgent;

import jade.core.Agent;

import java.util.Arrays;
import java.util.Iterator;

public class DemoAgent extends Agent {
    @Override
    protected  void  setup(){
        //添加行为
        this.addBehaviour(new FirstBehaviour());
    }
}

与其他Agent通信

基本原理

JADE中的Agent之间的通信基于异步通信模式。
每一个JADE Agent都有一个邮箱,即Agent消息队列,其他Agent发送来的信息都投入到这个邮箱中。一旦邮箱中收到消息,系统会给Agent发出通知,由程序元编写程序让Agent有选择地处理消息。
遵循FIPA规范,JADE Agent之间地通信所交换地是ACL消息,每一条消息都是继承了JADE.lang.acl.ACLMessage类的一个对象,包含了由FIPA规范制定的一系列消息属性,主要消息域如下:

  1. 消息的发送者;
  2. 消息接收者列表;
  3. 消息原语,如REQUEST原语表示发送方请求接收方执行某种操作;
  4. 消息的具体内容;
  5. 用来表达消息内容的语言,如English;
  6. 用来说明消息内容中某些词汇或短语的本体Ontology;
  7. 其他。
    准备发送消息的Agent应该创建一个新的ACLMessage对象,给他的属性赋予适当的值,然后调用Agent.send()方法发送消息。同样地,一个准备接收消息的Agent可以调用receive()或者blockingReceive()方法接收消息。

发送消息

发送消息就是填写好ACLMessage对象的各个域,然后调用Agent类的send()方法。
本例中让DemoAgent类的一个Agent实例作为信息发送方,让他向另一个运行时名字为alice的Agent发送信息,通知Alice明天考试。

  1. 编写一个发送消息的行为类,在Behaviour类的子类SendBehaviour中编写发送消息的代码,而发送消息的send()方法的主体是Agent,而不是Behaviour,需要在SendBehaviour的构造函数中将SengBehaviour与DemoAgent类关联起来。
package MyFirstAgent;

import jade.core.AID;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.ACLMessage;

public class SendBehaviour extends Behaviour {
    private DemoAgent sendagent=null;
        @Override
    public void action() {
            ACLMessage msg=new ACLMessage(ACLMessage.INFORM);
            msg.addReceiver(new AID("Alice",AID.ISLOCALNAME));
            msg.setLanguage("English");
            msg.setContent("There will be an examination tomorrow");
            sendagent.send(msg);
    }
    @Override
    public boolean done() {
        return true;
    }
    public SendBehaviour(DemoAgent a){
            sendagent=a;
    }
}
  1. 修改setup()方法,添加SendBehaviour
package MyFirstAgent;

import jade.core.Agent;

import java.util.Arrays;
import java.util.Iterator;

public class DemoAgent extends Agent {
    @Override
    protected  void  setup(){
       this.addBehaviour(new SendBehaviour(this));
    }
}

接收消息

由于运行时,Agent的实例在时刻监听发送给它的消息,一次性行为不适合处理消息的实时接收,所以,在消息接收时,我们使用了可以处理循环操作的特殊的Behaviour类:CyclicBehaviour

package MyFirstAgent;

import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;

public class DemoAgentSecond extends Agent {
    @Override
    protected void setup() {
        Behaviour loop=new CyclicBehaviour() {
            @Override
            public void action() {
                ACLMessage msg=receive();
                if(msg!=null){
                    System.out.println("I received this message:"+msg.getContent());
                }
            }
        };
        this.addBehaviour(loop);
    }
}

从代码的形式上看是写在同一个文件中,但实际上编译的时候仍会产生两个.class文件,一个对应Agent,一个对应CyclicBehaviour。
同时运行两个Agent输出:

I received this message:There will be an examination tomorrow
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值