[127] | 1 | package agents.anac.y2017.geneking;
|
---|
| 2 |
|
---|
| 3 | import java.util.List;
|
---|
| 4 |
|
---|
| 5 | import java.util.ArrayList;
|
---|
| 6 | import java.util.HashMap;
|
---|
| 7 | import java.util.Map;
|
---|
| 8 | import java.util.Random;
|
---|
| 9 | import java.util.Set;
|
---|
| 10 |
|
---|
| 11 | import java.io.IOException;
|
---|
| 12 |
|
---|
| 13 | import genius.core.AgentID;
|
---|
| 14 | import genius.core.Bid;
|
---|
| 15 | import genius.core.actions.Accept;
|
---|
| 16 | import genius.core.actions.Action;
|
---|
| 17 | import genius.core.actions.EndNegotiation;
|
---|
| 18 | import genius.core.actions.Offer;
|
---|
| 19 | import genius.core.issue.ISSUETYPE;
|
---|
| 20 | import genius.core.issue.Issue;
|
---|
| 21 | import genius.core.issue.IssueDiscrete;
|
---|
| 22 | import genius.core.issue.IssueInteger;
|
---|
| 23 | import genius.core.issue.IssueReal;
|
---|
| 24 | import genius.core.issue.Value;
|
---|
| 25 | import genius.core.issue.ValueDiscrete;
|
---|
| 26 | import genius.core.issue.ValueInteger;
|
---|
| 27 | import genius.core.issue.ValueReal;
|
---|
| 28 | import genius.core.list.Tuple;
|
---|
| 29 | import genius.core.parties.AbstractNegotiationParty;
|
---|
| 30 | import genius.core.parties.NegotiationInfo;
|
---|
| 31 | import genius.core.persistent.StandardInfo;
|
---|
| 32 | import genius.core.persistent.StandardInfoList;
|
---|
| 33 | import genius.core.utility.EvaluatorDiscrete;
|
---|
| 34 |
|
---|
| 35 | /**
|
---|
| 36 | * @author W.Pasman Some improvements over the standard SimpleAgent.
|
---|
| 37 | *
|
---|
| 38 | * Random Walker, Zero Intelligence Agent
|
---|
| 39 | */
|
---|
| 40 |
|
---|
| 41 | class IssueFreqRank {// ある論点中の頻度等
|
---|
| 42 | private HashMap<String, Integer> frequenceS;// 各提案内容の頻度
|
---|
| 43 | private int sum;// 全頻度の合計
|
---|
| 44 | private int maxFreq;// 最大頻度
|
---|
| 45 | private double average;// 頻度の平均
|
---|
| 46 | private double variance;// 頻度の分散
|
---|
| 47 | private double pseudoWeight;// 疑似重み
|
---|
| 48 |
|
---|
| 49 | IssueFreqRank(List<ValueDiscrete> valueS, ValueDiscrete aSelected) {
|
---|
| 50 | frequenceS = new HashMap<String, Integer>();
|
---|
| 51 | for (ValueDiscrete valueD : valueS) {
|
---|
| 52 | frequenceS.put(valueD.getValue(), 0);
|
---|
| 53 | }
|
---|
| 54 | sum = 0;
|
---|
| 55 | maxFreq = 0;
|
---|
| 56 | average = 0;
|
---|
| 57 | variance = 0;
|
---|
| 58 | pseudoWeight = 0;
|
---|
| 59 | addFreq(aSelected.getValue());
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | public HashMap<String, Integer> getFrequenceS() {
|
---|
| 63 | return (frequenceS);
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | public int getSum() {
|
---|
| 67 | return (sum);
|
---|
| 68 | }
|
---|
| 69 |
|
---|
| 70 | public int getMaxFreq() {
|
---|
| 71 | return (maxFreq);
|
---|
| 72 | }
|
---|
| 73 |
|
---|
| 74 | public double getAverage() {
|
---|
| 75 | return (average);
|
---|
| 76 | }
|
---|
| 77 |
|
---|
| 78 | public double getVariance() {
|
---|
| 79 | return (variance);
|
---|
| 80 | }
|
---|
| 81 |
|
---|
| 82 | public double pseudoWeight() {
|
---|
| 83 | return (pseudoWeight);
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | public void addFreq(String aSelected) {
|
---|
| 87 | int current = frequenceS.get(aSelected);
|
---|
| 88 | frequenceS.put(aSelected, current + 1);
|
---|
| 89 | sum += 1;
|
---|
| 90 | average = sum / frequenceS.size();
|
---|
| 91 | double vSum = 0;
|
---|
| 92 | for (HashMap.Entry<String, Integer> entry : frequenceS.entrySet()) {// 全ての値を調べる
|
---|
| 93 | if (maxFreq < entry.getValue()) {
|
---|
| 94 | maxFreq = entry.getValue();// 最大頻度を更新
|
---|
| 95 | }
|
---|
| 96 | double diff = entry.getValue() - average;
|
---|
| 97 | vSum += (diff * diff);
|
---|
| 98 | }
|
---|
| 99 | variance = Math.sqrt(vSum);
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | public class GeneKing extends AbstractNegotiationParty {// Agent
|
---|
| 105 | private Bid lastPartnerBid;
|
---|
| 106 | private static double MINIMUM_BID_UTILITY = 0.3;
|
---|
| 107 | //
|
---|
| 108 | private StandardInfoList history;
|
---|
| 109 | // private AbstractUtilitySpace utilitySpace;
|
---|
| 110 | ArrayList<Bid> geneS = new ArrayList<Bid>();// 遺伝子(入札内容)
|
---|
| 111 | ArrayList<Offer> foreignS = new ArrayList<Offer>();// 外来遺伝子(相手からの入札内容)
|
---|
| 112 | ArrayList<Offer> tailForeignS = new ArrayList<Offer>();
|
---|
| 113 | ArrayList<Bid> eliteS = new ArrayList<Bid>();// 優秀な個体(効用値の高い入札)
|
---|
| 114 | Bid offeredBid = null;
|
---|
| 115 | Bid myLastBid = null;
|
---|
| 116 | long initNum = 2000;// 初期個体数
|
---|
| 117 | int crossNum = 5;// 交叉回数
|
---|
| 118 | int limitForeignSNum = 500;
|
---|
| 119 | int maxForeignSNum = 200;
|
---|
| 120 | int maxNum = 300;
|
---|
| 121 | int MaxChangeNum = 100;
|
---|
| 122 | double acceptableUtility = 0.0;
|
---|
| 123 | double tgtUtility = 1.0;
|
---|
| 124 | final double VALIANCE = 0.05;
|
---|
| 125 | Random randomnr = new Random();
|
---|
| 126 | EvaluatorDiscrete evaluator = new EvaluatorDiscrete();
|
---|
| 127 | // HashMap<String,ArrayList<ArrayList<String>>> discreteRankS = new
|
---|
| 128 | // HashMap<String,ArrayList<ArrayList<String>>>();
|
---|
| 129 | HashMap<String, HashMap<String, Double>> dValueRankS = new HashMap<String, HashMap<String, Double>>();
|
---|
| 130 | HashMap<AgentID, HashMap<String, IssueFreqRank>> dFreqRankS2 = new HashMap<AgentID, HashMap<String, IssueFreqRank>>();
|
---|
| 131 | double utilWaight = 3.0, simWaight = 1.0;
|
---|
| 132 |
|
---|
| 133 | double getSimilarity2(Bid aBid1, Bid aBid2) {
|
---|
| 134 | double sim = 0;
|
---|
| 135 | List<Issue> IssueS1 = aBid1.getIssues();
|
---|
| 136 | int index = 0;
|
---|
| 137 | int len = IssueS1.size();
|
---|
| 138 | while (index < len) {
|
---|
| 139 | Issue issue1 = IssueS1.get(index);
|
---|
| 140 | switch (issue1.getType()) {
|
---|
| 141 | case DISCRETE: {
|
---|
| 142 | ValueDiscrete valueDiscrete1 = (ValueDiscrete) aBid1
|
---|
| 143 | .getValue(issue1.getNumber());
|
---|
| 144 | ValueDiscrete valueDiscrete2 = (ValueDiscrete) aBid2
|
---|
| 145 | .getValue(issue1.getNumber());
|
---|
| 146 | HashMap<String, Double> drank = dValueRankS
|
---|
| 147 | .get(issue1.getName());
|
---|
| 148 | String fName = valueDiscrete1.getValue(),
|
---|
| 149 | mName = valueDiscrete2.getValue();
|
---|
| 150 | double bigger = drank.get(fName), smaller = drank.get(mName);
|
---|
| 151 | if (bigger < smaller) {
|
---|
| 152 | double temp = bigger;
|
---|
| 153 | bigger = smaller;
|
---|
| 154 | smaller = temp;
|
---|
| 155 | }
|
---|
| 156 | double diff = bigger - smaller;
|
---|
| 157 | if (diff < 0) {
|
---|
| 158 | diff *= -1;
|
---|
| 159 | }
|
---|
| 160 | double finalDiff = (1 - diff / drank.size()) / len;
|
---|
| 161 | if (finalDiff < 0) {
|
---|
| 162 | finalDiff = 0;
|
---|
| 163 | }
|
---|
| 164 | // System.out.println("fr="+bigger+" fn="+fName+" mr="+smaller+"
|
---|
| 165 | // mn="+mName+" diff="+diff+" size="+drank.size());
|
---|
| 166 | sim += finalDiff;
|
---|
| 167 | break;
|
---|
| 168 | }
|
---|
| 169 | case INTEGER: {
|
---|
| 170 | ValueInteger valueInt1 = (ValueInteger) aBid1
|
---|
| 171 | .getValue(issue1.getNumber());
|
---|
| 172 | ValueInteger valueInt2 = (ValueInteger) aBid2
|
---|
| 173 | .getValue(issue1.getNumber());
|
---|
| 174 | double diff = (double) valueInt1.getValue()
|
---|
| 175 | - (double) valueInt2.getValue();
|
---|
| 176 | // System.out.println("Idiff="+diff);
|
---|
| 177 | if (diff < 0) {
|
---|
| 178 | diff *= -1.0;
|
---|
| 179 | }
|
---|
| 180 | IssueInteger issueInt = (IssueInteger) IssueS1.get(index);
|
---|
| 181 | double finalDiff = (1 - diff
|
---|
| 182 | / (issueInt.getUpperBound() - issueInt.getLowerBound()))
|
---|
| 183 | / len;
|
---|
| 184 | if (finalDiff < 0) {
|
---|
| 185 | finalDiff = 0;
|
---|
| 186 | }
|
---|
| 187 | sim += finalDiff;
|
---|
| 188 | break;
|
---|
| 189 | }
|
---|
| 190 | default: {
|
---|
| 191 | break;
|
---|
| 192 | }
|
---|
| 193 | }
|
---|
| 194 | ++index;
|
---|
| 195 | }
|
---|
| 196 | return (sim);
|
---|
| 197 | }
|
---|
| 198 |
|
---|
| 199 | double getAveSim(Bid aAlpha, List<Offer> aBetaS) {
|
---|
| 200 | double sim = 0;
|
---|
| 201 | for (Offer beta : aBetaS) {
|
---|
| 202 | sim += getSimilarity2(aAlpha, beta.getBid());
|
---|
| 203 | // System.out.print(" sim="+sim);
|
---|
| 204 | }
|
---|
| 205 | sim /= aBetaS.size();
|
---|
| 206 | // System.out.println(" total="+sim);
|
---|
| 207 | return (sim);
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | double getExUtility2(Bid aBid, HashMap<String, IssueFreqRank> aFreqRankS) {
|
---|
| 211 | double util = 0;
|
---|
| 212 | List<Issue> issueS = utilitySpace.getDomain().getIssues();
|
---|
| 213 | for (Issue issue : issueS) {
|
---|
| 214 | switch (issue.getType()) {
|
---|
| 215 | case DISCRETE: {
|
---|
| 216 | IssueFreqRank freqRank = aFreqRankS.get(issue.getName());// 順位
|
---|
| 217 | int freqValue = freqRank.getFrequenceS()
|
---|
| 218 | .get(aBid.getValue(issue.getNumber()));
|
---|
| 219 | if (freqValue == 0) {
|
---|
| 220 | freqValue += 1;
|
---|
| 221 | }
|
---|
| 222 | double nFreqValue = (double) freqValue
|
---|
| 223 | / (double) freqRank.getMaxFreq();
|
---|
| 224 | util += nFreqValue / issueS.size();
|
---|
| 225 | break;
|
---|
| 226 | }
|
---|
| 227 | case INTEGER: {
|
---|
| 228 | util += ((ValueInteger) (aBid.getValue(issue.getNumber())))
|
---|
| 229 | .getValue();
|
---|
| 230 | break;
|
---|
| 231 | }
|
---|
| 232 | }
|
---|
| 233 | }
|
---|
| 234 | return (util);
|
---|
| 235 | }
|
---|
| 236 |
|
---|
| 237 | double getMyEvaluation(Bid aBid, List<Offer> aMotherS) {
|
---|
| 238 | Set<AgentID> set = dFreqRankS2.keySet();
|
---|
| 239 | double exUtil1 = 0, exUtil2 = 0, count = 0;
|
---|
| 240 | for (AgentID id : set) {
|
---|
| 241 | if (count == 0) {
|
---|
| 242 | // exUtil1 = getExUtility(aBid,dFreqRankS.get(id));
|
---|
| 243 | exUtil1 = getExUtility2(aBid, dFreqRankS2.get(id));
|
---|
| 244 | } else {
|
---|
| 245 | // exUtil2 = getExUtility(aBid,dFreqRankS.get(id));
|
---|
| 246 | exUtil2 = getExUtility2(aBid, dFreqRankS2.get(id));
|
---|
| 247 | }
|
---|
| 248 | ++count;
|
---|
| 249 | }
|
---|
| 250 | double diff = (exUtil1 - exUtil2) * 2;
|
---|
| 251 | if (diff < 0) {
|
---|
| 252 | diff *= -1;
|
---|
| 253 | }
|
---|
| 254 | double util = utilitySpace.getUtility(aBid),
|
---|
| 255 | sim = getAveSim(aBid, aMotherS);
|
---|
| 256 | double newEval = util * utilWaight + sim * simWaight + exUtil1 + exUtil2
|
---|
| 257 | - diff;
|
---|
| 258 | // System.out.println("(u,s,e1,e2,d)="+"("+util+","+sim+","+exUtil1+","+exUtil2+","+diff+")");
|
---|
| 259 | return (newEval);
|
---|
| 260 | }
|
---|
| 261 |
|
---|
| 262 | ArrayList<Bid> chooseEliteS3(ArrayList<Bid> aGeneS, List<Offer> aMotherS) {
|
---|
| 263 | eliteS = new ArrayList<Bid>();
|
---|
| 264 | Bid best = new Bid(aGeneS.get(0));
|
---|
| 265 | double util = utilitySpace.getUtility(best);
|
---|
| 266 | double sim = getAveSim(best, aMotherS);
|
---|
| 267 | double bestEval = 0;
|
---|
| 268 | // System.out.println(" (u,s)=("+util+","+sim+")");
|
---|
| 269 | ArrayList<Bid> newGeneS = new ArrayList<Bid>(aGeneS);
|
---|
| 270 | int index, count;
|
---|
| 271 | while (eliteS.size() < maxNum) {
|
---|
| 272 | index = 0;
|
---|
| 273 | count = 0;
|
---|
| 274 | bestEval = -10;
|
---|
| 275 | for (Bid gene : newGeneS) {
|
---|
| 276 | double eval = getMyEvaluation(gene, aMotherS);
|
---|
| 277 | if (eval > bestEval) {
|
---|
| 278 | best = gene;
|
---|
| 279 | bestEval = eval;
|
---|
| 280 | index = count;
|
---|
| 281 | }
|
---|
| 282 | ++count;
|
---|
| 283 | }
|
---|
| 284 | eliteS.add(best);
|
---|
| 285 | newGeneS.remove(index);// 加えた入札を消す
|
---|
| 286 | if (newGeneS.size() == 0) {
|
---|
| 287 | break;
|
---|
| 288 | }
|
---|
| 289 | }
|
---|
| 290 | util = utilitySpace.getUtility(best);
|
---|
| 291 | sim = getAveSim(best, aMotherS);
|
---|
| 292 | // System.out.println(" (u,s)2=("+util+","+sim+")");
|
---|
| 293 | return (eliteS);
|
---|
| 294 | }
|
---|
| 295 |
|
---|
| 296 | Bid chooseBest(ArrayList<Bid> aGeneS) {
|
---|
| 297 | Bid best = new Bid(aGeneS.get(0));
|
---|
| 298 | double bestEval = getMyEvaluation(best, tailForeignS);
|
---|
| 299 | for (Bid gene : aGeneS) {
|
---|
| 300 | double eval = getMyEvaluation(gene, tailForeignS);
|
---|
| 301 | if (eval > bestEval) {
|
---|
| 302 | best = gene;
|
---|
| 303 | bestEval = eval;
|
---|
| 304 | }
|
---|
| 305 | }
|
---|
| 306 | return (best);
|
---|
| 307 | }
|
---|
| 308 |
|
---|
| 309 | private Bid getRandomBidGK() {
|
---|
| 310 | HashMap<Integer, Value> values = new HashMap<Integer, Value>(); // pairs
|
---|
| 311 | // <issuenumber,chosen
|
---|
| 312 | // value
|
---|
| 313 | // string>
|
---|
| 314 | List<Issue> issues = utilitySpace.getDomain().getIssues();
|
---|
| 315 | Random randomnr = new Random();
|
---|
| 316 | Bid bid = null;
|
---|
| 317 | do {
|
---|
| 318 | for (Issue lIssue : issues) {
|
---|
| 319 | switch (lIssue.getType()) {
|
---|
| 320 | case DISCRETE: {// 文字列
|
---|
| 321 | IssueDiscrete lIssueDiscrete = (IssueDiscrete) lIssue;
|
---|
| 322 | int optionIndex = randomnr
|
---|
| 323 | .nextInt(lIssueDiscrete.getNumberOfValues());
|
---|
| 324 | values.put(lIssue.getNumber(),
|
---|
| 325 | lIssueDiscrete.getValue(optionIndex));
|
---|
| 326 | break;
|
---|
| 327 | }
|
---|
| 328 | case REAL: {//
|
---|
| 329 | IssueReal lIssueReal = (IssueReal) lIssue;
|
---|
| 330 | int optionInd = randomnr.nextInt(
|
---|
| 331 | lIssueReal.getNumberOfDiscretizationSteps() - 1);
|
---|
| 332 | values.put(lIssueReal.getNumber(), new ValueReal(lIssueReal
|
---|
| 333 | .getLowerBound()
|
---|
| 334 | + (lIssueReal.getUpperBound()
|
---|
| 335 | - lIssueReal.getLowerBound()) * (optionInd)
|
---|
| 336 | / (lIssueReal
|
---|
| 337 | .getNumberOfDiscretizationSteps())));
|
---|
| 338 | break;
|
---|
| 339 | }
|
---|
| 340 | case INTEGER: {
|
---|
| 341 | IssueInteger lIssueInteger = (IssueInteger) lIssue;
|
---|
| 342 | int optionIndex2 = lIssueInteger.getLowerBound()
|
---|
| 343 | + randomnr.nextInt(lIssueInteger.getUpperBound()
|
---|
| 344 | - lIssueInteger.getLowerBound());
|
---|
| 345 | values.put(lIssueInteger.getNumber(),
|
---|
| 346 | new ValueInteger(optionIndex2));
|
---|
| 347 | break;
|
---|
| 348 | }
|
---|
| 349 | default: {
|
---|
| 350 | System.out.println("issue type " + lIssue.getType()
|
---|
| 351 | + " not supported by geneKing");
|
---|
| 352 | }
|
---|
| 353 | }
|
---|
| 354 | }
|
---|
| 355 | bid = new Bid(utilitySpace.getDomain(), values);
|
---|
| 356 | } while (utilitySpace.getUtility(bid) < MINIMUM_BID_UTILITY);
|
---|
| 357 |
|
---|
| 358 | return (bid);
|
---|
| 359 | }
|
---|
| 360 |
|
---|
| 361 | private ArrayList<Bid> getRandomBidS() {
|
---|
| 362 | ArrayList<Bid> initS = new ArrayList<Bid>();
|
---|
| 363 | while (initS.size() < initNum) {
|
---|
| 364 | Bid newBid = null;
|
---|
| 365 | // do{
|
---|
| 366 | newBid = getRandomBidGK();
|
---|
| 367 | // }while(initS.contains(newBid));
|
---|
| 368 | initS.add(newBid);
|
---|
| 369 | }
|
---|
| 370 | return (initS);
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 | Bid uniformCrossOver5(Bid aFather, Bid aMother,
|
---|
| 374 | HashMap<String, IssueFreqRank> aFreqRankS) {
|
---|
| 375 | Bid child = new Bid(aFather);
|
---|
| 376 | List<Issue> genome = child.getIssues();
|
---|
| 377 | for (Issue value : genome) {
|
---|
| 378 | switch (value.getType()) {
|
---|
| 379 | case DISCRETE: {
|
---|
| 380 | IssueDiscrete lIssueDis = (IssueDiscrete) value;
|
---|
| 381 | String fName = ((ValueDiscrete) aFather
|
---|
| 382 | .getValue(value.getNumber())).getValue();// 父親の文字列
|
---|
| 383 | String mName = ((ValueDiscrete) aMother
|
---|
| 384 | .getValue(value.getNumber())).getValue();// 母親の文字列
|
---|
| 385 | // System.out.println("f="+evaluator.getValue(((ValueDiscrete)aFather.getValue(value.getNumber())))
|
---|
| 386 | // +"m="
|
---|
| 387 | // +evaluator.getValue(((ValueDiscrete)aMother.getValue(value.getNumber()))));
|
---|
| 388 | if (fName == mName) {// 互いに同じ提案だった場合
|
---|
| 389 | child.putValue(value.getNumber(),
|
---|
| 390 | aFather.getValue(value.getNumber()));
|
---|
| 391 | } else {// 提案が異なる場合
|
---|
| 392 | HashMap<String, Double> rank = dValueRankS
|
---|
| 393 | .get(lIssueDis.getName());
|
---|
| 394 | HashMap<String, Integer> aFreqRank = aFreqRankS
|
---|
| 395 | .get(value.getName()).getFrequenceS();
|
---|
| 396 | double bigger = rank.get(fName) * aFreqRank.get(fName),
|
---|
| 397 | smaller = rank.get(mName) * aFreqRank.get(mName);
|
---|
| 398 | if (bigger < smaller) {
|
---|
| 399 | double temp = bigger;
|
---|
| 400 | bigger = smaller;
|
---|
| 401 | smaller = temp;
|
---|
| 402 | }
|
---|
| 403 | ArrayList<String> midS = new ArrayList<String>();
|
---|
| 404 | for (HashMap.Entry<String, Double> entry : rank
|
---|
| 405 | .entrySet()) {// 全ての値を調べる
|
---|
| 406 | double newMid = entry.getValue()
|
---|
| 407 | * aFreqRank.get(entry.getKey());
|
---|
| 408 | if (bigger >= newMid && smaller <= newMid) {
|
---|
| 409 | midS.add(entry.getKey());
|
---|
| 410 | }
|
---|
| 411 | }
|
---|
| 412 | int newSeed = randomnr.nextInt(midS.size());
|
---|
| 413 | child.putValue(value.getNumber(),
|
---|
| 414 | new ValueDiscrete(midS.get(newSeed)));
|
---|
| 415 | } // else
|
---|
| 416 | break;
|
---|
| 417 | }
|
---|
| 418 | case INTEGER: {
|
---|
| 419 | IssueInteger lIssueInteger = (IssueInteger) value;
|
---|
| 420 | int bigger = ((ValueInteger) aFather
|
---|
| 421 | .getValue(value.getNumber())).getValue();
|
---|
| 422 | int smaller = ((ValueInteger) aMother
|
---|
| 423 | .getValue(value.getNumber())).getValue();
|
---|
| 424 | if (bigger < smaller) {
|
---|
| 425 | int temp = bigger;
|
---|
| 426 | bigger = smaller;
|
---|
| 427 | smaller = temp;
|
---|
| 428 | }
|
---|
| 429 | int optionIndex = smaller
|
---|
| 430 | + randomnr.nextInt(bigger - smaller + 1);
|
---|
| 431 | child.putValue(lIssueInteger.getNumber(),
|
---|
| 432 | new ValueInteger(optionIndex));
|
---|
| 433 | break;
|
---|
| 434 | }
|
---|
| 435 | default: {
|
---|
| 436 | System.out.println("issue type " + value.getType()
|
---|
| 437 | + " not supported by geneKing");
|
---|
| 438 | }
|
---|
| 439 | }// switch
|
---|
| 440 | } // for
|
---|
| 441 | return (child);
|
---|
| 442 | }
|
---|
| 443 |
|
---|
| 444 | // 突然変異を起こす
|
---|
| 445 | Bid mutation(Bid aOriginal) {
|
---|
| 446 | Bid mutant = new Bid(aOriginal);
|
---|
| 447 | List<Issue> genome = mutant.getIssues();
|
---|
| 448 | for (Issue issue : genome) {
|
---|
| 449 | int rot = randomnr.nextInt(70);
|
---|
| 450 | if (rot == 0) {// 値が一致したときのみ変異させる
|
---|
| 451 | switch (issue.getType()) {
|
---|
| 452 | case DISCRETE: {
|
---|
| 453 | IssueDiscrete lIssueDiscrete = (IssueDiscrete) issue;
|
---|
| 454 | int optionIndex = randomnr
|
---|
| 455 | .nextInt(lIssueDiscrete.getNumberOfValues());
|
---|
| 456 | mutant.putValue(issue.getNumber(),
|
---|
| 457 | lIssueDiscrete.getValue(optionIndex));
|
---|
| 458 | break;
|
---|
| 459 | }
|
---|
| 460 | case INTEGER: {
|
---|
| 461 | IssueInteger lIssueInteger = (IssueInteger) issue;
|
---|
| 462 | int optionIndex = lIssueInteger.getLowerBound()
|
---|
| 463 | + randomnr.nextInt(lIssueInteger.getUpperBound()
|
---|
| 464 | - lIssueInteger.getLowerBound());
|
---|
| 465 | mutant.putValue(lIssueInteger.getNumber(),
|
---|
| 466 | new ValueInteger(optionIndex));
|
---|
| 467 | break;
|
---|
| 468 | }
|
---|
| 469 | case REAL: {
|
---|
| 470 | IssueReal lIssueReal = (IssueReal) issue;
|
---|
| 471 | int optionInd = randomnr.nextInt(
|
---|
| 472 | lIssueReal.getNumberOfDiscretizationSteps() - 1);
|
---|
| 473 | mutant.putValue(lIssueReal.getNumber(), new ValueReal(
|
---|
| 474 | lIssueReal.getLowerBound() + (lIssueReal
|
---|
| 475 | .getUpperBound()
|
---|
| 476 | - lIssueReal.getLowerBound()) * (optionInd)
|
---|
| 477 | / (lIssueReal
|
---|
| 478 | .getNumberOfDiscretizationSteps())));
|
---|
| 479 | break;
|
---|
| 480 | }
|
---|
| 481 | default: {
|
---|
| 482 | System.out.println("issue type " + issue.getType()
|
---|
| 483 | + " not supported by geneKing");
|
---|
| 484 | }
|
---|
| 485 | }// switch
|
---|
| 486 | } // if
|
---|
| 487 | } // for
|
---|
| 488 | return (mutant);
|
---|
| 489 | }
|
---|
| 490 |
|
---|
| 491 | ArrayList<Bid> makeNextG3(ArrayList<Bid> aCurrentS,
|
---|
| 492 | ArrayList<Offer> aForeignS) {
|
---|
| 493 | ArrayList<Bid> nextGeneS = new ArrayList<Bid>();
|
---|
| 494 | int tail = aForeignS.size();
|
---|
| 495 | int len = 8;
|
---|
| 496 | int start = tail - len;
|
---|
| 497 | if (start < 0) {
|
---|
| 498 | start = 0;
|
---|
| 499 | }
|
---|
| 500 | tailForeignS = new ArrayList<Offer>(aForeignS.subList(start, tail));
|
---|
| 501 | // System.out.println("0Len="+aCurrentS.size()+"
|
---|
| 502 | // 1Len="+aForeignS.size()+" 2Len="+tailForeignS.size()+"
|
---|
| 503 | // start="+start+" tail="+tail);
|
---|
| 504 | Bid lastBid = null;
|
---|
| 505 | for (Bid alpha : aCurrentS) {
|
---|
| 506 | for (Offer beta : tailForeignS) {
|
---|
| 507 | for (int i = 0; i < crossNum; ++i) {
|
---|
| 508 | // Bid child = uniformCrossOver3(alpha,beta.getBid());
|
---|
| 509 | Bid child = uniformCrossOver5(alpha, beta.getBid(),
|
---|
| 510 | dFreqRankS2.get(beta.getAgent()));
|
---|
| 511 | child = mutation(child);
|
---|
| 512 | double util = utilitySpace.getUtility(child);
|
---|
| 513 | // System.out.print(util+ "");
|
---|
| 514 | if (util > 0 && !child.equals(lastBid)) {
|
---|
| 515 | nextGeneS.add(child);
|
---|
| 516 | lastBid = child;
|
---|
| 517 | }
|
---|
| 518 | }
|
---|
| 519 | }
|
---|
| 520 | }
|
---|
| 521 | // System.out.println("NextG="+nextGeneS.size());
|
---|
| 522 | nextGeneS = chooseEliteS3(nextGeneS, tailForeignS);
|
---|
| 523 | // System.out.println("NextG2="+nextGeneS.size());
|
---|
| 524 | return (nextGeneS);
|
---|
| 525 | }
|
---|
| 526 |
|
---|
| 527 | void genelogy() {
|
---|
| 528 | if (foreignS.size() == 0) {
|
---|
| 529 | Bid newBid = chooseBest(geneS);
|
---|
| 530 | myLastBid = newBid;
|
---|
| 531 | System.out.println("No foreignS!");
|
---|
| 532 | return;
|
---|
| 533 | } else {
|
---|
| 534 | ArrayList<Bid> nextS = makeNextG3(geneS, foreignS);
|
---|
| 535 | // System.out.println("NextLen="+nextS.size());
|
---|
| 536 | Bid newBid = chooseBest(nextS);
|
---|
| 537 | if (myLastBid != null) {
|
---|
| 538 | // double newEval =
|
---|
| 539 | // utilitySpace.getUtility(newBid)*utilWaight+getAveSim(newBid,foreignS)*simWaight;
|
---|
| 540 | double newEval = getMyEvaluation(newBid, tailForeignS);
|
---|
| 541 | double lastEval = getMyEvaluation(myLastBid, tailForeignS);
|
---|
| 542 | if (newEval > lastEval) {
|
---|
| 543 | myLastBid = newBid;
|
---|
| 544 | // System.out.println("New Best!");
|
---|
| 545 | }
|
---|
| 546 | } else {
|
---|
| 547 | myLastBid = newBid;
|
---|
| 548 | }
|
---|
| 549 | geneS = new ArrayList<Bid>(nextS);// 全入れ替え
|
---|
| 550 | }
|
---|
| 551 | }
|
---|
| 552 |
|
---|
| 553 | private boolean isAcceptableGK() {
|
---|
| 554 | double offeredUtil = 0.0;
|
---|
| 555 | if (offeredBid != null) {
|
---|
| 556 | offeredUtil = utilitySpace.getUtility(offeredBid);
|
---|
| 557 | }
|
---|
| 558 | double myUtil = 1.0;
|
---|
| 559 | if (myLastBid != null) {
|
---|
| 560 | myUtil = utilitySpace.getUtility(myLastBid);
|
---|
| 561 | }
|
---|
| 562 | if (offeredUtil >= myUtil - VALIANCE) {// 自分の提案以上のものか、その近くであった場合
|
---|
| 563 | return (true);
|
---|
| 564 | }
|
---|
| 565 | return (false);
|
---|
| 566 | }
|
---|
| 567 |
|
---|
| 568 | private HashMap<String, Double> makeRank2(IssueDiscrete aIssue) {
|
---|
| 569 | HashMap<String, Double> rRank = new HashMap<String, Double>();
|
---|
| 570 | List<ValueDiscrete> valueS = aIssue.getValues();
|
---|
| 571 | for (ValueDiscrete valueD : valueS) {
|
---|
| 572 | // Integer newEval = evaluator.getValue(valueD);//評価値に直す
|
---|
| 573 | double newEval = (double) (evaluator.getValue(valueD))
|
---|
| 574 | / evaluator.getEvalMax();
|
---|
| 575 | System.out.println("newEval=" + newEval);
|
---|
| 576 | // Integer newEval =
|
---|
| 577 | // EvaluatorDiscrete.this.getEvaluationNotNormalized(valueD);
|
---|
| 578 | rRank.put(valueD.getValue(), newEval);
|
---|
| 579 | }
|
---|
| 580 | return (rRank);
|
---|
| 581 | }
|
---|
| 582 |
|
---|
| 583 | private void makeRankS(List<Issue> aIssueS) {
|
---|
| 584 | System.out.println("Make Rank Start!");
|
---|
| 585 | int count = 0;
|
---|
| 586 | for (Issue issue : aIssueS) {
|
---|
| 587 | if (issue.getType().equals(ISSUETYPE.DISCRETE)) {
|
---|
| 588 | try {
|
---|
| 589 | evaluator.loadFromXML(
|
---|
| 590 | utilitySpace.toXML().getChildElementsAsList().get(0)
|
---|
| 591 | .getChildElementsAsList().get(count));
|
---|
| 592 | // evaluator.loadFromXML(issue.toXML());
|
---|
| 593 | // evaluator.setXML(issue.toXML());
|
---|
| 594 | // System.out.println("evaluator="+((EvaluatorDiscrete)evaluator).getEvalMax());
|
---|
| 595 | } catch (IOException e) {
|
---|
| 596 |
|
---|
| 597 | }
|
---|
| 598 | // discreteRankS.put(issue.getName(),
|
---|
| 599 | // makeRank((IssueDiscrete)issue));
|
---|
| 600 | dValueRankS.put(issue.getName(),
|
---|
| 601 | makeRank2((IssueDiscrete) issue));
|
---|
| 602 | System.out.println("issue-N Finish!");
|
---|
| 603 | } // if
|
---|
| 604 | ++count;
|
---|
| 605 | } // for
|
---|
| 606 | }
|
---|
| 607 |
|
---|
| 608 | private void initInitNum() {
|
---|
| 609 | long candidateNum = 1;
|
---|
| 610 | candidateNum = utilitySpace.getDomain().getNumberOfPossibleBids();
|
---|
| 611 | if (initNum > candidateNum) {
|
---|
| 612 | initNum = candidateNum;
|
---|
| 613 | }
|
---|
| 614 | }
|
---|
| 615 |
|
---|
| 616 | private void initGK() {
|
---|
| 617 | history = (StandardInfoList) getData().get();
|
---|
| 618 |
|
---|
| 619 | if (!history.isEmpty()) {
|
---|
| 620 | // example of using the history. Compute for each party the maximum
|
---|
| 621 | // utility of the bids in last session.
|
---|
| 622 | Map<String, Double> maxutils = new HashMap<String, Double>();
|
---|
| 623 | StandardInfo lastinfo = history.get(history.size() - 1);
|
---|
| 624 | for (Tuple<String, Double> offered : lastinfo.getUtilities()) {
|
---|
| 625 | String party = offered.get1();
|
---|
| 626 | Double util = offered.get2();
|
---|
| 627 | maxutils.put(party, maxutils.containsKey(party)
|
---|
| 628 | ? Math.max(maxutils.get(party), util) : util);
|
---|
| 629 | }
|
---|
| 630 | System.out.println(maxutils); // notice tournament suppresses all
|
---|
| 631 | // output.
|
---|
| 632 | }
|
---|
| 633 |
|
---|
| 634 | MINIMUM_BID_UTILITY = utilitySpace.getReservationValueUndiscounted();
|
---|
| 635 | if (MINIMUM_BID_UTILITY < utilitySpace
|
---|
| 636 | .getReservationValueUndiscounted()) {
|
---|
| 637 | MINIMUM_BID_UTILITY = utilitySpace
|
---|
| 638 | .getReservationValueUndiscounted();
|
---|
| 639 | }
|
---|
| 640 | acceptableUtility = MINIMUM_BID_UTILITY;
|
---|
| 641 | System.out.println("get issueS!");
|
---|
| 642 | List<Issue> issueS = utilitySpace.getDomain().getIssues();
|
---|
| 643 | System.out.println("got issueS!");
|
---|
| 644 | makeRankS(issueS);
|
---|
| 645 | System.out.println("Made Rank");
|
---|
| 646 | initInitNum();
|
---|
| 647 | geneS = getRandomBidS();
|
---|
| 648 | double bestUtil = 0;
|
---|
| 649 | for (StandardInfo stdInfo : history) {
|
---|
| 650 | Tuple agreement = stdInfo.getAgreement();
|
---|
| 651 | if (agreement != null) {
|
---|
| 652 | double newUtil = (double) agreement.get2();
|
---|
| 653 | if (newUtil > bestUtil && newUtil > 0.7) {
|
---|
| 654 | bestUtil = newUtil;
|
---|
| 655 | myLastBid = (Bid) agreement.get1();
|
---|
| 656 | }
|
---|
| 657 | if (newUtil > 0.7) {
|
---|
| 658 | geneS.add((Bid) agreement.get1());
|
---|
| 659 | }
|
---|
| 660 | }
|
---|
| 661 | // System.out.println("profile="+stdInfo.getAgentProfiles());
|
---|
| 662 | // System.out.println("stdInfo="+stdInfo.getUtilities());
|
---|
| 663 | // System.out.println("agree="+stdInfo.getAgreement());
|
---|
| 664 | }
|
---|
| 665 | }
|
---|
| 666 |
|
---|
| 667 | private String getNameGK() {
|
---|
| 668 | return ("GeneKing");
|
---|
| 669 | }
|
---|
| 670 |
|
---|
| 671 | private double getAverageUtility() {
|
---|
| 672 | double average = 0;
|
---|
| 673 | for (Offer foreign : tailForeignS) {
|
---|
| 674 | average += utilitySpace.getUtility(foreign.getBid());
|
---|
| 675 | }
|
---|
| 676 | average /= tailForeignS.size();
|
---|
| 677 | return (average);
|
---|
| 678 | }
|
---|
| 679 |
|
---|
| 680 | private Action chooseActionGK() {
|
---|
| 681 | double time = timeline.getTime();
|
---|
| 682 | if (time > 0.99) {// 締め切り間近の場合
|
---|
| 683 | double partnerUtil = getAverageUtility();
|
---|
| 684 | if (partnerUtil >= acceptableUtility) {
|
---|
| 685 | acceptableUtility = partnerUtil;
|
---|
| 686 | }
|
---|
| 687 |
|
---|
| 688 | if (getAverageUtility() < MINIMUM_BID_UTILITY) {
|
---|
| 689 | System.out.println("End Negotiation!");
|
---|
| 690 | return (new EndNegotiation(getPartyId()));
|
---|
| 691 | } else if (partnerUtil >= acceptableUtility) {// 最後の提案が良かった場合
|
---|
| 692 | return (new Accept(getPartyId(), lastPartnerBid));
|
---|
| 693 | } else {
|
---|
| 694 | genelogy();
|
---|
| 695 | return (new Offer(getPartyId(), myLastBid));
|
---|
| 696 | }
|
---|
| 697 | } else {// まだ余裕のある場合
|
---|
| 698 | if (isAcceptableGK()) {
|
---|
| 699 | return (new Accept(getPartyId(), lastPartnerBid));
|
---|
| 700 | } else {
|
---|
| 701 | genelogy();
|
---|
| 702 | return (new Offer(getPartyId(), myLastBid));
|
---|
| 703 | }
|
---|
| 704 | }
|
---|
| 705 | }
|
---|
| 706 |
|
---|
| 707 | private IssueFreqRank makeFreqRank2(IssueDiscrete aIssue,
|
---|
| 708 | ValueDiscrete aSelected) {
|
---|
| 709 | IssueFreqRank rRank = new IssueFreqRank(aIssue.getValues(), aSelected);
|
---|
| 710 | return (rRank);
|
---|
| 711 | }
|
---|
| 712 |
|
---|
| 713 | private HashMap<String, IssueFreqRank> makeFreqRankS2(Bid aBid) {
|
---|
| 714 | HashMap<String, IssueFreqRank> rFreqRankS = new HashMap<String, IssueFreqRank>();
|
---|
| 715 | List<Issue> issueS = utilitySpace.getDomain().getIssues();
|
---|
| 716 | for (Issue issue : issueS) {
|
---|
| 717 | if (issue.getType().equals(ISSUETYPE.DISCRETE)) {// DISCRETE型だった場合
|
---|
| 718 | IssueDiscrete dIssue = (IssueDiscrete) issue;
|
---|
| 719 | rFreqRankS.put(issue.getName(), makeFreqRank2(dIssue,
|
---|
| 720 | (ValueDiscrete) (aBid.getValue(dIssue.getNumber()))));
|
---|
| 721 | }
|
---|
| 722 | }
|
---|
| 723 | return (rFreqRankS);
|
---|
| 724 | }
|
---|
| 725 |
|
---|
| 726 | private void updateFreqRank2(ValueDiscrete aSelected, IssueFreqRank aRank) {
|
---|
| 727 | aRank.addFreq(aSelected.getValue());
|
---|
| 728 | }
|
---|
| 729 |
|
---|
| 730 | void updateFreqRankS2(Bid aBid,
|
---|
| 731 | HashMap<String, IssueFreqRank> adFreqRankS) {
|
---|
| 732 | List<Issue> issueS = utilitySpace.getDomain().getIssues();
|
---|
| 733 | for (Issue issue : issueS) {
|
---|
| 734 | if (issue.getType().equals(ISSUETYPE.DISCRETE)) {// DISCRETE型だった場合
|
---|
| 735 | updateFreqRank2(
|
---|
| 736 | (ValueDiscrete) (aBid.getValue(issue.getNumber())),
|
---|
| 737 | adFreqRankS.get(issue.getName()));
|
---|
| 738 | }
|
---|
| 739 | }
|
---|
| 740 | }
|
---|
| 741 |
|
---|
| 742 | // Offerのリストの長さをチェックし、長すぎた場合は後方のみを残す
|
---|
| 743 | ArrayList<Offer> reduceList(ArrayList<Offer> aList, int aMaxSize) {
|
---|
| 744 | ArrayList<Offer> rList = new ArrayList<Offer>(
|
---|
| 745 | aList.subList(aList.size() - aMaxSize, aList.size()));
|
---|
| 746 | return (rList);
|
---|
| 747 | }
|
---|
| 748 |
|
---|
| 749 | private void ReceiveMessageGK(Action aAction) {
|
---|
| 750 | AgentID id = aAction.getAgent();
|
---|
| 751 | if (aAction instanceof Offer) {
|
---|
| 752 | offeredBid = new Bid(((Offer) aAction).getBid()); // 提案された合意案候補
|
---|
| 753 | foreignS.add((Offer) aAction);
|
---|
| 754 | if (dFreqRankS2.containsKey(id)) {// 登録されていた場合
|
---|
| 755 | updateFreqRankS2(offeredBid, dFreqRankS2.get(id));
|
---|
| 756 | } else {// まだ登録されていない場合
|
---|
| 757 | dFreqRankS2.put(id, makeFreqRankS2(offeredBid));
|
---|
| 758 | }
|
---|
| 759 | lastPartnerBid = offeredBid;
|
---|
| 760 | // System.out.println("aAction="+offeredBid+"
|
---|
| 761 | // len="+foreignS.size()+" "+aAction.getAgent());
|
---|
| 762 | } else if (aAction instanceof Accept) {// 受け入れだった場合
|
---|
| 763 | Bid accepted = new Bid(((Accept) aAction).getBid());
|
---|
| 764 | Offer accOffer = new Offer(aAction.getAgent(), accepted);
|
---|
| 765 | foreignS.add(accOffer);
|
---|
| 766 | if (dFreqRankS2.containsKey(id)) {// 登録されていた場合
|
---|
| 767 | updateFreqRankS2(accepted, dFreqRankS2.get(id));
|
---|
| 768 | } else {// まだ登録されていない場合
|
---|
| 769 | dFreqRankS2.put(id, makeFreqRankS2(accepted));
|
---|
| 770 | }
|
---|
| 771 | }
|
---|
| 772 | if (foreignS.size() > limitForeignSNum) {
|
---|
| 773 | foreignS = reduceList(foreignS, maxForeignSNum);// 数が増えすぎたら昔のものを減らす
|
---|
| 774 | }
|
---|
| 775 |
|
---|
| 776 | }
|
---|
| 777 |
|
---|
| 778 | @Override
|
---|
| 779 | public void init(NegotiationInfo info) {
|
---|
| 780 | super.init(info);
|
---|
| 781 | System.out.println("Discount Factor is "
|
---|
| 782 | + getUtilitySpace().getDiscountFactor());
|
---|
| 783 | System.out.println("Reservation Value is "
|
---|
| 784 | + getUtilitySpace().getReservationValueUndiscounted());
|
---|
| 785 | MINIMUM_BID_UTILITY = getUtilitySpace()
|
---|
| 786 | .getReservationValueUndiscounted();
|
---|
| 787 | initGK();
|
---|
| 788 | }
|
---|
| 789 |
|
---|
| 790 | @Override
|
---|
| 791 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
| 792 | return (chooseActionGK());
|
---|
| 793 | }
|
---|
| 794 |
|
---|
| 795 | @Override
|
---|
| 796 | public void receiveMessage(AgentID sender, Action action) {
|
---|
| 797 | super.receiveMessage(sender, action);
|
---|
| 798 | ReceiveMessageGK(action);
|
---|
| 799 | }
|
---|
| 800 |
|
---|
| 801 | @Override
|
---|
| 802 | public String getDescription() {
|
---|
| 803 | return "ANAC2017";
|
---|
| 804 | }
|
---|
| 805 | }
|
---|