Example #1
0
    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
Example #3
0
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