/** * */ 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; /** * This utility function evaluates the utility of an offer based on its separate utilities regarding the ratio of its total price {@link UF_LessPrice} * with respect to the break even prices as well as the total deviation of the chips quantities {@link UF_CloseToQuantity} by considering the importance of price vs. quantity. * * To this end, this function adapts the `Intensification' concept in Fuzzy logic [1] depending the value (below or above 0.5) of the above mentioned separate utilities. * The values below 0.5 are more decreased (using 2*value^2); however, the values above 0.5 are more increased (using 1-2*(1-value)^2). * * And, if price is more important than quantity, but the price utility has been below 0.5, then the respected total utility would also be decreased; otherwise, it would be increased. * The similar scenario would hold for the quantity. * * * [1] Lotfi-Ali Asgar-Zadeh, Fuzzy sets, Information and control 8 (3), 338-353 (1965). * * * @author Faria Nassiri-Mofakham * */ public class UF_IntensifiedLessPriceCloseToQuantity implements UtilityFunction { private WishList wishlist; private ChipIssueValue breakEvenPrices; private boolean priceVSquantity; // true, if `less price' is more important; // false, if `close to quantity' is important. public UF_IntensifiedLessPriceCloseToQuantity(WishList w, ChipIssueValue bEP, boolean pVSq) { this.wishlist = w; this.breakEvenPrices = bEP; this.priceVSquantity = pVSq; } @Override public Double getUtility(Bundle b) { int totalDeviationQ = 0; double desiredP=0.0; for (Chip c : wishlist) { int desiredQ = wishlist.getQuantity(c); Integer offeredQ = b.getQuantity(c); if (offeredQ == null) offeredQ = 0; int deviationOfferedQ = Math.abs(desiredQ - offeredQ); totalDeviationQ += deviationOfferedQ; desiredP += ((c!=null) ? breakEvenPrices.getUnitValue(c) : 0.0); } double offeredP = ((b!=null) ? b.getTotalPrice() : 0.0); if (offeredP > desiredP) { //System.out.println("offeredPrice "+ offeredP + " > desiredPrice "+ desiredP); return 0.0; } double uP = 1.0 - offeredP/desiredP; double uQ = 1.0 / (1 + totalDeviationQ); //System.out.println("uP "+uP+"\n"+"uQ "+uQ); double u = ( priceVSquantity ? ( (uP < 0.5) ? ( (uQ < 0.5) ? Math.pow(2*Math.pow(uP, 2), 1-uQ) : Math.pow(1-2*Math.pow(1-uP, 2), uQ) ) : Math.pow(1-2*Math.pow(1-uP, 2), 1-uQ) ) : ( (uQ < 0.5) ? ( (uP < 0.5) ? Math.pow(2*Math.pow(uQ, 2), 1-uP) : Math.pow(1-2*Math.pow(1-uQ, 2), uP) ) : Math.pow(1-2*Math.pow(1-uQ, 2), 1-uP) ) ); return (Double.isNaN(u) ? 0.0 : u); } @Override public String toString() { return this.getClass().getSimpleName() + ": WishList " + wishlist.toString() + ": BreakEvenPrices "+ breakEvenPrices.toString()+ ": Price Vs. Quantity "+ (priceVSquantity? " `Price'" : " `Quantity'"); } public static void main(String[] args) { //boolean pq=true; WishList wishlist1 = new WishListBuilder().addWish("Red", 7).addWish("Green", 5).build(); ChipIssueValue prices1 = new ChipIssueValueBuilder().addIssue("Red", 100.0).addIssue("Green", 200.0).addIssue("Blue", 700.0).build(); UF_IntensifiedLessPriceCloseToQuantity u11 = new UF_IntensifiedLessPriceCloseToQuantity(wishlist1, prices1, true); UF_IntensifiedLessPriceCloseToQuantity u12 = new UF_IntensifiedLessPriceCloseToQuantity(wishlist1, prices1, false); WishList wishlist2 = new WishListBuilder().addWish("Red", 7).addWish("Green", 5).build(); ChipIssueValue prices2 = new ChipIssueValueBuilder().addIssue("Red", 10.0).addIssue("Green", 20.0).addIssue("Blue", 70.0).build(); UF_IntensifiedLessPriceCloseToQuantity u21 = new UF_IntensifiedLessPriceCloseToQuantity(wishlist2, prices2, true); UF_IntensifiedLessPriceCloseToQuantity u22 = new UF_IntensifiedLessPriceCloseToQuantity(wishlist2, prices2, false); WishList wishlist3 = new WishListBuilder().addWish("Green", 4).addWish("Yellow", 6).addWish("Orange", 40).build(); ChipIssueValue prices3 = new ChipIssueValueBuilder().addIssue("Green", 3.0).addIssue("Yellow", 5.0).addIssue("Orange", 1.0).build(); UF_IntensifiedLessPriceCloseToQuantity u31 = new UF_IntensifiedLessPriceCloseToQuantity(wishlist3, prices3, true); UF_IntensifiedLessPriceCloseToQuantity u32 = new UF_IntensifiedLessPriceCloseToQuantity(wishlist3, prices3, false); Bundle offer1 = new BundleBuilder() .addStack("Red", 1.0, 6) .addStack("Green", 3.0, 15) .addStack("Purple", 0.10, 10) .build(); Bundle offer2 = new BundleBuilder() .addStack("Red", 1.0, 1) .addStack("Green", 3.0, 1) .addStack("Purple", 0.10, 1) .build(); Bundle offer3 = new BundleBuilder() // .addStack("Green", 2.0, 3) // .addStack("Yellow", 5.0, 4) // .addStack("Orange", 1.0, 17) //--- .addStack("Green", 3.0, 4) .addStack("Yellow", 5.0, 6) .addStack("Orange", 1.0, 40) //--- // .addStack("Green", 10.0, 1) // .addStack("Yellow", 10.0, 1) // .addStack("Orange", 10.0, 1) .build(); System.out.println("\nu11 : "+u11 +"\nOffer1 = "+offer1); System.out.println("=> "+u11.getUtility(offer1)); System.out.println("\nu11 : "+u11 +"\nOffer2 = "+offer2); System.out.println("=> "+u11.getUtility(offer2)); System.out.println("\nu11 : "+u11 +"\nOffer3 = "+offer3); System.out.println("=> "+u11.getUtility(offer3)); System.out.println("\nu12 : "+u12 +"\nOffer1 = "+offer1); System.out.println("=> "+u12.getUtility(offer1)); System.out.println("\nu12 : "+u12 +"\nOffer2 = "+offer2); System.out.println("=> "+u12.getUtility(offer2)); System.out.println("\nu12 : "+u12 +"\nOffer3 = "+offer3); System.out.println("=> "+u12.getUtility(offer3)); System.out.println("\nu21 : "+u21 +"\nOffer1 = "+offer1); System.out.println("=> "+u21.getUtility(offer1)); System.out.println("\nu21 : "+u21 +"\nOffer2 = "+offer2); System.out.println("=> "+u21.getUtility(offer2)); System.out.println("\nu21 : "+u21 +"\nOffer3 = "+offer3); System.out.println("=> "+u21.getUtility(offer3)); System.out.println("\nu22 : "+u22 +"\nOffer1 = "+offer1); System.out.println("=> "+u22.getUtility(offer1)); System.out.println("\nu22 : "+u22 +"\nOffer2 = "+offer2); System.out.println("=> "+u22.getUtility(offer2)); System.out.println("\nu22 : "+u22 +"\nOffer3 = "+offer3); System.out.println("=> "+u22.getUtility(offer3)); System.out.println("\nu31 : "+u31 +"\nOffer1 = "+offer1); System.out.println("=> "+u31.getUtility(offer1)); System.out.println("\nu31 : "+u31 +"\nOffer2 = "+offer2); System.out.println("=> "+u31.getUtility(offer2)); System.out.println("\nu31 : "+u31 +"\nOffer3 = "+offer3); System.out.println("=> "+u31.getUtility(offer3)); System.out.println("\nu32 : "+u32 +"\nOffer1 = "+offer1); System.out.println("=> "+u32.getUtility(offer1)); System.out.println("\nu32 : "+u32 +"\nOffer2 = "+offer2); System.out.println("=> "+u32.getUtility(offer2)); System.out.println("\nu32 : "+u32 +"\nOffer3 = "+offer3); System.out.println("=> "+u32.getUtility(offer3)); } }