source: CSE3210/agent18/acceptance_strategy.py

Last change on this file was 74, checked in by wouter, 21 months ago

#6 Added CSE3210 parties

File size: 4.7 KB
Line 
1import decimal
2
3import numpy as np
4
5
6class AcceptanceStrategy:
7 """
8 Contains acceptance strategies that agents can use. According to "Acceptance Conditions in Automated Negotiation"
9 (https://homepages.cwi.nl/~baarslag/pub/Acceptance_conditions_in_automated_negotiation.pdf) the following are the
10 best strategies ranked according the average utility for the agent:
11 1. combi_max_w
12 2. combi_avg_w
13 3. gap(0.1)
14 4. combi_max_t
15 5. time(0.99)
16 6. gap(0.2)
17 7. gap(0.05)
18 8. next(1.02, 0)
19 9. gap(0.02)
20 10. prev(1.02, 0)
21 11. next(1, 0)
22 12. prev(1, 0)
23 """
24
25 def __init__(self, progress, profile, rec_bid_hist=None, next_sent_bid=None, prev_sent_bid=None):
26 """
27 Constructs an acceptance strategy object.
28 @param progress: the current negotiation progress from 0 to 1 (essentially time).
29 @param rec_bid_hist: the history of all the opponent's bids so far.
30 """
31 self.progress = progress
32 self.profile = profile
33 if rec_bid_hist and len(rec_bid_hist) == 0:
34 Exception(f"Expected history of at least 1 bid but got 0")
35 elif rec_bid_hist:
36 self.rec_utility_hist = list(map(lambda bid: self.profile.getUtility(bid), rec_bid_hist))
37 self.rec_bid_hist = rec_bid_hist
38 self.last_rec_bid = rec_bid_hist[-1]
39 self.next_sent_bid = next_sent_bid
40 self.prev_sent_bid = prev_sent_bid
41
42 def combi_max_w(self, progress_thresh, scale, const):
43 """Combined strategy that checks a window of previously received bids"""
44 window = self._get_bid_window()
45 if len(window) != 0:
46 # Take the maximum of the bid window
47 alpha = np.max(window)
48 else:
49 alpha = 0
50 return self._combi(progress_thresh, alpha, scale, const)
51
52 def combi_avg_w(self, progress_thresh, scale, const):
53 """Combined strategy that checks a window of previously received bids"""
54 window = self._get_bid_window()
55 if len(window) != 0:
56 alpha = np.mean(window)
57 else:
58 alpha = 0
59 return self._combi(progress_thresh, alpha, scale, const)
60
61 def combi_max_t(self, progress_thresh, scale, const):
62 """Combined strategy that checks all previously received bids"""
63 alpha = np.max(self.rec_utility_hist)
64 return self._combi(progress_thresh, alpha, scale, const)
65
66 def _get_bid_window(self):
67 if self.progress == 0:
68 self.max_bids = 100
69 else:
70 # automatically figure out how many max bids there will be
71 self.max_bids = len(self.rec_utility_hist) // self.progress
72 num_bids = int(self.max_bids * self.progress)
73 remaining_bids = int(self.max_bids * (1 - self.progress))
74 # compute bounds of the bid window
75 bounds = np.clip([num_bids - remaining_bids, num_bids], 0, len(self.rec_utility_hist) - 1)
76 # print(bounds)
77 if bounds[1] < bounds[0]:
78 raise Exception("Invalid bounds")
79 return self.rec_utility_hist[bounds[0]: bounds[1]]
80
81 def _combi(self, progress_thresh, alpha, scale, const):
82 """Helper method for the combi acceptance strategy. According to research most effective with T = 0.99."""
83 early = self.next(scale, const)
84 late = self.time(progress_thresh) and self.profile.getUtility(self.last_rec_bid) >= alpha
85 # print(early, late)
86 return early or late
87
88 def gap(self, gap):
89 return self.prev(1, gap)
90
91 def time(self, progress_thresh):
92 """Accepts bids after a certain time period"""
93 return self.progress >= progress_thresh
94
95 def next(self, scale_factor, utility_gap):
96 """Accepts bids better the next bids that should be sent"""
97 # print(f"|| Next sent for agent {hash(self.profile)}: {self.profile.getUtility(self.next_sent_bid)}")
98 return decimal.Decimal(scale_factor) * self.profile.getUtility(self.last_rec_bid) \
99 + decimal.Decimal(utility_gap) >= self.profile.getUtility(self.next_sent_bid)
100
101 def prev(self, scale_factor, utility_gap):
102 """Accepts bids better than the previous bid that has been sent"""
103 return decimal.Decimal(scale_factor) * self.profile.getUtility(self.last_rec_bid) \
104 + decimal.Decimal(utility_gap) >= self.profile.getUtility(self.prev_sent_bid)
105
106 def const(self, utility_thresh):
107 """Accepts bids over a utility threshold"""
108 return self.profile.getUtility(self.last_rec_bid) > utility_thresh
109
110 def IAMHaggler(self):
111 return self.const(0.88) and self.next(1.02, 0) and self.prev(1.02, 0)
Note: See TracBrowser for help on using the repository browser.