《关于多代理系统的研究》03
来源:互联网 发布:淘宝日本直邮是真的吗 编辑:程序博客网 时间:2024/05/21 02:52
本篇介绍如何实现多代理系统的Goal。
1. Goals的简单介绍
面向Goal的编程是Agent Programming的一个核心概念。它表示一个Agent把自己托付给一个托管者,尝试所有的可能性来实现目标。Goal的分类为四种。
1. achieve goal:比如飞机着落。这个Agent会尝试所有的Plans,直到飞机安全着落。否则是没有机会去尝试其他的可能性,造成飞机坠毁。这种就是Agent必须要到达某种事物的状态。
2. query goal:顾名思义就是要查询某个目标,检索某些信息。比如清洁工Agent,无时不刻在寻找垃圾这个目标。
3. maintain goal:维持目标。一直使事物能够保持某种状态。比如核反应堆。当反应的状态不满足的时候,就会调用相应的Plan来维持这种状态。
4. perform goal:Agent必须要执行的某个动作。比如边境官兵的巡逻,只有执行巡逻这个动作,才能保证边疆的安全。
从这些生活中得例子可以看出,多代理的应用在我们的生活中,无处不在。只有从生活中得例子得到启发,才能从理论上更好的改进提升我们的生活空间。
那么,Goal的表示方法有几种呢?
1. 内部类:如果一个Goal是某个Agent的私有物,比人是不可以也不能用到的话,那么就是用内部类。简单并且方便参数的传递。
2. 类:这个Goal没有直接的联系与某个agent。
2. 开始使用Goal
是用Goal作为内部类。添加@Goal标记。
package a1;import java.util.HashMap;import java.util.Map;import jadex.bdiv3.BDIAgent;import jadex.bdiv3.annotation.Belief;import jadex.bdiv3.annotation.Goal;import jadex.bdiv3.annotation.Plan;import jadex.bdiv3.annotation.Trigger;import jadex.micro.annotation.Agent;import jadex.micro.annotation.AgentBody;import jadex.micro.annotation.AgentCreated;import jadex.micro.annotation.Description;@Agent@Description("<h1>Translate English to Chinese</h1>")// @Plans(@Plan(body=@Body(TranslatePlan.class)))public class TranslateEngChBDI { @Agent protected BDIAgent translateAgent; @Belief protected Map<String, String> wordTable; @AgentCreated public void init() { this.wordTable = new HashMap<String, String>(); // add some examples of word pairs wordTable.put("milk", "牛奶"); wordTable.put("banana", "香蕉"); wordTable.put("school", "学校"); wordTable.put("teacher", "老师"); wordTable.put("science", "科学"); } @Goal public class TranslateEngCh { protected String eword; protected String cword; public TranslateEngCh(String eword) { this.eword = eword; } public String getEword() { return eword; } public void setEword(String eword) { this.eword = eword; } public String getCword() { return cword; } public void setCword(String cword) { this.cword = cword; } } @Plan(trigger = @Trigger(goals = TranslateEngCh.class)) public void translateEngChPlan(TranslateEngCh goal) { goal.setCword(wordTable.get(goal.getEword())); } @AgentBody public void body() { String ewordString = "school"; TranslateEngCh goal = (TranslateEngCh) translateAgent.dispatchTopLevelGoal( new TranslateEngCh(ewordString)).get(); System.out.println("翻译结果:" + ewordString + "--->" + goal.getCword()); }}
goal定义完成之后,是被agent来调用的。为了实现这个goal,那么就需要有Plan来支持,最终完成某个目的。
记住两点:
1. agent.dispatchTopLevelGoal();
2. 调用goal以后,需要Plan来对goal进行处理。
上述程序的结果,显示为了达成某个目标,定义Plan来处理goal。
这里我们是用了类的get和set方法来操作goal的成员变量。如何能够实现在类的外部直接对成员变量进行操作呢?
3. 使用Goal的参数和结果(optionally)
使用目标的参数和结果能够节省很多代码。并且保证目标的安全性。
主要的实现形式为:@GoalParameter 和@GoalResult
package a1;import java.util.HashMap;import java.util.Map;import jadex.bdiv3.BDIAgent;import jadex.bdiv3.annotation.Belief;import jadex.bdiv3.annotation.Goal;import jadex.bdiv3.annotation.GoalParameter;import jadex.bdiv3.annotation.GoalResult;import jadex.bdiv3.annotation.Plan;import jadex.bdiv3.annotation.Trigger;import jadex.micro.annotation.Agent;import jadex.micro.annotation.AgentBody;import jadex.micro.annotation.AgentCreated;import jadex.micro.annotation.Description;@Agent@Description("<h1>Translate English to Chinese</h1>")// @Plans(@Plan(body=@Body(TranslatePlan.class)))public class TranslateEngChBDI { @Agent protected BDIAgent translateAgent; @Belief protected Map<String, String> wordTable; @AgentCreated public void init() { this.wordTable = new HashMap<String, String>(); // add some examples of word pairs wordTable.put("milk", "牛奶"); wordTable.put("banana", "香蕉"); wordTable.put("school", "学校"); wordTable.put("teacher", "老师"); wordTable.put("science", "科学"); } @Goal public class TranslateEngCh { @GoalParameter protected String eword; @GoalResult protected String cword; public TranslateEngCh(String eword) { this.eword = eword; } } @Plan(trigger = @Trigger(goals = TranslateEngCh.class)) public String translateEngChPlan(String ewordString) { return wordTable.get(ewordString); } @AgentBody public void body() { String ewordString = "school"; String chString = (String) translateAgent.dispatchTopLevelGoal(new TranslateEngCh(ewordString)).get(); System.out.println("翻译结果:" + ewordString + "--->" + chString); }}
get()方法的作用是返回异步计算的结果,也就是翻译以后的结果。
4. Goal的Retry
从上述的例子中不难发现,goal其实和Plan是没有什么区别的。相反,goal使用起来还是比较麻烦,因为需要Plan来处理一下。但是goal的唯一好处就是,当使用比较复杂的goal的时候,只需要考虑目标即可,不需要去考虑实现的过程。讲目标分解为n多个plan来实现。不过目前所接触到的问题,都是比较小的规模,不需要尝试不同的plan。但是还是举一个比较小的例子来说明一下。
package a1;import java.util.HashMap;import java.util.Map;import jadex.bdiv3.BDIAgent;import jadex.bdiv3.annotation.Belief;import jadex.bdiv3.annotation.Goal;import jadex.bdiv3.annotation.GoalParameter;import jadex.bdiv3.annotation.GoalResult;import jadex.bdiv3.annotation.Plan;import jadex.bdiv3.annotation.Trigger;import jadex.bdiv3.runtime.impl.PlanFailureException;import jadex.micro.annotation.Agent;import jadex.micro.annotation.AgentBody;import jadex.micro.annotation.AgentCreated;import jadex.micro.annotation.Description;@Agent@Description("<h1>Translate English to Chinese</h1>")// @Plans(@Plan(body=@Body(TranslatePlan.class)))public class TranslateEngChBDI { @Agent protected BDIAgent translateAgent; @Belief protected Map<String, String> wordTable; @AgentCreated public void init() { this.wordTable = new HashMap<String, String>(); // add some examples of word pairs wordTable.put("milk", "牛奶"); wordTable.put("banana", "香蕉"); wordTable.put("school", "学校"); wordTable.put("teacher", "老师"); wordTable.put("science", "科学"); } @Goal public class TranslateEngCh { @GoalParameter protected String eword; @GoalResult protected String cword; public TranslateEngCh(String eword) { this.eword = eword; } } @Plan(trigger = @Trigger(goals = TranslateEngCh.class)) public String translateEngChPlanA(String ewordString) { System.err.println("Plan A"); throw new PlanFailureException(); //return wordTable.get(ewordString); } @Plan(trigger = @Trigger(goals=TranslateEngCh.class)) public String translateEngChPlanB(String ewordsString){ System.out.println("Plan B"); return wordTable.get(ewordsString); } @AgentBody public void body() { String ewordString = "school"; String chString = (String) translateAgent.dispatchTopLevelGoal( new TranslateEngCh(ewordString)).get(); System.out.println("翻译结果:" + ewordString + "--->" + chString); }}
小的改动,就是增加了另外一个Plan,然后手动使第一个Plan处于失效状态。这样本着能够达到目的的原则,还是去寻找其他的Plan。最终能够完成goal。
5. Goal Creation Condition
package a1;import java.util.HashMap;import java.util.Map;import jadex.bdiv3.BDIAgent;import jadex.bdiv3.annotation.Belief;import jadex.bdiv3.annotation.Goal;import jadex.bdiv3.annotation.GoalCreationCondition;import jadex.bdiv3.annotation.GoalParameter;import jadex.bdiv3.annotation.GoalResult;import jadex.bdiv3.annotation.Plan;import jadex.bdiv3.annotation.Trigger;import jadex.micro.annotation.Agent;import jadex.micro.annotation.AgentBody;import jadex.micro.annotation.AgentCreated;import jadex.micro.annotation.Description;@Agent@Description("<h1>Translate English to Chinese</h1>")// @Plans(@Plan(body=@Body(TranslatePlan.class)))public class TranslateEngChBDI { @Agent protected BDIAgent translateAgent; @Belief protected String eword; @Belief protected Map<String, String> wordTable; @AgentCreated public void init() { this.wordTable = new HashMap<String, String>(); // add some examples of word pairs wordTable.put("milk", "牛奶"); wordTable.put("banana", "香蕉"); wordTable.put("school", "学校"); wordTable.put("teacher", "老师"); wordTable.put("science", "科学"); } @Goal public class TranslateEngCh { @GoalParameter protected String eword; @GoalResult protected String cword; @GoalCreationCondition(beliefs = "eword") public TranslateEngCh(String eword) { this.eword = eword; } } @Plan(trigger = @Trigger(goals = TranslateEngCh.class)) public String translateEngChPlan(String ewordsString) { System.out.println("Plan executing"); return wordTable.get(ewordsString); } @AgentBody public void body() { eword = "laoshi"; eword = "kexue"; }}
上述代码的主要是为了说明,当Belief改变的时候,我们可以创建新的goal。但是感觉原作者对这点功能讲解的不是很好。
6. 简单介绍一下Goal的重复尝试和Maintain Goal
这种方法-目的的推理过程是开始于goal的。这个agent会一直执行所有的plan,知道执行完毕以后成功或者仍旧没有成功,如果仍旧没有成功的话,程序会继续执行plans,直到成功。但是这种是有弊端的。容易造成程序的死锁。 所以默认情况下,这种重复recur是set为false的。如果有需要的话,可以进一步的学习。
关于maintaingoal的用法,这里也不再多做介绍。
总结:关于goal的用法,其实就是使用内部类。单独的一个外部类,作为goal来使用,不是很常见的。可能会根据接触的项目大小,用到的知识可能会比较多。对于目前我的项目来说,使用goal与不使用goal都是一样的。只需要Agent和Plans即可。当然,也可能是设计上有一定的问题,今后对系统进行慢慢的改进。
- 《关于多代理系统的研究》03
- 《关于多代理系统的研究》01
- 《关于多代理系统的研究》02
- 《关于多代理系统的研究》04
- 《关于多代理系统的研究》05(The end)
- 关于动态代理的研究
- 关于排名系统的研究
- 关于分布式系统的研究
- 关于 【通过代理访问】 的研究,【突破 IP ,“无限制”投票】
- 关于嵌入式系统的研究方向
- [经典]关于嵌入式系统的研究方向
- 关于嵌入式系统的研究方向
- 03-关于学习方法的研究
- 不同的系统下,路径不同,关于路径的研究
- 不同的系统下,路径不同,关于路径的研究
- 关于流通系统的流失特性的研究
- 关于Mathematica系统通讯机制MathLink的研究
- 关于研究生面试系统的探索研究V
- vim+latex+\cite{}+F9 autocomplete
- C++ string 详解
- String是引用类型,和其他引用类型区别在哪里?
- 【Android】Android之单项问答题
- 什么是委托
- 《关于多代理系统的研究》03
- Android环境搭建GOOD
- 【Android】Android之多页面问答题
- C语言的历史
- 异步调用
- 浅谈字符编码
- PageSetupDialog 类的一个 BUG
- 一次程序调试小记
- 浅谈 F# 2.0 的两个运行时