分割統治法 (devide and conquer method)を行うエージェントについて説明します.次の手順で問題解決をします.
教科書p.73 "3.5 問題の処理手順を考える" の内容に相当します.
(3.2節と同じ)
class ODB_iwate extends ODB_aomori { def setup() { onsenlist = [ [name:'金田一温泉', type:'単純泉', city:'二戸市', point:50], [name:'奥中山温泉', type:'ナトリウム炭酸水素塩泉', city:'一戸町', point:70], [name:'田山温泉', type:'アルカリ性単純泉', city:'安代町', point:60] ] } }
onsenlist
以外はODB_aomoriと同じなので,ODB_iwateはODB_aomoriのサブクラスとして定義しています.extends
の後ろにクラス名を記述することで,そのクラスのサブクラスとして定義できます.class ODB_akita extends ODB_aomori { def setup() { onsenlist = [ [name:'大葛温泉', type:'カルシウム硫酸塩泉', city:'比内町', point:50], [name:'雪沢温泉', type:'硫酸塩泉', city:'大館市', point:70], [name:'湯ノ沢温泉', type:'アルカリ性単純泉', city:'森吉町', point:100] ] } }
class Searcher extends TAG { def loop(msg) { if (msg._p=='request-information' && msg.ninkiOnsen=='tohoku') { // 3つのエージェントにrequest-informationを送信し,全ての返事を待つ def replies = request(['ODB_aomori', 'ODB_iwate', 'ODB_akita'], [_p:'request-information', point:'max']) replies.each{println it} // requestの返事を表示する def maxpoint = replies.max{it.point} // repliesの中からpointが最大の要素を探す reply(msg, maxpoint) } else { reply(msg, [_p:'sorry', msg:msg]) } } }
request()
の第1引数にエージェント名のリストを指定すると,それら全てに第2引数で指定したメッセージを送ります.その後,全てのエージェントから返答があるまで,そこで停止します.replies
はリストです.要素はエージェントからの返答メッセージです.リストに対しては,次の操作を行えます.
replies.each{println it}
: replies
の要素それぞれを表示します.replies.max{it.point}
: replies
の要素の属性point
に着目して,その値が最大の要素を返します.[_p:'request-information', ninkiOnsen:'tohoku']
を送ると,次のデータが返ってきます:[_p:'inform', name:'湯ノ沢温泉', type:'アルカリ性単純泉', city:'森吉町', point:100, _f:'Searcher']
新しく作成するエージェント名.groovy
と入力しますtohoku
という地域名で検索していますが,例えば[_p:'request-information', ninkiOnsenFrom:['akita', 'aomori']]
のように県名を指定できるようにしてみましょう.次のどちらかでGroovyのREPL環境を開くことができます.小さいプログラム片を試すときに便利です.
(1) Webアプリ
https://groovyconsole.appspot.com/ を開きます.
上方にコードを記述して éxecute script を押すと実行結果が表示されます.
(2) Groovy Console
$ java -cp tagserver.jar groovy.ui.Console
-cp
に続けてtagserver.jar
の場所を指定してくださいdef list = ['akita', 'aomori'] def agent = [] list.each{agent.add('ODB_'+it)} print agent