/** * */ package bargainingchips.players; import java.util.List; import java.util.Random; import java.util.ArrayList; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import bargainingchips.ChipIssueValue; import bargainingchips.ChipIssueValueBuilder; import bargainingchips.NegotiationContext; import bargainingchips.actions.Offer; import bargainingchips.actions.OfferBy; import bargainingchips.messaging.coordination.CoordinationMessage; import bargainingchips.messaging.status.StatusMessage; import bargainingchips.protocol.AsynchronousOffersProtocol; import bargainingchips.utilityfunctions.UtilityFunction; import bargainingchips.wishlist.WishList; import bargainingchips.wishlist.WishListBuilder; //import bargainingchips.utilityfunctions.UF; import bargainingchips.utilityfunctions.UF_BezierPriceBezierQuantity; import bargainingchips.utilityfunctions.UF_BezierPriceGaussianQuantity; import bargainingchips.utilityfunctions.UF_CloseToQuantity; import bargainingchips.utilityfunctions.UF_IntensifiedLessPriceCloseToQuantity; import bargainingchips.utilityfunctions.UF_LessPrice; import bargainingchips.utilityfunctions.UF_LessPriceCloseToQuantity; import bargainingchips.utilityfunctions.UF_PeakedFlatCurvePriceGaussianQuantity; import bargainingchips.utilityfunctions.UF_PeakedFlatPricePeakedFlatQuantity; import bargainingchips.utilityfunctions.UF_PeakedPricePeakedQuantity; /** * The {@link Buyer} class is extended in a way that the buyer negotiators could be created by using different random utility functions among * UF_CloseToQuantity, UF_LessPrice, UF_LessPriceCloseToQuantity, UF_IntensifiedLessPriceCloseToQuantity, UF_PeakedPricePeakedQuantity, * UF_PeakedFlatPricePeakedFlatQuantity, UF_PeakedFlatCurvePriceGaussianQuantity, UF_BezierPriceBezierQuantity, and * UF_BezierPriceGaussianQuantity, where the first function takes only quantity into account, * the second function considers only price, but all the others deal with both price and quantity, receive different numbers of parameters, * and consider the importance of issues (i.e., for price, quantity, etc.) as well as the importance of Chips (i.e., colors) with respect to each other. * It also created buyer negotiators using either Boulware or Bargaining (based on NiceTitForTat) negotiation strategies. * * * @author Faria Nassiri-Mofakham * */ public class BargainingBuyer { private Coordinator c; private BlockingQueue cin; private BlockingQueue cout; private List threads; public BargainingBuyer(WishList overallWishlist)//, ChipIssueValue breakEvenPrices, boolean priceVSQuantity) { cin = new LinkedBlockingQueue(); cout = new LinkedBlockingQueue(); // Coordinator c = new Coordinator(overallWishlist, cout, cin); threads = new ArrayList(); } public void connectSeller(String sellerName, WishList wishlistSam) { // Set up the protocol BlockingQueue from = new LinkedBlockingQueue(); BlockingQueue toBuyer = new LinkedBlockingQueue(); BlockingQueue toSeller = new LinkedBlockingQueue(); String bobiName = "Bob" + " " + getThreadNumber(); AsynchronousOffersProtocol aop = new AsynchronousOffersProtocol(from, bobiName, toBuyer, sellerName, toSeller); NegotiationContext context = new NegotiationContext(); // Make a new subnegotiator WishList wishlist = new WishListBuilder().addWish("Green", 4).addWish("Yellow", 6).addWish("Orange", 40).build(); ChipIssueValue breakEvenPrices = new ChipIssueValueBuilder().addIssue("Green", 3.0).addIssue("Yellow", 5.0).addIssue("Orange", 1.0).build(); ChipIssueValue prices1 = new ChipIssueValueBuilder().addIssue("Green", new Double[] {3.0, 4.8}).addIssue("Yellow", new Double[] {5.0, 8.0}).addIssue("Orange", new Double[] {1.0, 2.5}).build(); ChipIssueValue uPrices1 = new ChipIssueValueBuilder().addIssue("Green", 1.0).addIssue("Yellow", 0.8).addIssue("Orange", 0.75).build(); ChipIssueValue deviations1 = new ChipIssueValueBuilder().addIssue("Green", 1).addIssue("Yellow", 1).addIssue("Orange", 10).build(); ChipIssueValue prices2 = new ChipIssueValueBuilder().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(); ChipIssueValue uPrices2 = new ChipIssueValueBuilder().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(); ChipIssueValue deviations2 = new ChipIssueValueBuilder().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(); ChipIssueValue uDev2 = new ChipIssueValueBuilder().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(); ChipIssueValue deviations3 = new ChipIssueValueBuilder().addIssue("Green", new Integer[] {2,1,2,3}).addIssue("Yellow", new Integer[] {3,2,2,3}).addIssue("Orange", new Integer[] {10,2,5,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; boolean pq = ( (wP > wQ) ? true : false); // true, if less price is more important; false, if close to quantity is important. // boolean pq = ((new Random().nextInt(2)+1 == 1) ? true : false); int m=4; // input Bezier points //One utility function is assigned to bobi, in random // UtilityFunction u = new UF(wishlist, breakEvenPrices, prices1, uPrices1, deviations1, uPrices2, prices2, deviations2, uDev2, deviations3, wC, wP, wQ, pq, m ); UtilityFunction u = null; switch(new Random().nextInt(9)+1) { case 1: u = new UF_CloseToQuantity(wishlist); break; case 2: u = new UF_LessPrice(wishlist, breakEvenPrices); break; case 3: u = new UF_LessPriceCloseToQuantity(wishlist, breakEvenPrices); break; case 4: u = new UF_IntensifiedLessPriceCloseToQuantity(wishlist, breakEvenPrices, pq); break; case 5: u = new UF_PeakedPricePeakedQuantity(wishlist, breakEvenPrices, deviations1, wC, wP, wQ); break; case 6: u = new UF_PeakedFlatPricePeakedFlatQuantity(wishlist, deviations2, uDev2, prices2, uPrices2, wC, wP, wQ); break; case 7: u = new UF_PeakedFlatCurvePriceGaussianQuantity(wishlist, prices1, uPrices1, deviations1, wC, wP, wQ); break; case 8: u = new UF_BezierPriceBezierQuantity (wishlist, m, prices2, deviations3, wC, wP, wQ); break; case 9: u = new UF_BezierPriceGaussianQuantity (wishlist, m, prices2, deviations1, wC, wP, wQ); break; } Agent bobi = ((new Random().nextInt(2)+1 == 1) ? new BoulwareAgent(bobiName, u, context, toBuyer, from, cin, cout) : new BargainingAgent(bobiName, u, context, toBuyer, from, cin, cout)); // Seller UtilityFunction uSam = new UF_CloseToQuantity(wishlistSam); Agent sam = new BasicAgent(sellerName, uSam, context, toSeller, from); // The thread NegotiationThread thread = new NegotiationThread(); thread.protocol = aop; thread.subbuyer = bobi; thread.seller = sam; threads.add(thread); } public void startThreads() { // Start the coordinator once Thread threadCoordinator = new Thread(c); threadCoordinator.start(); // Start all threads: subnegotiator + protocol + seller for (NegotiationThread t : threads) { System.out.println(t.subbuyer.toDescription()); System.out.println("playing vs"); System.out.println(t.seller.toDescription()); Thread aopThread = new Thread(t.protocol); aopThread.start(); Thread threadBuyer = new Thread(t.subbuyer); threadBuyer.start(); Thread threadSeller = new Thread(t.seller); threadSeller.start(); } } private int getThreadNumber() { return threads.size(); } }