[1] | 1 | package agents.anac.y2016.grandma;
|
---|
| 2 |
|
---|
| 3 | import java.util.ArrayList;
|
---|
| 4 | import java.util.List;
|
---|
| 5 |
|
---|
| 6 | import genius.core.AgentID;
|
---|
| 7 | import genius.core.Bid;
|
---|
| 8 | import genius.core.BidHistory;
|
---|
| 9 | import genius.core.actions.Accept;
|
---|
| 10 | import genius.core.actions.Action;
|
---|
| 11 | import genius.core.actions.DefaultAction;
|
---|
| 12 | import genius.core.actions.Offer;
|
---|
| 13 | import genius.core.bidding.BidDetails;
|
---|
| 14 | import genius.core.issue.IssueInteger;
|
---|
| 15 | import genius.core.issue.ValueInteger;
|
---|
| 16 | import genius.core.parties.AbstractNegotiationParty;
|
---|
| 17 |
|
---|
| 18 | /**
|
---|
| 19 | * Grandma Agent Teo Cherici - Maarten de Vries - Tim Resink version 1.1 -
|
---|
| 20 | * 30-03-16 upgraded to handle Issues of INTEGER type
|
---|
| 21 | */
|
---|
| 22 | public class GrandmaAgent extends AbstractNegotiationParty {
|
---|
| 23 |
|
---|
| 24 | private Action lastOfferedBidAction = null; // the last opponent offer
|
---|
| 25 | // action (not Accept)
|
---|
| 26 | private static double MINIMUM_BID_UTILITY = 0.0; // minimum acceptable
|
---|
| 27 | // utility (MAU)
|
---|
| 28 | private static double DISC_SENSITIVITY = 0.5; // Discount factor sensitivity
|
---|
| 29 | // (larger->faster
|
---|
| 30 | // convergence to mean)
|
---|
| 31 | private static int RAND_BID_AMOUNT = 15; // amount of randomly generated
|
---|
| 32 | // bids to compare for closest
|
---|
| 33 | // to mean
|
---|
| 34 | private static double MIN_UTIL_BOUND = 0.4; // minimal boundary utility
|
---|
| 35 | // limit
|
---|
| 36 | // private static double MEAN_POW_COEFF = 1.25; // power coefficient of
|
---|
| 37 | // mean, for minutil calculation
|
---|
| 38 | private static double DOMAIN_DISCOUNT = 1; // discount factor
|
---|
| 39 | private static double TIME_EXPFACT = 100; // discount factor
|
---|
| 40 |
|
---|
| 41 | private int issueN = 0; // number of issues
|
---|
| 42 | private int partiesN = 0; // number of parties
|
---|
| 43 | private int lastOffsteps = 0; // number of steps since last offer
|
---|
| 44 | private int bidNum = -1; // negotiation counter, updates for every received
|
---|
| 45 | // message and action chosen
|
---|
| 46 | private double lowBoundUtil = 0.95; // minimum utility boundary used for
|
---|
| 47 | // acceptance and offering
|
---|
| 48 | private double discMeanUtil = 1; // discounted mean utility value of
|
---|
| 49 | // opponent bids
|
---|
| 50 | private ArrayList<BidHistory> BidHist; // Bid History array of all parties
|
---|
| 51 | private ArrayList<ArrayList<Integer>> IssueAmounts = new ArrayList<ArrayList<Integer>>(); // counter
|
---|
| 52 | // of
|
---|
| 53 | // total
|
---|
| 54 | // offered
|
---|
| 55 | // issue
|
---|
| 56 | // arguments
|
---|
| 57 | private ArrayList<ArrayList<String>> IssueNames = new ArrayList<ArrayList<String>>(); // list
|
---|
| 58 | // of
|
---|
| 59 | // issue
|
---|
| 60 | // arguments
|
---|
| 61 | private ArrayList<ArrayList<Double>> normIssueVals = new ArrayList<ArrayList<Double>>(); // normalised
|
---|
| 62 | // issue
|
---|
| 63 | // amounts
|
---|
| 64 |
|
---|
| 65 | private ArrayList<ArrayList<Integer>> intIssCount = new ArrayList<ArrayList<Integer>>(); // integer
|
---|
| 66 | // issues
|
---|
| 67 | // counter
|
---|
| 68 |
|
---|
| 69 | public void init() {
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | private void initfunc() throws Exception {
|
---|
| 73 | partiesN = getNumberOfParties();
|
---|
| 74 | MINIMUM_BID_UTILITY = utilitySpace.getReservationValueUndiscounted();
|
---|
| 75 | /* Opponent model initialisation */
|
---|
| 76 | issueN = getRandBid(0).getIssues().size();
|
---|
| 77 | /* Setup BidHistory structure */
|
---|
| 78 | BidHist = new ArrayList<BidHistory>();
|
---|
| 79 | for (int i = 0; i < partiesN; i++) {
|
---|
| 80 | BidHist.add(new BidHistory());
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | /* Setup IssueAmounts structure */
|
---|
| 84 | for (int k = 0; k < issueN; k++) {
|
---|
| 85 | // for discrete issues
|
---|
| 86 | IssueNames.add(new ArrayList<String>());
|
---|
| 87 | IssueAmounts.add(new ArrayList<Integer>());
|
---|
| 88 | normIssueVals.add(new ArrayList<Double>());
|
---|
| 89 | // for integers issues
|
---|
| 90 | intIssCount.add(new ArrayList<Integer>());
|
---|
| 91 | intIssCount.get(k).add(0);
|
---|
| 92 | intIssCount.get(k).add(0);
|
---|
| 93 | }
|
---|
| 94 | DOMAIN_DISCOUNT = utilitySpace.getDiscountFactor(); // get Discount
|
---|
| 95 | // Factor from
|
---|
| 96 | // domain (or party)
|
---|
| 97 | MIN_UTIL_BOUND = 0.4 * DOMAIN_DISCOUNT; // update the minimum utility
|
---|
| 98 | // bound according to discount
|
---|
| 99 | // factor
|
---|
| 100 | // MEAN_POW_COEFF = 1+2*Math.pow(MIN_UTIL_BOUND, 2); // update the bound
|
---|
| 101 | // coefficient according to its value
|
---|
| 102 | DISC_SENSITIVITY = 10 / DOMAIN_DISCOUNT;
|
---|
| 103 | TIME_EXPFACT = Math.pow(30, DOMAIN_DISCOUNT);
|
---|
| 104 | // System.out.println("discount factor:"+DOMAIN_DISCOUNT);
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | /*
|
---|
| 108 | * chooseAction method; needs to always return a valid action (Accept or
|
---|
| 109 | * counter offer)
|
---|
| 110 | */
|
---|
| 111 | @Override
|
---|
| 112 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
| 113 | if (bidNum == -1) {
|
---|
| 114 | try {
|
---|
| 115 | initfunc();
|
---|
| 116 | } catch (Exception e) {
|
---|
| 117 | System.out.println("!!!initialization failed!!!");
|
---|
| 118 | e.printStackTrace();
|
---|
| 119 | }
|
---|
| 120 | }
|
---|
| 121 | bidNum = bidNum + 1;
|
---|
| 122 | double OppBidUtil = 0;
|
---|
| 123 | /* get Utility value of last opponent action */
|
---|
| 124 | if (DefaultAction.getBidFromAction(lastOfferedBidAction) != null) {
|
---|
| 125 | Bid OppBid = DefaultAction.getBidFromAction(lastOfferedBidAction);
|
---|
| 126 | OppBidUtil = getUtility(OppBid);
|
---|
| 127 | } else {
|
---|
| 128 | OppBidUtil = 0;
|
---|
| 129 | }
|
---|
| 130 | /* should we accept? (checked with isAcceptable) */
|
---|
| 131 | try {
|
---|
| 132 | /*
|
---|
| 133 | * accept if the opponent offer is better than our acceptance value
|
---|
| 134 | * (still calculate new acceptance value)
|
---|
| 135 | */
|
---|
| 136 | if (validActions.contains(Accept.class)
|
---|
| 137 | && isAcceptable(OppBidUtil)) {
|
---|
| 138 | lastOffsteps = lastOffsteps + 1;
|
---|
| 139 | Bid lastBid = BidHist.get((bidNum - lastOffsteps) % partiesN)
|
---|
| 140 | .getLastBid();
|
---|
| 141 | BH_update(bidNum % partiesN, lastBid);
|
---|
| 142 |
|
---|
| 143 | return new Accept(getPartyId(), lastBid);
|
---|
| 144 | } else {
|
---|
| 145 | /* otherwise give new offer */
|
---|
| 146 | lastOffsteps = 0;
|
---|
| 147 | return new Offer(getPartyId(), getBid());
|
---|
| 148 | }
|
---|
| 149 | } catch (Exception e) {
|
---|
| 150 | e.printStackTrace();
|
---|
| 151 | System.out.println("unable to check acceptance");
|
---|
| 152 | return new Offer(getPartyId(), getRandBid(lowBoundUtil));
|
---|
| 153 | }
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | @Override
|
---|
| 157 | public void receiveMessage(AgentID sender, Action action) {
|
---|
| 158 | super.receiveMessage(sender, action);
|
---|
| 159 | // if just started, initialise group19
|
---|
| 160 | if (bidNum == -1) {
|
---|
| 161 | try {
|
---|
| 162 | initfunc();
|
---|
| 163 | } catch (Exception e) {
|
---|
| 164 | System.out.println("!!!initialization failed!!!");
|
---|
| 165 | e.printStackTrace();
|
---|
| 166 | }
|
---|
| 167 | }
|
---|
| 168 | bidNum = bidNum + 1;
|
---|
| 169 | Bid lastBid = null;
|
---|
| 170 | /* store action as variable and add it to the bid history */
|
---|
| 171 | if (DefaultAction.getBidFromAction(action) != null) {
|
---|
| 172 |
|
---|
| 173 | lastOffsteps = 0;
|
---|
| 174 | lastOfferedBidAction = action;
|
---|
| 175 | lastBid = DefaultAction.getBidFromAction(lastOfferedBidAction);
|
---|
| 176 | BH_update((bidNum % partiesN), lastBid);
|
---|
| 177 | } else {
|
---|
| 178 | lastOffsteps = lastOffsteps + 1;
|
---|
| 179 | /* add last made offer to the bid history */
|
---|
| 180 | lastBid = BidHist
|
---|
| 181 | .get(((bidNum + partiesN) - lastOffsteps) % partiesN)
|
---|
| 182 | .getLastBid();
|
---|
| 183 | BH_update(bidNum % partiesN, lastBid);
|
---|
| 184 | }
|
---|
| 185 | if (lastBid != null) {
|
---|
| 186 | if (Math.floor(bidNum / partiesN) > 0) {
|
---|
| 187 | //
|
---|
| 188 | lowBoundUtil_update(getUtility(lastBid));
|
---|
| 189 | }
|
---|
| 190 | try {
|
---|
| 191 | // update offered issues arguments counter
|
---|
| 192 | Counter_update(lastBid);
|
---|
| 193 | } catch (Exception e) {
|
---|
| 194 | System.out.println("-- ERROR -- unable to update mean");
|
---|
| 195 | e.printStackTrace();
|
---|
| 196 | }
|
---|
| 197 | }
|
---|
| 198 | }
|
---|
| 199 |
|
---|
| 200 | @Override
|
---|
| 201 | public String getDescription() {
|
---|
| 202 | return "ANAC2016";
|
---|
| 203 | }
|
---|
| 204 |
|
---|
| 205 | /*
|
---|
| 206 | * Checks if the utility of the offered bid is higher than the minimum
|
---|
| 207 | * accepted (reservation value) and if it is higher than the Lower Boundary
|
---|
| 208 | * Utility
|
---|
| 209 | */
|
---|
| 210 | private boolean isAcceptable(double offered) {
|
---|
| 211 | if (offered > lowBoundUtil && offered > MINIMUM_BID_UTILITY) {
|
---|
| 212 | return true;
|
---|
| 213 | } else {
|
---|
| 214 | return false;
|
---|
| 215 | }
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | /* private function to get a new valid Bid */
|
---|
| 219 | private Bid getRandBid(double minUtil) {
|
---|
| 220 | Bid newbid;
|
---|
| 221 | int loopcheck = 0;
|
---|
| 222 | do {
|
---|
| 223 | loopcheck++;
|
---|
| 224 | newbid = generateRandomBid();
|
---|
| 225 | } while (getUtility(newbid) < minUtil && loopcheck < 100000);
|
---|
| 226 | return newbid;
|
---|
| 227 | }
|
---|
| 228 |
|
---|
| 229 | /* --- update Bid History of opponent oppID with bid newBid --- */
|
---|
| 230 | private void BH_update(int oppID, Bid newBid) {
|
---|
| 231 | if (oppID > -1 && oppID < partiesN) {
|
---|
| 232 | BidDetails tempBD = new BidDetails(newBid, getUtility(newBid));
|
---|
| 233 | BidHist.get(oppID).add(tempBD);
|
---|
| 234 | }
|
---|
| 235 | }
|
---|
| 236 |
|
---|
| 237 | /*
|
---|
| 238 | * Update counter of offered issue arguments used to calculate the proximity
|
---|
| 239 | * of eventual bids to the issues most offered by the opponents
|
---|
| 240 | */
|
---|
| 241 | private void Counter_update(Bid recBid) throws Exception {
|
---|
| 242 | for (int k = 0; k < issueN; k++) {
|
---|
| 243 | // INTEGERS:
|
---|
| 244 | if (utilitySpace.getDomain().getIssues().get(k).getType().toString()
|
---|
| 245 | .equals("INTEGER")) {
|
---|
| 246 | // check if value outside bounds
|
---|
| 247 | IssueInteger kIntIssue = (IssueInteger) utilitySpace.getDomain()
|
---|
| 248 | .getIssues().get(k);
|
---|
| 249 | ValueInteger recBidInt = (ValueInteger) recBid.getValue(k + 1);
|
---|
| 250 | Integer median = (kIntIssue.getLowerBound()
|
---|
| 251 | + kIntIssue.getUpperBound()) / 2;
|
---|
| 252 | if (recBidInt.getValue() > median) {
|
---|
| 253 | Integer plusCount = intIssCount.get(k).get(1);
|
---|
| 254 | intIssCount.get(k).set(1, plusCount + 1);
|
---|
| 255 | } else {
|
---|
| 256 | Integer minCount = intIssCount.get(k).get(0);
|
---|
| 257 | intIssCount.get(k).set(0, minCount + 1);
|
---|
| 258 | }
|
---|
| 259 | // System.out.println("plusCount:"+intIssCount.get(k).get(1));
|
---|
| 260 | // System.out.println("minCount:"+intIssCount.get(k).get(0));
|
---|
| 261 | }
|
---|
| 262 | // DISCRETE:
|
---|
| 263 | else if (utilitySpace.getDomain().getIssues().get(k).getType()
|
---|
| 264 | .toString().equals("DISCRETE")) {
|
---|
| 265 | boolean found = false;
|
---|
| 266 | if (IssueNames.get(k).isEmpty()) {
|
---|
| 267 | IssueNames.get(k).add(recBid.getValue(k + 1).toString());
|
---|
| 268 | IssueAmounts.get(k).add(1);
|
---|
| 269 | found = true;
|
---|
| 270 | } else {
|
---|
| 271 | // for all existing IssueNames
|
---|
| 272 | for (int j = 0; j < IssueNames.get(k).size(); j++) {
|
---|
| 273 | /*
|
---|
| 274 | * compare bid issue value (ex. "Beer") to existing
|
---|
| 275 | * names in IssueNames, if it does add one to
|
---|
| 276 | * IssueValues, otherwise create new IssueNames name and
|
---|
| 277 | * IssueValues value, and add 1 to it
|
---|
| 278 | */
|
---|
| 279 | if (recBid.getValue(k + 1).toString()
|
---|
| 280 | .equals(IssueNames.get(k).get(j))) {
|
---|
| 281 | int newval = IssueAmounts.get(k).get(j) + 1;
|
---|
| 282 | ArrayList<Integer> newArr = IssueAmounts.get(k);
|
---|
| 283 | newArr.set(j, newval);
|
---|
| 284 | IssueAmounts.set(k, newArr);
|
---|
| 285 | found = true;
|
---|
| 286 | }
|
---|
| 287 | }
|
---|
| 288 | if (!found) {
|
---|
| 289 | IssueNames.get(k)
|
---|
| 290 | .add(recBid.getValue(k + 1).toString());
|
---|
| 291 | IssueAmounts.get(k).add(1);
|
---|
| 292 | }
|
---|
| 293 | }
|
---|
| 294 | } else {
|
---|
| 295 | System.out.println(
|
---|
| 296 | "Wrong Issue Type:" + recBid.getValue(k + 1).getType());
|
---|
| 297 | }
|
---|
| 298 | }
|
---|
| 299 | }
|
---|
| 300 |
|
---|
| 301 | /* calculates normalised issue mean amounts */
|
---|
| 302 | private void normaliseMean() {
|
---|
| 303 | for (int i = 0; i < IssueAmounts.size(); i++) {
|
---|
| 304 | // DISCRETE Issues
|
---|
| 305 | if (utilitySpace.getDomain().getIssues().get(i).getType().toString()
|
---|
| 306 | .equals("DISCRETE")) {
|
---|
| 307 | double tot = 0;
|
---|
| 308 | for (int k = 0; k < IssueAmounts.get(i).size(); k++) {
|
---|
| 309 | tot = tot + IssueAmounts.get(i).get(k);
|
---|
| 310 | }
|
---|
| 311 | normIssueVals.get(i).clear();
|
---|
| 312 | ArrayList<Double> issValList = new ArrayList<Double>();
|
---|
| 313 | for (int j = 0; j < IssueAmounts.get(i).size(); j++) {
|
---|
| 314 | issValList.add(IssueAmounts.get(i).get(j) / tot);
|
---|
| 315 | }
|
---|
| 316 | normIssueVals.set(i, issValList);
|
---|
| 317 | } // INTEGER Issues
|
---|
| 318 | else if (utilitySpace.getDomain().getIssues().get(i).getType()
|
---|
| 319 | .toString().equals("INTEGER")) {
|
---|
| 320 |
|
---|
| 321 | }
|
---|
| 322 | }
|
---|
| 323 | }
|
---|
| 324 |
|
---|
| 325 | /*
|
---|
| 326 | * Offering strategy get minimum utility value (boundary) -> generate n
|
---|
| 327 | * random bids above boundary -> -> calculate their proximity to opponents
|
---|
| 328 | * offering mean -> return bid with highest value
|
---|
| 329 | */
|
---|
| 330 | private Bid getBid() {
|
---|
| 331 | // set min utility
|
---|
| 332 | double minUt = lowBoundUtil;
|
---|
| 333 | double maxmeanUt = 0;
|
---|
| 334 | Bid finalBid;
|
---|
| 335 | // if already in 2nd round
|
---|
| 336 | if (Math.floor(bidNum / partiesN) > 0) {
|
---|
| 337 | ArrayList<Bid> BidArr = new ArrayList<Bid>();
|
---|
| 338 | ArrayList<Double> proxArr = new ArrayList<Double>();
|
---|
| 339 | // normalise mean values
|
---|
| 340 | normaliseMean();
|
---|
| 341 | // generate random bids
|
---|
| 342 | for (int i = 0; i < RAND_BID_AMOUNT; i++) {
|
---|
| 343 | BidArr.add(getRandBid(minUt));
|
---|
| 344 | try {
|
---|
| 345 | // calculate proximity value to the opponents offering mean
|
---|
| 346 | proxArr.add(getProx(BidArr.get(i)));
|
---|
| 347 | } catch (Exception e) {
|
---|
| 348 | System.out.println("Unable to calculate mean utility");
|
---|
| 349 | e.printStackTrace();
|
---|
| 350 | }
|
---|
| 351 | }
|
---|
| 352 | // find best proximity value
|
---|
| 353 | for (int p = 0; p < proxArr.size(); p++) {
|
---|
| 354 | if (proxArr.get(p) > maxmeanUt) {
|
---|
| 355 | maxmeanUt = proxArr.get(p);
|
---|
| 356 | }
|
---|
| 357 | }
|
---|
| 358 | // return bid with maximum proximity
|
---|
| 359 | finalBid = BidArr.get(proxArr.indexOf(maxmeanUt));
|
---|
| 360 | } else {
|
---|
| 361 | finalBid = getRandBid(minUt);
|
---|
| 362 | }
|
---|
| 363 | return finalBid;
|
---|
| 364 | }
|
---|
| 365 |
|
---|
| 366 | /*
|
---|
| 367 | * calculate the proximity of a bid to the normalised mean point bids with
|
---|
| 368 | * issue values equal to the most offered ones get higher scores this
|
---|
| 369 | * results in them being preferred to those with lower values
|
---|
| 370 | */
|
---|
| 371 | private double getProx(Bid bid) throws Exception {
|
---|
| 372 | double proxVal = 0;
|
---|
| 373 |
|
---|
| 374 | for (int i = 0; i < IssueNames.size(); i++) {
|
---|
| 375 | // DISCRETE
|
---|
| 376 | if (utilitySpace.getDomain().getIssues().get(i).getType().toString()
|
---|
| 377 | .equals("DISCRETE")) {
|
---|
| 378 | for (int k = 0; k < IssueNames.get(i).size(); k++) {
|
---|
| 379 | if (bid.getValue(i + 1).toString()
|
---|
| 380 | .equals(IssueNames.get(i).get(k))) {
|
---|
| 381 | proxVal = proxVal + normIssueVals.get(i).get(k);
|
---|
| 382 | }
|
---|
| 383 | }
|
---|
| 384 | } // INTEGERS
|
---|
| 385 | else if (utilitySpace.getDomain().getIssues().get(i).getType()
|
---|
| 386 | .toString().equals("INTEGER")) {
|
---|
| 387 | IssueInteger kIntIssue = (IssueInteger) utilitySpace.getDomain()
|
---|
| 388 | .getIssues().get(i);
|
---|
| 389 | ValueInteger bidInt = (ValueInteger) bid.getValue(i + 1); // bid
|
---|
| 390 | // Integer
|
---|
| 391 | // value
|
---|
| 392 | double nombidnorm = bidInt.getValue()
|
---|
| 393 | - kIntIssue.getLowerBound();
|
---|
| 394 | double denbidnorm = kIntIssue.getUpperBound()
|
---|
| 395 | - kIntIssue.getLowerBound();
|
---|
| 396 | Double bidNorm = nombidnorm / denbidnorm; // Normalised bid
|
---|
| 397 | // Integer issue
|
---|
| 398 | // value [0,1]
|
---|
| 399 | double nomcountnorm = intIssCount.get(i).get(1);
|
---|
| 400 | double dencountnorm = intIssCount.get(i).get(0)
|
---|
| 401 | + intIssCount.get(i).get(1);
|
---|
| 402 | double countNorm = nomcountnorm / dencountnorm;
|
---|
| 403 | double intIssProxVal = 1 - Math.abs(bidNorm - countNorm);
|
---|
| 404 | // System.out.println("integer Issue ProxVal:"+intIssProxVal);
|
---|
| 405 | proxVal = proxVal + intIssProxVal;
|
---|
| 406 | }
|
---|
| 407 | }
|
---|
| 408 | return proxVal;
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | /*
|
---|
| 412 | * Update the Lower Boundary Utility the utility calculated is dependent on
|
---|
| 413 | * the discounted mean utility and on a time factor (see report)
|
---|
| 414 | */
|
---|
| 415 | private void lowBoundUtil_update(double lastUt) {
|
---|
| 416 | double time = timeline.getTime();
|
---|
| 417 | // discount factor for discounted mean utility (should stay constant
|
---|
| 418 | // trough negotiation)
|
---|
| 419 | double discFact = DISC_SENSITIVITY
|
---|
| 420 | / ((bidNum * (partiesN - 1)) / (partiesN * time));
|
---|
| 421 | // System.out.println("discount factor:"+discFact);
|
---|
| 422 | discMeanUtil = (1 - discFact) * discMeanUtil + discFact * lastUt;
|
---|
| 423 | double tfact = 1 - Math.pow(time, TIME_EXPFACT);
|
---|
| 424 | // System.out.println("time:"+time);
|
---|
| 425 | // System.out.println("discMeanUtil:"+discMeanUtil);
|
---|
| 426 | lowBoundUtil = (MIN_UTIL_BOUND + (1 - MIN_UTIL_BOUND) * discMeanUtil)
|
---|
| 427 | * tfact;// *Math.pow(discMeanUtil,
|
---|
| 428 | // MEAN_POW_COEFF))*tfact;
|
---|
| 429 | // System.out.println("min utility:"+lowBoundUtil);
|
---|
| 430 | }
|
---|
| 431 | }
|
---|