複数のエージェントが協調動作するためには,何らかの協調プロトコルが必要となります.本節では,契約ネットプロトコル(Contract Net Protocol: CNP)と呼ばれる協調プロトコルを用いたエージェントについて説明します.
教科書p.90 "3.7 適切なエージェントを探して協調する" の内容に相当します.
ホテル | エージェント | 宿泊料金 | 朝食の有無 | 駅から徒歩 |
---|---|---|---|---|
X | Hotel_X | 8,000円 | あり | 10分 |
Y | Hotel_Y | 10,000円 | あり | 5分 |
Z | Hotel_Z | 5,000円 | なし | 7分 |
public class Manager extends TAG { def loop(msg) { if (msg._p=='request-information' && msg.charge!=null && msg.toho!=null && msg.breakfast!=null) { // 徒歩と朝食の条件を3つのエージェントに送信し,全ての返事を待つ def replies = request(['Hotel_X', 'Hotel_Y', 'Hotel_Z'], [_p:'request-bid', toho:msg.toho, breakfast:msg.breakfast]) def bids = replies.findAll{it._p == 'bid'} // bidだけを集める if (msg.charge=='cheap') { def m = bids.min{it.charge} // 料金が最低なbidを選ぶ reply(m, [_p:'award', msg:m]) reply(msg, [_p:'inform', msg:m]) } } else { reply(msg, [_p:'sorry', msg:msg]) } } }
replies
に格納します.bids
に格納します.bids
の中から料金が最小の bid メッセージをm
に格納し,class Hotel_X extends TAG { def info = [charge:8000, toho:10, breakfast:'yes'] // 料金8000円,徒歩10分, 朝食あり def loop(msg) { if (msg._p=='request-bid' && msg.toho!=null && msg.breakfast!=null) { if (msg.toho >= info.toho && msg.breakfast == info.breakfast) { reply(msg, [_p:'bid', charge:info.charge, toho:info.toho, breakfast:info.breakfast]) } else { reply(msg, [_p:'giveup']) } } else if (msg._p=='award') { println("award:" + msg) } else { reply(msg, [_p:'sorry', msg:msg]) } } }
class Hotel_Y extends Hotel_X { def setup() { info = [charge:10000, toho:5, breakfast:'yes'] // 料金10000円,徒歩5分, 朝食あり } }
info
以外はHotel_Xと同じなので,Hotel_Xのサブクラスとして定義します.setup()
でinfo
の値を再設定しています.class Hotel_Z extends Hotel_X { def setup() { info = [charge:5000, toho:7, breakfast:'no'] // 料金5000円,徒歩7分, 朝食なし } }
info
以外はHotel_Xと同じなので,Hotel_Xのサブクラスとして定義します.setup()
でinfo
の値を再設定しています.[_p:'request-information', charge:'cheap', toho:10, breakfast:'yes']
を送信します.これは,次のホテルを探しているという意味です.
[_p:'request-bid', toho:msg.toho, breakfast:msg.breakfast]
をタスク通知として3つのホテルエージェントに送信します.エージェント | メッセージ | 意味 |
---|---|---|
Hotel_X | [_p:'bid', charge:8000, toho:10, breakfast:'yes'] | 料金8,000円,徒歩10分,朝食付き |
Hotel_Y | [_p:'bid', charge:10000, toho:5, breakfast:'yes'] | 料金10,000円,徒歩5分,朝食付き |
Hotel_Z | [_p:'giveup'] | 条件を満たすことができません |
[_p:'request-information', charge:'cheap', toho:10, breakfast:'yes']
を送信したときにaward を受け取れるHotel_Wを作成してみましょう.