[74] | 1 | from math import *
|
---|
| 2 |
|
---|
| 3 | # Here is some of the code we wrote during the development of the agent,
|
---|
| 4 | # which we did not use in the final version
|
---|
| 5 |
|
---|
| 6 | """
|
---|
| 7 | Counts the number of occurrences of each issue in opponent's bid, and
|
---|
| 8 | determines the best value for each issue
|
---|
| 9 | """
|
---|
| 10 | def get_opponent_info(self):
|
---|
| 11 | prev_bids = self.all_bids
|
---|
| 12 | if len(prev_bids) < 2:
|
---|
| 13 | return None
|
---|
| 14 |
|
---|
| 15 | # prev_bids.sort(key=lambda x: x[1])
|
---|
| 16 | issues = self._last_received_bid.getIssues()
|
---|
| 17 |
|
---|
| 18 | demanded_best_offer = {}
|
---|
| 19 | for issue in issues:
|
---|
| 20 | issue_value_opponent = {}
|
---|
| 21 | for i in range(len(prev_bids)):
|
---|
| 22 | bid = prev_bids[i][0]
|
---|
| 23 | val = bid.getValue(issue)
|
---|
| 24 | if val in issue_value_opponent:
|
---|
| 25 | issue_value_opponent[val] = issue_value_opponent[val] + 1
|
---|
| 26 | else:
|
---|
| 27 | issue_value_opponent[val] = 1
|
---|
| 28 |
|
---|
| 29 | sorted_dict = dict(sorted(issue_value_opponent.items(), key=lambda item: item[1]))
|
---|
| 30 | opponent_val = list(sorted_dict.keys())[-1]
|
---|
| 31 | demanded_best_offer[issue] = opponent_val
|
---|
| 32 |
|
---|
| 33 | return demanded_best_offer
|
---|
| 34 |
|
---|
| 35 | """
|
---|
| 36 | Adds the values of issues found in opponent's offer in a global object.
|
---|
| 37 | """
|
---|
| 38 | def get_opponent_preference(self):
|
---|
| 39 | first_bid = self.all_bids[0][0]
|
---|
| 40 |
|
---|
| 41 | for issue in first_bid.getIssues():
|
---|
| 42 | self.opponent_preferences.append((issue, first_bid.getValue(issue)))
|
---|
| 43 |
|
---|
| 44 | """
|
---|
| 45 | Sigmoid function
|
---|
| 46 |
|
---|
| 47 | Parameters
|
---|
| 48 | ----------
|
---|
| 49 | x: negotiation progress
|
---|
| 50 | """
|
---|
| 51 |
|
---|
| 52 | def sigmoid(self, x):
|
---|
| 53 | return - 1 / (1 + exp(-5 * x + 5)) + 0.95
|
---|
| 54 |
|
---|
| 55 | """
|
---|
| 56 | Method for deciding whether an offer is good based on a sigmoid function
|
---|
| 57 |
|
---|
| 58 | Parameters
|
---|
| 59 | ----------
|
---|
| 60 | bid: the offer that is received/ to be send
|
---|
| 61 | """
|
---|
| 62 |
|
---|
| 63 | def _isGoodSigmoid(self, bid: Bid) -> bool:
|
---|
| 64 | if bid is None:
|
---|
| 65 | return False
|
---|
| 66 |
|
---|
| 67 | profile = self._profile.getProfile()
|
---|
| 68 | progress = self._progress.get(time.time() * 1000)
|
---|
| 69 |
|
---|
| 70 | if float(profile.getUtility(bid)) > self.sigmoid(progress):
|
---|
| 71 | return True
|
---|
| 72 | return False
|
---|
| 73 |
|
---|
| 74 | """
|
---|
| 75 | Finds the good bids from all bids.
|
---|
| 76 | """
|
---|
| 77 | def find_all_good_bids(self):
|
---|
| 78 | domain = self._profile.getProfile().getDomain()
|
---|
| 79 | all_bids = AllBidsList(domain)
|
---|
| 80 |
|
---|
| 81 | for bid in all_bids:
|
---|
| 82 | if self._isGood(bid):
|
---|
| 83 | self.all_good_bids.append(bid)
|
---|
| 84 |
|
---|
| 85 | """
|
---|
| 86 | Selects all favorable bids for the opponent based on issues that are not important to us,
|
---|
| 87 | but we consider them to be important fo the opponent.
|
---|
| 88 | """
|
---|
| 89 | def get_all_suitable_bids(self):
|
---|
| 90 | domain = self._profile.getProfile().getDomain()
|
---|
| 91 | all_bids = AllBidsList(domain)
|
---|
| 92 |
|
---|
| 93 | opponent_desired_bid = self.get_opponent_info_good()
|
---|
| 94 | not_important_issues = self.not_important_issues
|
---|
| 95 |
|
---|
| 96 | bids_with_utility = []
|
---|
| 97 |
|
---|
| 98 | for bid in all_bids:
|
---|
| 99 | counter = 0
|
---|
| 100 | if opponent_desired_bid is not None:
|
---|
| 101 | for not_important_issue in not_important_issues:
|
---|
| 102 | if bid.getIssueValues().get(not_important_issue) == opponent_desired_bid.get(not_important_issue):
|
---|
| 103 | counter += 1
|
---|
| 104 |
|
---|
| 105 | if (opponent_desired_bid is not None or counter == len(not_important_issues)) and self._isGood(bid):
|
---|
| 106 | bids_with_utility.append((bid, self._profile.getProfile().getUtility(bid)))
|
---|
| 107 |
|
---|
| 108 | bids_with_utility = sorted(bids_with_utility, key=lambda item: -item[1])
|
---|
| 109 | return bids_with_utility
|
---|
| 110 |
|
---|
| 111 | """
|
---|
| 112 | Determines whether the opponent is repeating bids by checking
|
---|
| 113 | if the last 5 offers are the same.
|
---|
| 114 | """
|
---|
| 115 | def is_opponent_repeating_bids(self):
|
---|
| 116 | if len(self.all_bids) >= 5:
|
---|
| 117 | for i in range(1, 5):
|
---|
| 118 | if self.all_bids[-i] != self.all_bids[-i - 1]:
|
---|
| 119 | return False
|
---|
| 120 | return True
|
---|
| 121 | return False
|
---|
| 122 |
|
---|
| 123 | """
|
---|
| 124 | Searches for the smallest utility that is in the range between an utility that we think
|
---|
| 125 | is appropriate and 1.
|
---|
| 126 | """
|
---|
| 127 | def search_for_value(self, suggeseted_value_utility, issue):
|
---|
| 128 | max_val = 1
|
---|
| 129 | desired_value = ""
|
---|
| 130 | utilities = self._profile.getProfile().getUtilities()
|
---|
| 131 | all_values_for_issue = self._profile.getProfile().getDomain().getValues(issue)
|
---|
| 132 |
|
---|
| 133 | for v in all_values_for_issue:
|
---|
| 134 | value_utility = utilities.get(issue).getUtility(v)
|
---|
| 135 | if suggeseted_value_utility <= value_utility and value_utility <= max_val:
|
---|
| 136 | desired_value = v
|
---|
| 137 | max_val = value_utility
|
---|
| 138 | return desired_value
|
---|
| 139 |
|
---|