3.7 契約ネットプロトコル

複数のエージェントが協調動作するためには,何らかの協調プロトコルが必要となります.本節では,契約ネットプロトコル(Contract Net Protocol: CNP)と呼ばれる協調プロトコルを用いたエージェントについて説明します.
教科書p.90 "3.7 適切なエージェントを探して協調する" の内容に相当します.

概要

%0 user user Manager Manager user->Manager request hotel information Hotel_X Hotel_X Manager->Hotel_X task-announcement, bid,award Hotel_Y Hotel_Y Manager->Hotel_Y task-announcement,bid Hotel_Z Hotel_Z Manager->Hotel_Z task-announcement

ホテル エージェント 宿泊料金 朝食の有無 駅から徒歩
X Hotel_X 8,000円 あり 10分
Y Hotel_Y 10,000円 あり 5分
Z Hotel_Z 5,000円 なし 7分

メッセージの流れ

useruserManagerManagerHotel_XHotel_XHotel_YHotel_YHotel_ZHotel_Zrequest-informationタスク通知,入札parrequest-bidbidrequest-bidbidrequest-bidgiveup落札awardinform

プログラム

Manager.groovy

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])
        }
    }
}

Hotel_X.groovy

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])
        }
    }
}

Hotel_Y.groovy

class Hotel_Y extends Hotel_X {
    def setup() {
        info = [charge:10000, toho:5, breakfast:'yes'] // 料金10000円,徒歩5分, 朝食あり
    }
}

Hotel_Z.groovy

class Hotel_Z extends Hotel_X {
    def setup() {
        info = [charge:5000, toho:7, breakfast:'no'] // 料金5000円,徒歩7分, 朝食なし
    }
}

動作方法

エージェント メッセージ 意味
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'] 条件を満たすことができません

課題

  1. Hotel_Zがaward を受け取るには,userはManagerにどのようなメッセージを送ればいいのかを考えてみましょう.
  2. userがManagerに[_p:'request-information', charge:'cheap', toho:10, breakfast:'yes']を送信したときにaward を受け取れるHotel_Wを作成してみましょう.

エージェントプログラムの新規登録