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 | //import bargainingchips.utilityfunctions.helperMethods;
|
---|
12 |
|
---|
13 | /**
|
---|
14 | *
|
---|
15 | * This utility function inputs {@link wishList} (i.e., quantity of each desired {@link Chip}), and price per each
|
---|
16 | * {@link Chip} as peaked curves.
|
---|
17 | * For quantity, the buyer may accept, with degrees of satisfaction, offered quantity around the peak, which is
|
---|
18 | * determined by the deviation from the peak per each {@link Chip}. It is in a Guassian form.
|
---|
19 | * For the price, the buyer would designate a series of `n' prices per each {@link Chip}, and then a
|
---|
20 | * Bezier function (of rank `n') is applied to determine the value of the offered price. That is the buyer inputs
|
---|
21 | * an array of prices per each desired {@link Chip} (i.e., in {@link wishList}). The prices could be in integer or
|
---|
22 | * real format, determined by type T[] (i.e, `Integer[]' or `Double[]', etc).
|
---|
23 | * It is worth to mention that this function considers the importance of issues (i.e., for price, quantity, etc.)
|
---|
24 | * as well as the importance of Chips (i.e., colors) with respect to each other.
|
---|
25 | *
|
---|
26 | *
|
---|
27 | * @author Faria Nassiri-Mofakham
|
---|
28 | *
|
---|
29 | */
|
---|
30 |
|
---|
31 | public class UF_BezierPriceGaussianQuantity<T> implements UtilityFunction {
|
---|
32 | // `T' for the type of price data points, and `n' for the number of data points
|
---|
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<Integer> qtyDeviation; // sigma_c. A symmetric deviation for quantities less than or more than the exact qty per chip.
|
---|
37 | private int n; // number of price data points at Bezier curve
|
---|
38 | private ChipIssueValue<T[]> bezierPrice; // list of `n' data points of type T determining the price curve
|
---|
39 | private ChipIssueValue<Double> lambdaC; // kappa_c and lambda_c
|
---|
40 | private double lambdaP,lambdaQ; // lambda_p and lambda_q
|
---|
41 |
|
---|
42 |
|
---|
43 | public UF_BezierPriceGaussianQuantity(WishList w, int m, ChipIssueValue<T[]> bz, ChipIssueValue<Integer> qtyDev, ChipIssueValue<Double> lc, double lp, double lq)
|
---|
44 | {
|
---|
45 | wishlist=w;
|
---|
46 | qtyDeviation=qtyDev;
|
---|
47 | n=m;
|
---|
48 | bezierPrice=bz;
|
---|
49 | lambdaC=lc;
|
---|
50 | lambdaP=lp;
|
---|
51 | lambdaQ=lq;
|
---|
52 | }
|
---|
53 |
|
---|
54 | @Override
|
---|
55 | public Double getUtility(Bundle b)
|
---|
56 | {
|
---|
57 | double sumWeightedPrice = 0.0;
|
---|
58 | double sumWeightedQty = 0.0;
|
---|
59 |
|
---|
60 | if (b!=null)
|
---|
61 | {
|
---|
62 | for (Chip c : wishlist)
|
---|
63 | {
|
---|
64 | int desiredQ = wishlist.getQuantity(c);
|
---|
65 |
|
---|
66 | T[] desiredP = bezierPrice.getUnitValue(c);
|
---|
67 | if (desiredP.length > n)
|
---|
68 | throw new IllegalStateException("\n\n[Warning] UF_BezierPriceAndGaussianQuantity::getUtility(Bundle). Input only "+n+" price data points! "+ desiredP);
|
---|
69 |
|
---|
70 | Double importanceC= lambdaC.getUnitValue(c);
|
---|
71 | int devC= qtyDeviation.getUnitValue(c);
|
---|
72 |
|
---|
73 | Integer offeredQ = b.getQuantity(c);
|
---|
74 | if (offeredQ == null)
|
---|
75 | offeredQ = 0;
|
---|
76 | Double offeredP= b.getUnitPrice(c);
|
---|
77 |
|
---|
78 | sumWeightedPrice += importanceC * bezier(desiredP, offeredP);
|
---|
79 | sumWeightedQty += importanceC / (devC * 2 * Math.sqrt(Math.PI)) * Math.pow(Math.E, -0.5 * Math.pow((offeredQ - desiredQ)/devC, 2));
|
---|
80 | }
|
---|
81 | double u = lambdaP * sumWeightedPrice + lambdaQ * sumWeightedQty;
|
---|
82 | return ( (u>1) ? 1 : ( (u<0) ? 0 : u) );
|
---|
83 | }
|
---|
84 | return 0.0;
|
---|
85 | }
|
---|
86 |
|
---|
87 | /**
|
---|
88 | * @param input parameter (e.g., an offered price per a {@link Chip},
|
---|
89 | * and `n' data points of type T (e.g., as of Double[], Integer[], etc).
|
---|
90 | *
|
---|
91 | * @return Bezier value of rank `n' for the offered parameter.
|
---|
92 | **/
|
---|
93 | private double bezier(T[] desired, Double offered)
|
---|
94 | {
|
---|
95 | double bez = 0.0;
|
---|
96 | // n is desired.length;
|
---|
97 | for (int i=0; i<n; i++)
|
---|
98 | {
|
---|
99 | bez = ( (offered < (double) desired[0]) ? 1.0 : ( (offered > (double) desired[n-1]) ? 0.0 : comb(n,i)*Math.pow(1-offered, n)*Math.pow(i, n)*(double)desired[i]));
|
---|
100 | }
|
---|
101 | return ( (bez>1) ? 1 : (bez<0) ? 0 : bez);
|
---|
102 | }
|
---|
103 |
|
---|
104 | /**
|
---|
105 | * @return combination of `m' and `k'
|
---|
106 | **/
|
---|
107 | private int comb(int m, int k)
|
---|
108 | {
|
---|
109 | return fc(m)/(fc(m-k)*fc(k));
|
---|
110 | }
|
---|
111 |
|
---|
112 | /**
|
---|
113 | * @return factorial of `m'
|
---|
114 | **/
|
---|
115 | private int fc(int m) {
|
---|
116 | int result = 1;
|
---|
117 | for (; m > 1; m--) {
|
---|
118 | result *= m;
|
---|
119 | }
|
---|
120 | return result;
|
---|
121 | }
|
---|
122 |
|
---|
123 | /**
|
---|
124 | * @return an String list of values assigned to a single variable, e.g. list of quantities or prices of a {@link Chip}
|
---|
125 | **/
|
---|
126 | private String writeT(ChipIssueValue<T[]> t)
|
---|
127 | {
|
---|
128 | String s = "{";
|
---|
129 | T[] j;
|
---|
130 | if (t!=null)
|
---|
131 | {
|
---|
132 | for (Chip c: t)
|
---|
133 | {
|
---|
134 | s += " " + c.toString() + "={";
|
---|
135 | j = t.getUnitValue(c);
|
---|
136 | for (int k=0; k<j.length; k++)
|
---|
137 | s += j[k].toString()+((k<j.length-1) ? ", " : "");
|
---|
138 | s += "}";
|
---|
139 | }
|
---|
140 | }
|
---|
141 | s += " }";
|
---|
142 | return s;
|
---|
143 | }
|
---|
144 |
|
---|
145 | @Override
|
---|
146 | public String toString()
|
---|
147 | {
|
---|
148 | return this.getClass().getSimpleName() + ": WishList " + wishlist + ": BezierPrice "+ writeT(bezierPrice)+ ": QtyDeviations "+ qtyDeviation + ": Colors' weights "+ lambdaC + ": Issue Price's weight "+ lambdaP + ": Issue Quantity's weight " + lambdaQ;
|
---|
149 | }
|
---|
150 |
|
---|
151 | public static void main(String[] args)
|
---|
152 | {
|
---|
153 | WishList wishlist = new WishListBuilder().addWish("Green", 4).addWish("Yellow", 6).addWish("Orange", 40).build();
|
---|
154 | int m=4;
|
---|
155 | 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();
|
---|
156 | ChipIssueValue<Integer> deviations = new ChipIssueValueBuilder<Integer>().addIssue("Green", 1).addIssue("Yellow", 1).addIssue("Orange", 10).build();
|
---|
157 | ChipIssueValue<Double> wC = new ChipIssueValueBuilder<Double>().addIssue("Green", 0.5).addIssue("Yellow", 0.3).addIssue("Orange", 0.2).build();
|
---|
158 | double wP = 0.6;
|
---|
159 | double wQ = 0.4;
|
---|
160 |
|
---|
161 | UF_BezierPriceGaussianQuantity<Double> u = new UF_BezierPriceGaussianQuantity<Double> (wishlist, m, prices, deviations, wC, wP, wQ);
|
---|
162 | System.out.println(u);
|
---|
163 |
|
---|
164 | Bundle offer = new BundleBuilder()
|
---|
165 | .addStack("Green", 2.0, 3)
|
---|
166 | .addStack("Yellow", 5.0, 4)
|
---|
167 | .addStack("Orange", 1.0, 17)
|
---|
168 | //---
|
---|
169 | // .addStack("Green", 3.0, 4) //should give utility 1.0 in weighted additive
|
---|
170 | // .addStack("Yellow", 5.0, 6)
|
---|
171 | // .addStack("Orange", 1.0, 40)
|
---|
172 | //---
|
---|
173 | // .addStack("Green", 10.0, 1) //should give utility 0.0 in weighted additive
|
---|
174 | // .addStack("Yellow", 10.0, 1)
|
---|
175 | // .addStack("Orange", 10.0, 1)
|
---|
176 | //---
|
---|
177 | // .addStack("Red", 1.0, 6)
|
---|
178 | // .addStack("Green", 3.0, 15)
|
---|
179 | // .addStack("Purple", 0.10, 10)
|
---|
180 | .build();
|
---|
181 | System.out.println(u.getUtility(offer));
|
---|
182 | }
|
---|
183 | }
|
---|
184 |
|
---|
185 |
|
---|