[338] | 1 | package bargainingchips.utilityfunctions;
|
---|
| 2 |
|
---|
| 3 | import bargainingchips.Bundle;
|
---|
| 4 | import bargainingchips.BundleBuilder;
|
---|
| 5 | import bargainingchips.Chip;
|
---|
| 6 | import bargainingchips.ChipIssueValue;
|
---|
| 7 | import bargainingchips.ChipIssueValueBuilder;
|
---|
[340] | 8 | import bargainingchips.wishlist.WishList;
|
---|
| 9 | import bargainingchips.wishlist.WishListBuilder;
|
---|
[338] | 10 |
|
---|
| 11 | /**
|
---|
| 12 | *
|
---|
| 13 | * In addition to {@link wishList}, this utility function inputs piecewise linear curves as for desired
|
---|
| 14 | * quantity and price per each {@link Chip}.
|
---|
| 15 | * To this end, the buyer designates 2 `Double' data points, namely p1 and p2, for the price of each {@link Chip},
|
---|
| 16 | * where the utility of offers lower than or equal to p1 and higher than or equal to p2 will be
|
---|
| 17 | * respectively 1 and 0. That is, it is flattened and peaked for values before p1. For the prices offered
|
---|
| 18 | * between p1 and p2, it has a downward slope.
|
---|
| 19 | * Quantity is similar to price but also mirrors for quantities less than the exact quantity per each
|
---|
| 20 | * {@link Chip} at {@link wishList}, that is flattened and peaked at 1 around the exact quantity. To this end,
|
---|
| 21 | * it inputs 4 `Integer' data deviation, namely d1, d2, d3, and d4, for the acceptable quantities of each {@link Chip}
|
---|
| 22 | * around the exact wished quantity q, where the utility of quantities lower than or equal to q-d1 or higher
|
---|
| 23 | * than or equal to q+d4 will be 0, the utility of quantities higher than or equal to q-d2 or less than or equal to q+d3
|
---|
| 24 | * will be 1, for the quantities offered between q+d3 and q+d4, it has a downward slope, and for the quantities offered
|
---|
| 25 | * between q+d1 and q+d2, it has an upward slope.
|
---|
| 26 | *
|
---|
| 27 | *
|
---|
| 28 | *
|
---|
| 29 | * @author Faria Nassiri-Mofakham
|
---|
| 30 | *
|
---|
| 31 | */
|
---|
| 32 | public class UF_PeakedFlatPricePeakedFlatQuantity implements UtilityFunction {
|
---|
| 33 |
|
---|
| 34 | private WishList wishlist; // the exact wished quantity per each Chip
|
---|
| 35 | // Other parts of the buyer's preferences are assigned with desirability degrees of a variety of prices and quantities per each Chip.
|
---|
| 36 | private ChipIssueValue<Double[]> qtyDeviation; // `Indivisible' or `divisible' space; list of 4 data points of type `Double' for discreet or continues values; The deviation around the wished quantity per each {@link Chip} could be asymmetric.
|
---|
| 37 | private ChipIssueValue<Double[]> uQty; // list of respected single utility for data points regarding quantity deviations
|
---|
| 38 | private ChipIssueValue<Double[]> breakEvenPrice; // list of 2 data points of type Double determining the price curve
|
---|
| 39 | private ChipIssueValue<Double[]> uBreakEvenPrice; // list of respected single utility for data points regarding price deviations
|
---|
| 40 | private ChipIssueValue<Double> lambdaC; // importance of each Chip (i.e, color)
|
---|
| 41 | private double lambdaP,lambdaQ; // importance of issues (i.e., price, quantity, etc)
|
---|
| 42 |
|
---|
| 43 |
|
---|
| 44 | public UF_PeakedFlatPricePeakedFlatQuantity(WishList w, ChipIssueValue<Double[]> qty, ChipIssueValue<Double[]> uQy, ChipIssueValue<Double[]> bEP, ChipIssueValue<Double[]> uBEP, ChipIssueValue<Double> lc, double lp, double lq)
|
---|
| 45 | {
|
---|
| 46 | wishlist=w;
|
---|
| 47 | qtyDeviation=qty;
|
---|
| 48 | uQty=uQy;
|
---|
| 49 | breakEvenPrice=bEP;
|
---|
| 50 | uBreakEvenPrice=uBEP;
|
---|
| 51 | lambdaC=lc;
|
---|
| 52 | lambdaP=lp;
|
---|
| 53 | lambdaQ=lq;
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | @Override
|
---|
| 57 | public Double getUtility(Bundle b)
|
---|
| 58 | {
|
---|
| 59 | double sumWeightedPrice=0.0;
|
---|
| 60 | double sumWeightedQty=0.0;
|
---|
| 61 |
|
---|
| 62 | if (b!=null)
|
---|
| 63 | {
|
---|
| 64 | for (Chip c : wishlist)
|
---|
| 65 | {
|
---|
| 66 | int desiredQ = wishlist.getQuantity(c);
|
---|
| 67 |
|
---|
| 68 | Double[] qtyDev = qtyDeviation.getUnitValue(c); // gives 4 data deviation for quantity
|
---|
| 69 | if (qtyDev.length > 4)
|
---|
| 70 | throw new IllegalStateException("\n\n[Warning] UF_PeakedFlatPriceAndPeakedFlatQuantity::getUtility(Bundle). Input only 4 quantity data deviation! "+ qtyDev);
|
---|
| 71 |
|
---|
| 72 | Double[] uQy = uQty.getUnitValue(c); // gives asymmetric utility for the data points in jumping from flat (sloped) to sloped(flat) lines
|
---|
| 73 | if (uQy.length > 4)
|
---|
| 74 | throw new IllegalStateException("\n\n[Warning] UF_PeakedFlatPriceAndPeakedFlatQuantity::getUtility(Bundle). Input only 4 values for utility of quantity data points in jumping from flat (sloped) to sloped(flat) lines! "+ uQy);
|
---|
| 75 |
|
---|
| 76 | Double[] desiredP = (Double[]) breakEvenPrice.getUnitValue(c); // gives 4 data points for price
|
---|
| 77 | if (desiredP.length > 4)
|
---|
| 78 | throw new IllegalStateException("\n\n[Warning] UF_PeakedFlatPriceAndPeakedFlatQuantity::getUtility(Bundle). Input only 4 price data points! "+ desiredP);
|
---|
| 79 |
|
---|
| 80 | Double[] uPrices= uBreakEvenPrice.getUnitValue(c); // gives utility for the first and second data points in jumping from flat to sloped line
|
---|
| 81 | if (uPrices.length > 2)
|
---|
| 82 | throw new IllegalStateException("\n\n[Warning] UF_PeakedFlatPriceAndPeakedFlatQuantity::getUtility(Bundle). Input only 2 values for utility of price data points in jumping from flat to sloped line! "+ uPrices);
|
---|
| 83 |
|
---|
| 84 | Double importanceC= lambdaC.getUnitValue(c);
|
---|
| 85 |
|
---|
| 86 | Integer offeredQ = b.getQuantity(c);
|
---|
| 87 | if (offeredQ == null)
|
---|
| 88 | offeredQ = 0;
|
---|
| 89 | Double offeredP= b.getUnitPrice(c);
|
---|
| 90 |
|
---|
| 91 | sumWeightedPrice += importanceC * uPrice(offeredP, desiredP,uPrices);
|
---|
| 92 | sumWeightedQty += importanceC * uQuantity(offeredQ, desiredQ, qtyDev, uQy);
|
---|
| 93 | }
|
---|
| 94 | double u = lambdaP * sumWeightedPrice + lambdaQ * sumWeightedQty;
|
---|
| 95 | return ( (u>1) ? 1 : ( (u<0) ? 0 : u) );
|
---|
| 96 | }
|
---|
| 97 | return 0.0;
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | /**
|
---|
| 101 | * @param param: the offered price
|
---|
| 102 | * @param data: the designated price data points
|
---|
| 103 | * @param uData: the utility of the the price data points
|
---|
| 104 | * @return the utility regarding the offered price
|
---|
| 105 | */
|
---|
| 106 | private double uPrice(double param, Double[] data, Double[] uData)
|
---|
| 107 | {
|
---|
| 108 | return ((param <= data[0]) ? 1 : (param >= data[1]) ? 0 : uSlope(param, data[0], data[1], uData[0], uData[1]) );
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | /**
|
---|
| 112 | * @param param: the offered quantity
|
---|
| 113 | * @param data: the designated quantity data points
|
---|
| 114 | * @param uData: the utility of quantity data points
|
---|
| 115 | * @return the utility regarding the offered quantity
|
---|
| 116 | */
|
---|
| 117 | private double uQuantity(double param, double q, Double[] data, Double[] uData)
|
---|
| 118 | {
|
---|
| 119 | return ( (param <= q-data[0] || param >= q+data[3]) ? 0 : ( (param > q-data[0] && param <= q-data[1] ) ? uSlope(param, data[0], data[1], uData[0], uData[1]) : ( (param > q+data[2] && param < q+data[3]) ? uSlope(param, data[2], data[3], uData[2], uData[3]) : 1) ) );
|
---|
| 120 | }
|
---|
| 121 |
|
---|
| 122 | private double uSlope(double param, double data1, double data2, Double uData1, Double uData2)
|
---|
| 123 | {
|
---|
| 124 | return (param-data1)*(uData1-uData2)/(data1-data2)+uData1;
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | /**
|
---|
| 128 | * @return a String list of values assigned to a single variable, e.g. list of quantities or prices of a {@link Chip}
|
---|
| 129 | **/
|
---|
| 130 | private String writeT(ChipIssueValue<Double[]> t)
|
---|
| 131 | {
|
---|
| 132 | String s = "{";
|
---|
| 133 | Double[] j;
|
---|
| 134 | if (t!=null)
|
---|
| 135 | {
|
---|
| 136 | for (Chip c: t)
|
---|
| 137 | {
|
---|
| 138 | s += " " + c.toString() + "={";
|
---|
| 139 | j= t.getUnitValue(c);
|
---|
| 140 | //System.out.println("j: "+j);
|
---|
| 141 | for (int k=0; k<j.length; k++)
|
---|
| 142 | s += j[k].toString()+((k<j.length-1) ? ", " : "");
|
---|
| 143 | s += "}";
|
---|
| 144 | }
|
---|
| 145 | }
|
---|
| 146 | s += " }";
|
---|
| 147 | return s;
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | @Override
|
---|
| 151 | public String toString()
|
---|
| 152 | {
|
---|
| 153 | return this.getClass().getSimpleName() + ": WishList " + wishlist + ": QtyDeviations "+ writeT(qtyDeviation)+ ": uQtyDeviations "+ writeT(uQty)+": PriceDataPoints "+ writeT(breakEvenPrice) +": uPriceDataPoints "+ writeT(uBreakEvenPrice) + ": Colors' weights "+ lambdaC + ": Issue Price's weight "+ lambdaP + ": Issue Quantity's weight " + lambdaQ;
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | public static void main(String[] args)
|
---|
| 157 | {
|
---|
| 158 | WishList wishlist = new WishListBuilder().addWish("Green", 4).addWish("Yellow", 6).addWish("Orange", 40).build();
|
---|
| 159 | ChipIssueValue<Double[]> deviations = new ChipIssueValueBuilder<Double[]>().addIssue("Green", new Double[] {100.0, 20.0, 50.0, 500.0}).addIssue("Yellow", new Double[] {50.0, 30.0, 30.0, 50.0}).addIssue("Orange", new Double[] {200.0, 40.0, 60.0, 1000.0}).build();
|
---|
| 160 | ChipIssueValue<Double[]> uDev = new ChipIssueValueBuilder<Double[]>().addIssue("Green", new Double[] {0.25, 0.8, 0.9, 0.1}).addIssue("Yellow", new Double[] {0.3, 0.7, 0.7, 0.3}).addIssue("Orange", new Double[] {0.15, 0.95, 0.85, 0.3}).build();
|
---|
| 161 |
|
---|
| 162 | ChipIssueValue<Double[]> prices = new ChipIssueValueBuilder<Double[]>().addIssue("Green", new Double[] {3.0, 3.5, 4.8, 5.0}).addIssue("Yellow", new Double[] {5.0, 5.2, 6.2, 8.0}).addIssue("Orange", new Double[] {1.0, 1.8, 2.5, 3.0}).build();
|
---|
| 163 | ChipIssueValue<Double[]> uPrices = new ChipIssueValueBuilder<Double[]>().addIssue("Green", new Double[] {0.7, 0.2}).addIssue("Yellow", new Double[] {0.8, 0.1}).addIssue("Orange", new Double[] {0.9, 0.3}).build();
|
---|
| 164 |
|
---|
| 165 | ChipIssueValue<Double> wC = new ChipIssueValueBuilder<Double>().addIssue("Green", 0.5).addIssue("Yellow", 0.3).addIssue("Orange", 0.2).build();
|
---|
| 166 | double wP = 0.6;
|
---|
| 167 | double wQ = 0.4;
|
---|
| 168 |
|
---|
| 169 |
|
---|
| 170 | UF_PeakedFlatPricePeakedFlatQuantity u = new UF_PeakedFlatPricePeakedFlatQuantity (wishlist, deviations, uDev, prices, uPrices, wC, wP, wQ);
|
---|
| 171 | System.out.println(u);
|
---|
| 172 |
|
---|
| 173 | Bundle offer = new BundleBuilder()
|
---|
| 174 | .addStack("Green", 2.0, 3)
|
---|
| 175 | .addStack("Yellow", 5.0, 4)
|
---|
| 176 | .addStack("Orange", 1.0, 17)
|
---|
| 177 | //---
|
---|
| 178 | // .addStack("Green", 3.0, 4) //should give utility 1.0 in weighted additive
|
---|
| 179 | // .addStack("Yellow", 5.0, 6)
|
---|
| 180 | // .addStack("Orange", 1.0, 40)
|
---|
| 181 | //---
|
---|
| 182 | // .addStack("Green", 10.0, 1) //should give utility 0.0 in weighted additive
|
---|
| 183 | // .addStack("Yellow", 10.0, 1)
|
---|
| 184 | // .addStack("Orange", 10.0, 1)
|
---|
| 185 | //---
|
---|
| 186 | // .addStack("Red", 1.0, 6)
|
---|
| 187 | // .addStack("Green", 3.0, 15)
|
---|
| 188 | // .addStack("Purple", 0.10, 10)
|
---|
| 189 | .build();
|
---|
| 190 | System.out.println(u.getUtility(offer));
|
---|
| 191 | }
|
---|
| 192 | }
|
---|
| 193 |
|
---|