[1] | 1 | package agents.anac.y2016.agenthp2;
|
---|
| 2 |
|
---|
| 3 | import java.util.HashMap;
|
---|
| 4 |
|
---|
| 5 | import genius.core.Bid;
|
---|
| 6 | import genius.core.issue.ISSUETYPE;
|
---|
| 7 | import genius.core.issue.Issue;
|
---|
| 8 | import genius.core.issue.IssueDiscrete;
|
---|
| 9 | import genius.core.issue.IssueInteger;
|
---|
| 10 | import genius.core.utility.AbstractUtilitySpace;
|
---|
| 11 |
|
---|
| 12 | /**
|
---|
| 13 | * AHP Evaluation class
|
---|
| 14 | *
|
---|
| 15 | * @author Hiroyuki Shinohara
|
---|
| 16 | * @date 2016/03/30
|
---|
| 17 | */
|
---|
| 18 | public class module_AHP {
|
---|
| 19 |
|
---|
| 20 | private int issueNum; // 効用空間の論点数
|
---|
| 21 | private AbstractUtilitySpace myUtilitySpace; // 自分の効用空間
|
---|
| 22 | private int issueElementCount[]; // 論点内の要素数
|
---|
| 23 | private HashMap<String, Integer>[][] valueCountHash; // 提案内出現回数カウント用Hash
|
---|
| 24 | private HashMap<String, Double>[][] expectUtilSpaceHash; // 予測効用空間保存用Hash
|
---|
| 25 | private double expectIssueWeightArray[][]; // 予測論点間重み保存用配列
|
---|
| 26 | private double geometricAverageMatrix[][]; // 幾何平均計算用一対比較行列格納用配列
|
---|
| 27 | private int pairComparisonSize; // 一対比較の段階数
|
---|
| 28 | private double pairComparisonResultArray[]; // 一対比較の結果参照用配列
|
---|
| 29 | private int pairComparisonThresholdArray[]; // 一対比較の出現数閾値格納用配列
|
---|
| 30 | private int valueCountMaxArray[]; // 論点ごと選択肢最大出現回数格納用配列
|
---|
| 31 | private double evaluationUtilityWeightArray[]; // AHP評価値に利用する参加者ごとの効用値重み格納用配列
|
---|
| 32 | private ISSUETYPE issueTypeArray[]; // 論点ごとの論点タイプの保存用配列
|
---|
| 33 |
|
---|
| 34 | /**
|
---|
| 35 | * コンストラクタ(配列等初期化)
|
---|
| 36 | *
|
---|
| 37 | * @param UtilitySpace
|
---|
| 38 | * 効用空間
|
---|
| 39 | * @param int 参加者数
|
---|
| 40 | */
|
---|
| 41 | public module_AHP(AbstractUtilitySpace utilitySpace, int participantNum) {
|
---|
| 42 |
|
---|
| 43 | // 論点数取得
|
---|
| 44 | issueNum = utilitySpace.getDomain().getIssues().size();
|
---|
| 45 |
|
---|
| 46 | // 効用空間保存
|
---|
| 47 | myUtilitySpace = utilitySpace;
|
---|
| 48 |
|
---|
| 49 | // 自分以外の参加人数
|
---|
| 50 | int otherCount = participantNum - 1;
|
---|
| 51 |
|
---|
| 52 | // 予測効用保存&提案カウント用Hash作成
|
---|
| 53 | // 各論点タイプを保存
|
---|
| 54 | valueCountHash = new HashMap[otherCount][issueNum];
|
---|
| 55 | expectUtilSpaceHash = new HashMap[otherCount][issueNum];
|
---|
| 56 | issueTypeArray = new ISSUETYPE[issueNum];
|
---|
| 57 | for (int i = 0; i < otherCount; i++) {
|
---|
| 58 | for (Issue tmp : utilitySpace.getDomain().getIssues()) {
|
---|
| 59 |
|
---|
| 60 | // 論点番号取得
|
---|
| 61 | int issue_num = tmp.getNumber();
|
---|
| 62 |
|
---|
| 63 | // 論点タイプ保存
|
---|
| 64 | issueTypeArray[issue_num - 1] = tmp.getType();
|
---|
| 65 |
|
---|
| 66 | // Hash作成
|
---|
| 67 | expectUtilSpaceHash[i][issue_num - 1] = new HashMap<String, Double>();
|
---|
| 68 | valueCountHash[i][issue_num - 1] = new HashMap<String, Integer>();
|
---|
| 69 | switch (tmp.getType()) {
|
---|
| 70 |
|
---|
| 71 | // 論点が離散値の場合
|
---|
| 72 | case DISCRETE:
|
---|
| 73 | IssueDiscrete tmpDiscrete = (IssueDiscrete) tmp;
|
---|
| 74 | for (int j = 0; j < tmpDiscrete.getNumberOfValues(); j++) {
|
---|
| 75 | expectUtilSpaceHash[i][issue_num - 1].put(tmpDiscrete
|
---|
| 76 | .getValue(j).toString(), 0.0);
|
---|
| 77 | valueCountHash[i][issue_num - 1].put(tmpDiscrete
|
---|
| 78 | .getValue(j).toString(), 0);
|
---|
| 79 | }
|
---|
| 80 | break;
|
---|
| 81 |
|
---|
| 82 | // 論点が連続値の場合
|
---|
| 83 | case INTEGER:
|
---|
| 84 | IssueInteger tmpInteger = (IssueInteger) tmp;
|
---|
| 85 | int lowest = tmpInteger.getLowerBound();
|
---|
| 86 | int highest = tmpInteger.getUpperBound();
|
---|
| 87 | for (int j = lowest; j <= highest; j++) {
|
---|
| 88 | expectUtilSpaceHash[i][issue_num - 1].put(
|
---|
| 89 | String.valueOf(j), 0.0);
|
---|
| 90 | valueCountHash[i][issue_num - 1].put(String.valueOf(j),
|
---|
| 91 | 0);
|
---|
| 92 | }
|
---|
| 93 | break;
|
---|
| 94 |
|
---|
| 95 | case OBJECTIVE:
|
---|
| 96 | case REAL:
|
---|
| 97 | case UNKNOWN:
|
---|
| 98 | default:
|
---|
| 99 | break;
|
---|
| 100 | }
|
---|
| 101 | }
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | // 論点内要素数保存配列作成
|
---|
| 105 | issueElementCount = new int[issueNum];
|
---|
| 106 | for (Issue tmp : utilitySpace.getDomain().getIssues()) {
|
---|
| 107 | switch (tmp.getType()) {
|
---|
| 108 |
|
---|
| 109 | // 論点が離散値の場合
|
---|
| 110 | case DISCRETE:
|
---|
| 111 | issueElementCount[tmp.getNumber() - 1] = ((IssueDiscrete) tmp)
|
---|
| 112 | .getNumberOfValues();
|
---|
| 113 | break;
|
---|
| 114 |
|
---|
| 115 | // 論点が連続値の場合
|
---|
| 116 | case INTEGER:
|
---|
| 117 | issueElementCount[tmp.getNumber() - 1] = ((IssueInteger) tmp)
|
---|
| 118 | .getUpperBound()
|
---|
| 119 | - ((IssueInteger) tmp).getLowerBound()
|
---|
| 120 | + 1;
|
---|
| 121 | break;
|
---|
| 122 |
|
---|
| 123 | case OBJECTIVE:
|
---|
| 124 | case REAL:
|
---|
| 125 | case UNKNOWN:
|
---|
| 126 | default:
|
---|
| 127 | break;
|
---|
| 128 | }
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | // 予測効用空間の論点間重み格納配列作成
|
---|
| 132 | expectIssueWeightArray = new double[otherCount][issueNum];
|
---|
| 133 |
|
---|
| 134 | // 一対比較の段階数設定&閾値格納用配列作成&結果配列作成
|
---|
| 135 | pairComparisonSize = 9; // 1,3,5,7,9 + 偶数値
|
---|
| 136 | pairComparisonThresholdArray = new int[pairComparisonSize + 1]; // 閾値なので+1
|
---|
| 137 | // |A1|A2|A3|:数値3,閾値4
|
---|
| 138 | pairComparisonResultArray = new double[pairComparisonSize];
|
---|
| 139 | for (int j = 1; j <= pairComparisonSize; j++) {
|
---|
| 140 | pairComparisonResultArray[j - 1] = (double) j
|
---|
| 141 | / (double) pairComparisonSize;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | // 幾何平均用一対比較行列格納配列作成
|
---|
| 145 | int tmpMax = issueNum;
|
---|
| 146 | for (int i = 0; i < issueElementCount.length; i++) {
|
---|
| 147 | if (tmpMax < issueElementCount[i]) {
|
---|
| 148 | tmpMax = issueElementCount[i];
|
---|
| 149 | }
|
---|
| 150 | }
|
---|
| 151 | geometricAverageMatrix = new double[tmpMax][tmpMax];
|
---|
| 152 |
|
---|
| 153 | // 論点ごと要素カウント最大格納用配列作成
|
---|
| 154 | valueCountMaxArray = new int[issueNum];
|
---|
| 155 |
|
---|
| 156 | // AHP評価値用効用重み配列作成
|
---|
| 157 | evaluationUtilityWeightArray = new double[otherCount];
|
---|
| 158 | for (int i = 0; i < otherCount; i++) {
|
---|
| 159 | evaluationUtilityWeightArray[i] = 1.0 / (double) otherCount;
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | /**
|
---|
| 164 | * 相手からのBidの内容をカウント
|
---|
| 165 | *
|
---|
| 166 | * @param int 参加者番号(0〜)
|
---|
| 167 | * @param Bid
|
---|
| 168 | * カウント対象Bid
|
---|
| 169 | */
|
---|
| 170 | public void countBid(int partyID, Bid targetBid) {
|
---|
| 171 |
|
---|
| 172 | // Bidの内容を論点ごとにHashにカウント
|
---|
| 173 | for (int i = 1; i <= issueNum; i++) {
|
---|
| 174 | try {
|
---|
| 175 | if (valueCountHash[partyID][i - 1].containsKey(targetBid
|
---|
| 176 | .getValue(i).toString())) {
|
---|
| 177 | int tmp = valueCountHash[partyID][i - 1].get(targetBid
|
---|
| 178 | .getValue(i).toString());
|
---|
| 179 | valueCountHash[partyID][i - 1].put(targetBid.getValue(i)
|
---|
| 180 | .toString(), tmp + 1);
|
---|
| 181 | }
|
---|
| 182 | } catch (Exception e) {
|
---|
| 183 | System.out.println("Offerd Bid From Party " + partyID
|
---|
| 184 | + " Is Wrong");
|
---|
| 185 | System.out
|
---|
| 186 | .println("Wrong Bid Content: " + targetBid.toString());
|
---|
| 187 | }
|
---|
| 188 | }
|
---|
| 189 | }
|
---|
| 190 |
|
---|
| 191 | /**
|
---|
| 192 | * 相手の効用空間予測更新(一対比較&幾何平均)
|
---|
| 193 | *
|
---|
| 194 | * @param int 参加者番号(0〜)
|
---|
| 195 | */
|
---|
| 196 | public void updateExpectUtilitySpace(int partyID) {
|
---|
| 197 |
|
---|
| 198 | // 論点内項目の評価値予測
|
---|
| 199 | for (int i = 0; i < issueNum; i++) {
|
---|
| 200 |
|
---|
| 201 | // 論点内要素のカウントを配列に格納
|
---|
| 202 | int arrayKey = 0;
|
---|
| 203 | int elementCount[] = new int[issueElementCount[i]];
|
---|
| 204 | for (String key : valueCountHash[partyID][i].keySet()) {
|
---|
| 205 |
|
---|
| 206 | int count = valueCountHash[partyID][i].get(key);
|
---|
| 207 | elementCount[arrayKey++] = count;
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | // 数え上げ結果を元にした論点内の各要素への重要度の割り当て
|
---|
| 211 | double elementPairComparisonArray[] = new double[issueElementCount[i]];
|
---|
| 212 | switch (issueTypeArray[i]) {
|
---|
| 213 |
|
---|
| 214 | // 論点が離散値の場合
|
---|
| 215 | case DISCRETE:
|
---|
| 216 |
|
---|
| 217 | // 評価が最大と予想される要素(=最大の出現数の要素)のカウントも保存
|
---|
| 218 | int tmpMax = 0;
|
---|
| 219 | for (int k = 0; k < elementCount.length; k++) {
|
---|
| 220 | if (tmpMax < elementCount[k]) {
|
---|
| 221 | tmpMax = elementCount[k];
|
---|
| 222 | }
|
---|
| 223 | }
|
---|
| 224 | valueCountMaxArray[i] = tmpMax;
|
---|
| 225 |
|
---|
| 226 | // 論点内要素評価値予測のための一対比較(重要度割り当て)
|
---|
| 227 | setPairComparisonArray(elementCount, elementPairComparisonArray);
|
---|
| 228 |
|
---|
| 229 | break;
|
---|
| 230 |
|
---|
| 231 | // 論点が連続値の場合
|
---|
| 232 | case INTEGER:
|
---|
| 233 |
|
---|
| 234 | // 連続値の前半と後半それぞれの出現数の和を取得
|
---|
| 235 | int elementSize = elementCount.length;
|
---|
| 236 | int sum_former = 0,
|
---|
| 237 | sum_latter = 0;
|
---|
| 238 | for (int k = 0; k < elementSize; k++) {
|
---|
| 239 | if ((elementSize / 2) > k) {
|
---|
| 240 | sum_former += elementCount[k];
|
---|
| 241 | } else {
|
---|
| 242 | sum_latter += elementCount[k];
|
---|
| 243 | }
|
---|
| 244 | }
|
---|
| 245 |
|
---|
| 246 | // 前半の方が出現数の総和が多い: 連続値に効用は反比例(1.0→0.0)
|
---|
| 247 | if (sum_former > sum_latter) {
|
---|
| 248 |
|
---|
| 249 | // 評価が最大の要素(=最小の連続値)のカウントも保存
|
---|
| 250 | valueCountMaxArray[i] = elementCount[0];
|
---|
| 251 |
|
---|
| 252 | // 最小の連続値には重要度9を割り当て,最大の連続値には重要度1を割り当て(9→1)
|
---|
| 253 | double offset = pairComparisonResultArray[pairComparisonSize - 1]
|
---|
| 254 | - pairComparisonResultArray[0];
|
---|
| 255 | for (int j = elementSize - 1; j >= 0; j--) {
|
---|
| 256 | elementPairComparisonArray[elementSize - j - 1] = pairComparisonResultArray[0]
|
---|
| 257 | + (offset * (double) j / (double) (elementSize - 1));
|
---|
| 258 | }
|
---|
| 259 |
|
---|
| 260 | // 後半の方が出現数の総和が多い: 連続値に効用は比例(0.0→1.0)
|
---|
| 261 | } else {
|
---|
| 262 |
|
---|
| 263 | // 評価が最大の要素(=最大の連続値)のカウントも保存
|
---|
| 264 | valueCountMaxArray[i] = elementCount[elementSize - 1];
|
---|
| 265 |
|
---|
| 266 | // 最小の連続値には重要度1を割り当て,最大の連続値には重要度9を割り当て(1→9)
|
---|
| 267 | double offset = pairComparisonResultArray[pairComparisonSize - 1]
|
---|
| 268 | - pairComparisonResultArray[0];
|
---|
| 269 | for (int j = elementSize - 1; j >= 0; j--) {
|
---|
| 270 | elementPairComparisonArray[j] = pairComparisonResultArray[0]
|
---|
| 271 | + (offset * (double) j / (double) (elementSize - 1));
|
---|
| 272 | }
|
---|
| 273 | }
|
---|
| 274 |
|
---|
| 275 | break;
|
---|
| 276 |
|
---|
| 277 | case OBJECTIVE:
|
---|
| 278 | case REAL:
|
---|
| 279 | case UNKNOWN:
|
---|
| 280 | default:
|
---|
| 281 | break;
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | // 一対比較結果を幾何平均で論点内要素評価値予測(最大1になるよう正規化)
|
---|
| 285 | double elementGeometricAverageArray[] = new double[issueElementCount[i]];
|
---|
| 286 | setGeometricAverageArray(issueElementCount[i],
|
---|
| 287 | elementPairComparisonArray, elementGeometricAverageArray);
|
---|
| 288 | double maxGeometricAverage = 0.0;
|
---|
| 289 | for (int j = 0; j < issueElementCount[i]; j++) {
|
---|
| 290 | if (maxGeometricAverage < elementGeometricAverageArray[j]) {
|
---|
| 291 | maxGeometricAverage = elementGeometricAverageArray[j];
|
---|
| 292 | }
|
---|
| 293 | }
|
---|
| 294 | for (int j = 0; j < issueElementCount[i]; j++) {
|
---|
| 295 | elementGeometricAverageArray[j] /= maxGeometricAverage;
|
---|
| 296 | }
|
---|
| 297 |
|
---|
| 298 | // 予測評価値をHashに保存
|
---|
| 299 | arrayKey = 0;
|
---|
| 300 | for (String key : valueCountHash[partyID][i].keySet()) {
|
---|
| 301 | expectUtilSpaceHash[partyID][i].put(key,
|
---|
| 302 | elementGeometricAverageArray[arrayKey++]);
|
---|
| 303 | }
|
---|
| 304 | }
|
---|
| 305 |
|
---|
| 306 | // 論点間重み予測のための一対比較
|
---|
| 307 | double weightPairComparisonArray[] = new double[issueNum];
|
---|
| 308 | setPairComparisonArray(valueCountMaxArray, weightPairComparisonArray);
|
---|
| 309 |
|
---|
| 310 | // 一対比較結果を幾何平均で論点間重み予測(総和1になるよう正規化)
|
---|
| 311 | setGeometricAverageArray(issueNum, weightPairComparisonArray,
|
---|
| 312 | expectIssueWeightArray[partyID]);
|
---|
| 313 | double sumGeometricAverage = 0.0;
|
---|
| 314 | for (int i = 0; i < issueNum; i++) {
|
---|
| 315 | sumGeometricAverage += expectIssueWeightArray[partyID][i];
|
---|
| 316 | }
|
---|
| 317 | for (int i = 0; i < issueNum; i++) {
|
---|
| 318 | expectIssueWeightArray[partyID][i] /= sumGeometricAverage;
|
---|
| 319 | }
|
---|
| 320 |
|
---|
| 321 | // log
|
---|
| 322 | /*
|
---|
| 323 | * System.out.println("Party ID = "+partyID); for(int
|
---|
| 324 | * i=0;i<issueNum;i++){ System.out.println("Issue " + (i+1) +
|
---|
| 325 | * " Count = " + valueCountHash[partyID][i].toString());
|
---|
| 326 | * System.out.println("Issue " + (i+1) + " Expect = " +
|
---|
| 327 | * expectUtilSpaceHash[partyID][i].toString());
|
---|
| 328 | * System.out.println("Issue " + (i+1) + " Weitght = " +
|
---|
| 329 | * expectIssueWeightArray[partyID][i]); }
|
---|
| 330 | */
|
---|
| 331 | }
|
---|
| 332 |
|
---|
| 333 | /**
|
---|
| 334 | * 一対比較結果取得
|
---|
| 335 | *
|
---|
| 336 | * @param int[] 一対比較対象配列
|
---|
| 337 | * @param double[] 一対比較結果配列
|
---|
| 338 | */
|
---|
| 339 | private void setPairComparisonArray(int targetArray[],
|
---|
| 340 | double pairComparison[]) {
|
---|
| 341 |
|
---|
| 342 | int arraySize = targetArray.length;
|
---|
| 343 |
|
---|
| 344 | // 一対比較対象の最大値&最小値取得
|
---|
| 345 | int tmpMaxCount = -1;
|
---|
| 346 | int tmpMinCount = -1;
|
---|
| 347 | for (int i = 0; i < arraySize; i++) {
|
---|
| 348 | if (tmpMaxCount == -1 || tmpMaxCount < targetArray[i]) {
|
---|
| 349 | tmpMaxCount = targetArray[i];
|
---|
| 350 | }
|
---|
| 351 | if (tmpMinCount == -1 || tmpMinCount > targetArray[i]) {
|
---|
| 352 | tmpMinCount = targetArray[i];
|
---|
| 353 | }
|
---|
| 354 | }
|
---|
| 355 | if (tmpMaxCount - tmpMinCount <= pairComparisonSize)
|
---|
| 356 | tmpMinCount = 0;
|
---|
| 357 |
|
---|
| 358 | // 一対比較閾値格納用配列作成(段階数+1が閾値の数)
|
---|
| 359 | // [最小,最大]の範囲を分割
|
---|
| 360 | // 重要度割り当て用範囲を一定でなく重み付け
|
---|
| 361 | double tmpRangeLimit = tmpMaxCount - tmpMinCount;
|
---|
| 362 | double rangeWeightArray[] = { 0.00, 0.05, 0.10, 0.20, 0.30, 0.40, 0.55,
|
---|
| 363 | 0.70, 0.85, 1.00 }; // 偶数利用+重要度5-9に重み
|
---|
| 364 | for (int i = 0; i <= pairComparisonSize; i++) {
|
---|
| 365 | pairComparisonThresholdArray[i] = (int) ((double) tmpRangeLimit * rangeWeightArray[i]);
|
---|
| 366 | pairComparisonThresholdArray[i] += tmpMinCount;
|
---|
| 367 | }
|
---|
| 368 |
|
---|
| 369 | // 一対比較
|
---|
| 370 | for (int i = 0; i < arraySize; i++) {
|
---|
| 371 |
|
---|
| 372 | int tmp = targetArray[i];
|
---|
| 373 | for (int j = 0; j < pairComparisonSize; j++) {
|
---|
| 374 | if (tmp >= pairComparisonThresholdArray[j]
|
---|
| 375 | && tmp <= pairComparisonThresholdArray[j + 1]) {
|
---|
| 376 | pairComparison[i] = pairComparisonResultArray[j];
|
---|
| 377 | break;
|
---|
| 378 | }
|
---|
| 379 | }
|
---|
| 380 | }
|
---|
| 381 | }
|
---|
| 382 |
|
---|
| 383 | /**
|
---|
| 384 | * 重要度割り当て(一対比較)結果より幾何平均計算
|
---|
| 385 | *
|
---|
| 386 | * @param int 一対比較行列サイズ
|
---|
| 387 | * @param double[] 一対比較結果配列
|
---|
| 388 | * @param double[] 幾何平均格納用配列
|
---|
| 389 | */
|
---|
| 390 | private void setGeometricAverageArray(int matrixSize,
|
---|
| 391 | double pairComparison[], double geometricAverage[]) {
|
---|
| 392 |
|
---|
| 393 | // 一対比較結果より一対比較行列作成
|
---|
| 394 | for (int i = 0; i < matrixSize; i++) {
|
---|
| 395 | for (int j = 0; j < matrixSize; j++) {
|
---|
| 396 | geometricAverageMatrix[i][j] = pairComparison[i]
|
---|
| 397 | / pairComparison[j];
|
---|
| 398 | }
|
---|
| 399 | }
|
---|
| 400 |
|
---|
| 401 | // 一対比較行列の行方向に幾何平均計算
|
---|
| 402 | for (int i = 0; i < matrixSize; i++) {
|
---|
| 403 | double multiply = 1.0;
|
---|
| 404 | for (int j = 0; j < matrixSize; j++) {
|
---|
| 405 | multiply *= geometricAverageMatrix[i][j];
|
---|
| 406 | }
|
---|
| 407 | geometricAverage[i] = Math.pow(multiply, 1.0 / matrixSize);
|
---|
| 408 | }
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | /**
|
---|
| 412 | * AHPの評価値取得
|
---|
| 413 | *
|
---|
| 414 | * @param Bid
|
---|
| 415 | * 評価対象提案
|
---|
| 416 | * @return double AHP評価値
|
---|
| 417 | */
|
---|
| 418 | public double getAHPEvaluation(Bid targetBid) {
|
---|
| 419 |
|
---|
| 420 | // 予測効用の重み付き総和をAHP評価値
|
---|
| 421 | double evaluationValue = 0.0;
|
---|
| 422 | for (int i = 0; i < evaluationUtilityWeightArray.length; i++) {
|
---|
| 423 | evaluationValue += getExpectUtility(i, targetBid)
|
---|
| 424 | * evaluationUtilityWeightArray[i];
|
---|
| 425 | }
|
---|
| 426 |
|
---|
| 427 | return evaluationValue;
|
---|
| 428 | }
|
---|
| 429 |
|
---|
| 430 | /**
|
---|
| 431 | * 提案の予測効用値を計算
|
---|
| 432 | *
|
---|
| 433 | * @param int 参加者番号(0〜)
|
---|
| 434 | * @param Bid
|
---|
| 435 | * 提案
|
---|
| 436 | * @return double 予測効用値
|
---|
| 437 | */
|
---|
| 438 | public double getExpectUtility(int partyID, Bid targetBid) {
|
---|
| 439 |
|
---|
| 440 | double utility = 0.0;
|
---|
| 441 | if (targetBid != null) {
|
---|
| 442 |
|
---|
| 443 | for (int i = 1; i <= issueNum; i++) {
|
---|
| 444 |
|
---|
| 445 | try {
|
---|
| 446 | // 相手の提案を元に予測効用空間から効用を取得し重み掛けて加算
|
---|
| 447 | String valName = targetBid.getValue(i).toString();
|
---|
| 448 | utility += (expectUtilSpaceHash[partyID][i - 1]
|
---|
| 449 | .get(valName) * expectIssueWeightArray[partyID][i - 1]);
|
---|
| 450 |
|
---|
| 451 | } catch (Exception e) {
|
---|
| 452 | System.out
|
---|
| 453 | .println("Get Expect Utility Target Bid Is Wrong");
|
---|
| 454 | System.out.println("Wrong Bid Content: "
|
---|
| 455 | + targetBid.toString());
|
---|
| 456 | }
|
---|
| 457 | }
|
---|
| 458 | }
|
---|
| 459 |
|
---|
| 460 | return utility;
|
---|
| 461 | }
|
---|
| 462 |
|
---|
| 463 | /**
|
---|
| 464 | * 特定の参加者から見たAHP評価値取得
|
---|
| 465 | *
|
---|
| 466 | * @param Bid
|
---|
| 467 | * 評価対象Bid
|
---|
| 468 | * @param int 参加者番号(0〜)
|
---|
| 469 | * @return double 特定の参加者から見たAHP評価値
|
---|
| 470 | */
|
---|
| 471 | public double getAHPEvaluationForOpponents(int partyID, Bid targetBid) {
|
---|
| 472 |
|
---|
| 473 | double evaluationValue = 0.0;
|
---|
| 474 | double weight = 1.0 / (double) evaluationUtilityWeightArray.length; // 重みは一定
|
---|
| 475 |
|
---|
| 476 | // 指定交渉相手以外の予測効用を重み付き加算
|
---|
| 477 | for (int i = 0; i < evaluationUtilityWeightArray.length; i++) {
|
---|
| 478 | if (i != partyID) {
|
---|
| 479 | evaluationValue += getExpectUtility(i, targetBid) * weight;
|
---|
| 480 | }
|
---|
| 481 | }
|
---|
| 482 |
|
---|
| 483 | // 自分の効用値を重み付き加算
|
---|
| 484 | double myUtility = 0.0;
|
---|
| 485 | try {
|
---|
| 486 | myUtility = myUtilitySpace.getUtility(targetBid);
|
---|
| 487 | } catch (Exception e) {
|
---|
| 488 | System.out.println("Get My Utility Target Bid Is Wrong");
|
---|
| 489 | System.out.println("Wrong Bid Content: " + targetBid.toString());
|
---|
| 490 | }
|
---|
| 491 | evaluationValue += myUtility * weight;
|
---|
| 492 |
|
---|
| 493 | return evaluationValue;
|
---|
| 494 | }
|
---|
| 495 | }
|
---|