[1] | 1 | package agents.anac.y2016.atlas3.etc;
|
---|
| 2 |
|
---|
| 3 | import genius.core.Bid;
|
---|
| 4 | import genius.core.utility.AbstractUtilitySpace;
|
---|
| 5 |
|
---|
| 6 | public class negotiationStrategy {
|
---|
| 7 | private AbstractUtilitySpace utilitySpace;
|
---|
| 8 | private negotiationInfo negotiationInfo;
|
---|
| 9 |
|
---|
| 10 | private double df = 1.0; // 割引係数
|
---|
| 11 | private double rv = 0.0; // 留保価格
|
---|
| 12 |
|
---|
| 13 | private double A11 = 0.0; // 効用値・・・A:強硬戦略,B:強硬戦略
|
---|
| 14 | private double A12 = 0.0; // 効用値・・・A:強硬戦略,B:妥協戦略
|
---|
| 15 | private double A21 = 0.0; // 効用値・・・A:妥協戦略,B:強硬戦略
|
---|
| 16 | private double A22 = 0.0; // 効用値・・・A:妥協戦略,B:妥協戦略
|
---|
| 17 |
|
---|
| 18 | static private double TF = 1.0; // 最終提案フェーズの時刻
|
---|
| 19 | static private double PF = 0.5; // 最終提案フェーズにおいて互いのが妥協戦略を選択した場合に,自身が相手よりも先に譲歩する確率
|
---|
| 20 |
|
---|
| 21 | private boolean isPrinting = false;
|
---|
| 22 |
|
---|
| 23 | public negotiationStrategy(AbstractUtilitySpace utilitySpace,
|
---|
| 24 | negotiationInfo negotiationInfo, boolean isPrinting) {
|
---|
| 25 | this.utilitySpace = utilitySpace;
|
---|
| 26 | this.negotiationInfo = negotiationInfo;
|
---|
| 27 | this.isPrinting = isPrinting;
|
---|
| 28 | df = utilitySpace.getDiscountFactor();
|
---|
| 29 | rv = utilitySpace.getReservationValue();
|
---|
| 30 |
|
---|
| 31 | if (this.isPrinting) {
|
---|
| 32 | System.out.println("negotiationStrategy:success");
|
---|
| 33 | }
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | // 受容判定
|
---|
| 37 | public boolean selectAccept(Bid offeredBid, double time) {
|
---|
| 38 | try {
|
---|
| 39 | double offeredBidUtil = utilitySpace.getUtility(offeredBid);
|
---|
| 40 | if (offeredBidUtil >= getThreshold(time)) {
|
---|
| 41 | return true;
|
---|
| 42 | } else {
|
---|
| 43 | return false;
|
---|
| 44 | }
|
---|
| 45 | } catch (Exception e) {
|
---|
| 46 | System.out.println("受容判定に失敗しました");
|
---|
| 47 | e.printStackTrace();
|
---|
| 48 | return false;
|
---|
| 49 | }
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | // 交渉終了判定
|
---|
| 53 | public boolean selectEndNegotiation(double time) {
|
---|
| 54 | // 閾値が留保価格を下回るとき交渉を放棄
|
---|
| 55 | if (utilitySpace.discount(rv, time) >= getThreshold(time)) {
|
---|
| 56 | return true;
|
---|
| 57 | } else {
|
---|
| 58 | return false;
|
---|
| 59 | }
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | // 割引後の効用値から割引前の効用値を導出する
|
---|
| 63 | public double pureUtility(double discounted_util, double time) {
|
---|
| 64 | return discounted_util / Math.pow(df, time);
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | // 閾値を返す
|
---|
| 68 | public double getThreshold(double time) {
|
---|
| 69 | double threshold = 1.0;
|
---|
| 70 | updateGameMatrix(); // ゲームの表を更新する
|
---|
| 71 |
|
---|
| 72 | double target = pureUtility(getExpectedUtilityinFOP(), time);
|
---|
| 73 |
|
---|
| 74 | // 最終提案フェーズの期待効用に基づき,譲歩を行う
|
---|
| 75 | if (utilitySpace.discount(1.0, time) == 1.0) {
|
---|
| 76 | threshold = target + (1.0 - target) * (1.0 - time);
|
---|
| 77 | } else {
|
---|
| 78 | threshold = Math.max(1.0 - time / utilitySpace.discount(1.0, time),
|
---|
| 79 | target);
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | // デバッグ用
|
---|
| 83 | if (isPrinting) {
|
---|
| 84 | System.out.println("threshold = " + threshold + ", opponents:"
|
---|
| 85 | + negotiationInfo.getOpponents());
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | return threshold;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | // 最終提案フェイズの混合戦略の期待効用
|
---|
| 92 | private double getExpectedUtilityinFOP() {
|
---|
| 93 | double q = getOpponentEES();
|
---|
| 94 | return q * A21 + (1 - q) * A22;
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | // 最終提案ゲームにおける最適混合戦略の均衡点での,相手の混合戦略(p,1.0-p)=(強硬戦略を選択する確率,妥協戦略を選択する確率)を導出する
|
---|
| 98 | private double getOpponentEES() {
|
---|
| 99 | double q = 1.0;
|
---|
| 100 | if ((A12 - A22 != 0) && (1.0 - (A11 - A21) / (A12 - A22) != 0)) {
|
---|
| 101 | q = 1.0 / (1.0 - (A11 - A21) / (A12 - A22));
|
---|
| 102 | }
|
---|
| 103 | if (q < 0.0 || q > 1.0) {
|
---|
| 104 | q = 1.0;
|
---|
| 105 | }
|
---|
| 106 | return q;
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | // ゲームの表を更新する
|
---|
| 110 | private void updateGameMatrix() {
|
---|
| 111 | double C; // 妥協案の推定効用値
|
---|
| 112 | if (negotiationInfo.getNegotiatorNum() == 2) {
|
---|
| 113 | C = negotiationInfo.getBOU();
|
---|
| 114 | } else {
|
---|
| 115 | C = negotiationInfo.getMPBU();
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | A11 = utilitySpace.discount(rv, 1.0);
|
---|
| 119 | A12 = utilitySpace.discount(1.0, TF);
|
---|
| 120 | if (C >= rv) {
|
---|
| 121 | A21 = utilitySpace.discount(C, TF);
|
---|
| 122 | } else {
|
---|
| 123 | A21 = utilitySpace.discount(rv, 1.0);
|
---|
| 124 | }
|
---|
| 125 | A22 = PF * A21 + (1.0 - PF) * A12;
|
---|
| 126 | }
|
---|
| 127 | }
|
---|