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;
|
---|
8 | import bargainingchips.wishlist.WishList;
|
---|
9 | import bargainingchips.wishlist.WishListBuilder;
|
---|
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 |
|
---|