package bargainingchips.utilityfunctions; import bargainingchips.Bundle; import bargainingchips.BundleBuilder; import bargainingchips.Chip; import bargainingchips.ChipIssueValue; import bargainingchips.ChipIssueValueBuilder; import bargainingchips.wishlist.WishList; import bargainingchips.wishlist.WishListBuilder; /** * * According to Equation (1), the buyer with peaked utility function evaluates bundles with price 0, as 1.0, and any price greater than the total break even unit price of the chips in the bundle, as 0.0. * For any other price between the two, she follows a linear downward function. However, regarding the quantity she checks per chip, so that if the quantity of the chip is equal to what she wished, it gets 1.0. * She may tolerate a deviation around this desired quantity. Any quantity outside this range would be evaluated as 0.0. The quantities within this range would be evaluated via a linear downward function and linear * upward function respectively for quantities more than or less than the desired quantity, both with a peak at the desired quantity. * * UF_peaked ignores any color which is not introduced in wishlist (i.e., free disposal) and takes the following values as input: * \phi_c, \kappa_c, \sigma_c, and \lambda_c, respectively the break even unit price, the exact quantity, the acceptable deviation around \kappa_c, * the importance of the chip with color c, * p_c, q_c, \lambda_q, and \lambda_p, respectively the unit price, quantity of the chip with color c and the importance of quantity and price in offer \omega * * And outputs u(\omega), where \omega is the offer to evaluate. * * * Equation (1): * * UF_PeakedPricePeakedQuantity(Bundle \omega) = \lambda_p [ 1 - ( \sum{\lambda_c * \phi_c * \kappa_c} * - \sum{\lambda_c * p_c * q_c}) / \sum{\lambda_c * \phi_c * \kappa_c} ] * + \lambda_q [ \lambda_c * \psi_c * (\kappa_c + \psi_c * \sigma_c - q_c) / \sigma_c ] * * where, * \psi_c = 1, if q_c >= \kappa_c, otherwise, \psi_c = -1. * \lambda_p + \lambda_q = 1 * \sum{\lambda_c} = 1 * * * * @author Faria Nassiri-Mofakham * */ public class UF_PeakedPricePeakedQuantity implements UtilityFunction { private WishList wishlist; // q_c // Other parts of the buyer's preferences are assigned with desirability degrees of a variety of prices and quantities per each Chip. private ChipIssueValue qtyDeviation; // sigma_c. Assuming a symmetric deviation. Of course, two different deviation could also be considered // for quantities less or more than the exact qty per chip private ChipIssueValue breakEvenPrice, lambdaC; // kappa_c and lambda_c private double lambdaP,lambdaQ; // lambda_p and lambda_q public UF_PeakedPricePeakedQuantity(WishList w, ChipIssueValue bEP, ChipIssueValue qtyDev, ChipIssueValue lc, double lp, double lq) { wishlist=w; qtyDeviation=qtyDev; breakEvenPrice=bEP; lambdaC=lc; lambdaP=lp; lambdaQ=lq; } @Override public Double getUtility(Bundle b) { double sumWeightedPriceOffered=0.0; double sumWeightedPriceDesired=0.0; double sumWeightedQty=0.0; if (b!=null) { for (Chip c : wishlist) { int desiredQ = wishlist.getQuantity(c); Double desiredP= breakEvenPrice.getUnitValue(c); Double importanceC= lambdaC.getUnitValue(c); int devC= qtyDeviation.getUnitValue(c); Integer offeredQ = b.getQuantity(c); if (offeredQ == null) offeredQ = 0; Double offeredP= b.getUnitPrice(c); int mC = ((offeredQ >= desiredQ) ? 1 : -1); sumWeightedPriceOffered += importanceC * offeredP * offeredQ; sumWeightedPriceDesired += importanceC * desiredP * desiredQ; sumWeightedQty += importanceC * mC * (desiredQ + mC * devC - offeredQ)/devC; } double u = lambdaP * (1 - (sumWeightedPriceOffered-sumWeightedPriceDesired)/sumWeightedPriceDesired) + lambdaQ * sumWeightedQty; //after changing the signs of sums return ( (u>1) ? 1 : ( (u<0) ? 0 : u) ); } return 0.0; } @Override public String toString() { return this.getClass().getSimpleName() + ": WishList " + wishlist + ": BreakEvenPrices "+ breakEvenPrice.toString()+ ": QtyDeviations "+ qtyDeviation + ": Colors' weights "+ lambdaC + ": Issue Price's weight "+ lambdaP + ": Issue Quantity's weight " + lambdaQ; } public static void main(String[] args) { WishList wishlist = new WishListBuilder().addWish("Green", 4).addWish("Yellow", 6).addWish("Orange", 40).build(); ChipIssueValue prices = new ChipIssueValueBuilder().addIssue("Green", 3.0).addIssue("Yellow", 5.0).addIssue("Orange", 1.0).build(); ChipIssueValue deviations = new ChipIssueValueBuilder().addIssue("Green", 1).addIssue("Yellow", 1).addIssue("Orange", 10).build(); ChipIssueValue wC = new ChipIssueValueBuilder().addIssue("Green", 0.5).addIssue("Yellow", 0.3).addIssue("Orange", 0.2).build(); double wP = 0.6; double wQ = 0.4; UF_PeakedPricePeakedQuantity u = new UF_PeakedPricePeakedQuantity (wishlist, prices, deviations, wC, wP, wQ); System.out.println(u); Bundle offer = new BundleBuilder() .addStack("Green", 2.0, 3) .addStack("Yellow", 5.0, 4) .addStack("Orange", 1.0, 17) //--- // .addStack("Green", 3.0, 4) //should give utility 1.0 // .addStack("Yellow", 5.0, 6) // .addStack("Orange", 1.0, 40) //--- // .addStack("Green", 10.0, 1) //should give utility 0.0 // .addStack("Yellow", 10.0, 1) // .addStack("Orange", 10.0, 1) //--- // .addStack("Red", 1.0, 6) // .addStack("Green", 3.0, 15) // .addStack("Purple", 0.10, 10) .build(); System.out.println(u.getUtility(offer)); } }