def start_negotiations( self, product: int, quantity: int, unit_price: int, time: int, to_buy: bool ) -> None: """ Starts a set of negotiations to by/sell the product with the given limits Args: product: product type. If it is an input product, negotiations to buy it will be started otherweise to sell. quantity: The maximum quantity to negotiate about unit_price: The maximum/minimum unit price for buy/sell time: The maximum/minimum time for buy/sell to_buy: Is the negotiation to buy or to sell Remarks: - This method assumes that products cannot be in my_input_products and my_output_products """ if quantity < 1 or unit_price < 1 or time < self.awi.current_step + 1: self.awi.logdebug( f"Less than 2 valid issues (q:{quantity}, u:{unit_price}, t:{time})" ) return # choose ranges for the negotiation agenda. cprice = self.awi.catalog_prices[product] qvalues = (1, quantity) if to_buy: uvalues = (1, cprice) tvalues = (self.awi.current_step + 1, time - 1) partners = self.awi.all_suppliers[product] else: uvalues = (cprice, 2 * cprice) tvalues = (time + 1, self.awi.n_steps - 1) partners = self.awi.all_consumers[product] issues = [ Issue(qvalues, name="quantity", value_type=int), Issue(tvalues, name="time", value_type=int), Issue(uvalues, name="unit_price", value_type=int), ] if Issue.num_outcomes(issues) < 2: self.awi.logdebug( f"Less than 2 issues for product {product}: {[str(_) for _ in issues]}" ) return # negotiate with all suppliers of the input product I need to produce for partner in partners: self.awi.request_negotiation( is_buy=to_buy, product=product, quantity=qvalues, unit_price=uvalues, time=tvalues, partner=partner, negotiator=self.negotiator(not to_buy, issues=issues), )
def on_ufun_changed(self): super().on_ufun_changed() presort = self.presort if (not presort and all(i.is_countable() for i in self._ami.issues) and Issue.num_outcomes( self._ami.issues) >= self.n_outcomes_to_force_presort): presort = True if presort: outcomes = self._ami.discrete_outcomes() uvals = self.utility_function.eval_all(outcomes) uvals_outcomes = [(u, o) for u, o in zip(uvals, outcomes) if u >= self.utility_function.reserved_value] self.ordered_outcomes = sorted( uvals_outcomes, key=lambda x: float(x[0]) if x[0] is not None else float("-inf"), reverse=True, ) if self.assume_normalized: self.ufun_min, self.ufun_max = 0.0, 1.0 elif len(self.ordered_outcomes) < 1: self.ufun_max = self.ufun_min = self.utility_function.reserved_value else: if self.ufun_max is None: self.ufun_max = self.ordered_outcomes[0][0] if self.ufun_min is None: # we set the minimum utility to the minimum finite value above both reserved_value for j in range(len(self.ordered_outcomes) - 1, -1, -1): self.ufun_min = self.ordered_outcomes[j][0] if self.ufun_min is not None and self.ufun_min > float( "-inf"): break if (self.ufun_min is not None and self.ufun_min < self.reserved_value): self.ufun_min = self.reserved_value else: if (self.ufun_min is None or self.ufun_max is None or self.best_outcome is None or self.worst_outcome is None): mn, mx, self.worst_outcome, self.best_outcome = utility_range( self.ufun, return_outcomes=True, issues=self._ami.issues) if self.ufun_min is None: self.ufun_min = mn if self.ufun_max is None: self.ufun_max = mx if self.ufun_min < self.reserved_value: self.ufun_min = self.reserved_value if self.ufun_max < self.ufun_min: self.ufun_max = self.ufun_min self.presorted = presort self.n_trials = 10
def test_n_outcomes(cissue, dissue, hamlet): assert Issue.num_outcomes([cissue, dissue, hamlet]) == float("inf") assert Issue.num_outcomes([dissue, hamlet]) == 50 assert Issue.num_outcomes([dissue]) == 10 assert Issue.num_outcomes([]) == 1