예제 #1
0
    def _start_negotiations(
        self,
        product: int,
        sell: bool,
        step: int,
        qvalues: Tuple[int, int],
        uvalues: Tuple[int, int],
        tvalues: Tuple[int, int],
        partners: List[str],
    ) -> None:
        # negotiate with all suppliers of the input product I need to produce

        issues = [
            Issue(qvalues, name="quantity"),
            Issue(tvalues, name="time"),
            Issue(uvalues, name="uvalues"),
        ]

        for partner in partners:
            negotiator = self.negotiator(sell, issues=issues)
            self.neg_history[sell][negotiator.id] = []
            self.awi.request_negotiation(
                is_buy=not sell,
                product=product,
                quantity=qvalues,
                unit_price=uvalues,
                time=tvalues,
                partner=partner,
                negotiator=negotiator,
            )
예제 #2
0
def test_lap_ufun_partial_ranking():
    issues = [Issue(5, "Price"), Issue(5, "Distance")]
    gt = {(o["Price"], o["Distance"]): 0.2 * o["Price"] - 0.45 * o["Distance"]
          for o in Issue.enumerate(issues, astype=dict)}
    ufun = RankingLAPUfunLearner(issues=issues, degree=1)
    ufun.fit(ranking_list=[(4, 0), (3, 0), (3, 1), (2, 4), (0, 4)])
    assert ufun.theta[0] > 0.0 > ufun.theta[1]
예제 #3
0
    def __init__(self,
                 name: str = 'dlr_negotiation_game',
                 game_type: str = "DRLNegotiation",
                 issues: Optional[List[Issue]] = None,
                 n_steps: int = 100,
                 competitors: Optional[List[Negotiator]] = None,
                 env=None):
        if competitors is None:
            competitors = [
                MyDRLNegotiator(name="c1",
                                is_seller=False,
                                env=env,
                                init_proposal=False),
                MyOpponentNegotiator(name="c2", env=env)
            ]

        # Default issues used for negotiation game
        if not issues:
            issues = [
                Issue(values=10, name="quantity"),
                Issue(values=n_steps, name="delivery_time"),
                Issue(values=100, name="unit_price")
            ]

        super().__init__(name=name,
                         game_type=game_type,
                         issues=issues,
                         n_steps=n_steps,
                         competitors=competitors,
                         env=env)
예제 #4
0
    def _start_negotiations(
        self,
        product: int,
        sell: bool,
        step: int,
        qvalues: Tuple[int, int],
        uvalues: Tuple[int, int],
        tvalues: Tuple[int, int],
        partners: List[str],
    ) -> None:
        super()._start_negotiations(product, sell, step, qvalues, uvalues,
                                    tvalues, partners)

        issues = [
            Issue(qvalues, name="quantity"),
            Issue(tvalues, name="time"),
            Issue(uvalues, name="uvalues"),
        ]
        sortpartner = {}
        if self.awi.current_step > 4:
            reportstep = ((self.awi.current_step // 5) - 1) * 5
            for k in self.awi.reports_at_step(reportstep).values():
                for ne in partners:
                    if ne == k.agent_id and k.breach_level < 1.0:
                        sortpartner[k.agent_id] = k.breach_level
            if len(sortpartner) != 0:
                sortpartners = sorted(sortpartner.items(), key=lambda x: x[1])
                sortpartners_list = [i[0] for i in sortpartners]
                for partner in sortpartners_list:
                    self.awi.request_negotiation(
                        is_buy=not sell,
                        product=product,
                        quantity=qvalues,
                        unit_price=uvalues,
                        time=tvalues,
                        partner=partner,
                        negotiator=self.negotiator(sell, issues=issues),
                    )
            else:
                for partner in partners:
                    self.awi.request_negotiation(
                        is_buy=not sell,
                        product=product,
                        quantity=qvalues,
                        unit_price=uvalues,
                        time=tvalues,
                        partner=partner,
                        negotiator=self.negotiator(sell, issues=issues),
                    )
        else:
            for partner in partners:
                self.awi.request_negotiation(
                    is_buy=not sell,
                    product=product,
                    quantity=qvalues,
                    unit_price=uvalues,
                    time=tvalues,
                    partner=partner,
                    negotiator=self.negotiator(sell, issues=issues),
                )
예제 #5
0
def test_ufun_quality_error_sums(kind):
    issues = [Issue(5, "Price"), Issue(5, "Distance")]
    gt = {(o["Price"], o["Distance"]): 0.2 * o["Price"] - 0.45 * o["Distance"]
          for o in Issue.enumerate(issues, astype=dict)}
    full_ranking = [
        _[0] for _ in sorted(
            zip(gt.keys(), gt.values()), key=lambda x: x[1], reverse=True)
    ]
    ufun = RankingLAPUfunLearner(issues=issues, degree=1, kind=kind)
    assert (_ufun_objective(
        [0.2, -0.45],
        ranking=full_ranking,
        fs=ufun.fs,
        n_params=ufun.n_params,
        tolerance=ufun.tolerance,
        kind=ufun.kind,
    ) == 0.0)
    assert (_ufun_objective(
        [0.2, 0.4],
        ranking=full_ranking,
        fs=ufun.fs,
        n_params=ufun.n_params,
        tolerance=ufun.tolerance,
        kind=ufun.kind,
    ) > 0.0)
예제 #6
0
def test_can_run_all_negotiators(asdict):
    from negmas.helpers import instantiate

    issues = [Issue((0.0, 1.0), name="price"), Issue(10, name="quantity")]
    weights = dict(price=1.0, quantity=1.0) if asdict else (1.0, 1.0)
    for outcome_type in [tuple, dict]:
        outcomes = Issue.enumerate(issues,
                                   max_n_outcomes=100,
                                   astype=outcome_type)
        neg_types = [
            (
                "RandomNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "AspirationNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "LimitedOutcomesNegotiator",
                dict(acceptance_probabilities=0.5),
            ),
            (
                "LimitedOutcomesAcceptor",
                dict(acceptance_probabilities=0.5),
            ),
            (
                "ToughNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "OnlyBestNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "NaiveTitForTatNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "SimpleTitForTatNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
            (
                "NiceNegotiator",
                dict(ufun=LinearUtilityFunction(weights=weights)),
            ),
        ]
        for i, (neg_type, params) in enumerate(neg_types):
            for n2, p2 in neg_types:
                print(f"{neg_type} <> {n2}")
                n1 = instantiate("negmas.sao." + neg_type, **params)
                n2 = instantiate("negmas.sao." + n2, **p2)
                m = SAOMechanism(n_steps=30,
                                 issues=issues,
                                 outcome_type=dict if asdict else tuple)
                m.add(n1)
                m.add(n2)
                m.run()
                assert not m.running
예제 #7
0
파일: inout.py 프로젝트: nazeyama/negmas
def get_domain_issues(
    domain_file_name: str,
    force_single_issue=False,
    max_n_outcomes: int = 1e6,
    n_discretization: Optional[int] = None,
    keep_issue_names=True,
    keep_value_names=True,
    safe_parsing=False,
) -> Union[Dict[str, Issue], List[Issue]]:
    """
    Returns the issues of a given XML domain (Genius Format)

    Args:
        domain_file_name:
        force_single_issue:
        max_n_outcomes:
        n_discretization:
        keep_issue_names:
        keep_value_names:
        safe_parsing:

    Returns:
        List or Dict of issues

    """
    issues, issues_details, mechanism = None, None, None
    if domain_file_name is not None:
        domain_file_name = str(domain_file_name)
        issues_details, _ = Issue.from_genius(
            domain_file_name,
            force_single_issue=False,
            keep_issue_names=True,
            keep_value_names=True,
            safe_parsing=safe_parsing,
            n_discretization=n_discretization,
        )
        if force_single_issue:
            issues, _ = Issue.from_genius(
                domain_file_name,
                force_single_issue=force_single_issue,
                keep_issue_names=keep_issue_names,
                keep_value_names=keep_value_names,
                max_n_outcomes=max_n_outcomes,
                n_discretization=n_discretization,
            )
            if issues is None:
                return []
        else:
            issues, _ = Issue.from_genius(
                domain_file_name,
                force_single_issue=force_single_issue,
                keep_issue_names=keep_issue_names,
                keep_value_names=keep_value_names,
                safe_parsing=safe_parsing,
                n_discretization=n_discretization,
            )
    return issues if not force_single_issue else [issues]
예제 #8
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),
            )
예제 #9
0
def test_ranking(ascending):
    issues = [Issue(5, "Price"), Issue(5, "Distance")]
    outcomes = Issue.enumerate(issues, astype=tuple)
    ufun = util.UtilityFunction.generate_random(1, outcomes=outcomes)[0]

    rank = ranking(ufun, outcomes, ascending=ascending)

    for r1, r2 in zip(rank[:-1], rank[1:]):
        assert (ascending
                and ufun(r1) <= ufun(r2)) or (not ascending
                                              and ufun(r1) >= ufun(r2))
예제 #10
0
 def current_output_issues(self) -> List[Issue]:
     if self.my_output_product == 0:
         issues = []
     else:
         u, t, q = self._owner._make_issues(self.my_output_product)
         issues = [
             Issue(values=q, name="quantity"),
             Issue(values=t, name="time"),
             Issue(values=u, name="unit_price"),
         ]
     return issues
예제 #11
0
def test_partial_ranking(ascending, fraction):
    issues = [Issue(5, "Price"), Issue(5, "Distance")]
    outcomes = Issue.enumerate(issues, astype=tuple)
    ufun = util.UtilityFunction.generate_random(1, outcomes=outcomes)[0]

    rank = partial(ranking(ufun, outcomes, ascending=ascending), fraction)

    assert len(rank) == int(len(outcomes) * fraction + 0.5)

    for r1, r2 in zip(rank[:-1], rank[1:]):
        assert (ascending
                and ufun(r1) <= ufun(r2)) or (not ascending
                                              and ufun(r1) >= ufun(r2))
예제 #12
0
def test_can_create_all_negotiator_types():
    from negmas.helpers import instantiate

    issues = [Issue((0.0, 1.0), name="price"), Issue(10, name="quantity")]
    for outcome_type in [tuple, dict]:
        outcomes = Issue.enumerate(issues,
                                   max_n_outcomes=100,
                                   astype=outcome_type)
        neg_types = [
            (
                "RandomNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
            ("LimitedOutcomesNegotiator", dict()),
            ("LimitedOutcomesAcceptor", dict()),
            (
                "AspirationNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
            (
                "ToughNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
            (
                "OnlyBestNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
            (
                "NaiveTitForTatNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
            (
                "SimpleTitForTatNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
            (
                "NiceNegotiator",
                dict(ufun=LinearUtilityFunction(
                    weights=dict(price=1.0, quantity=1.0))),
            ),
        ]
        for neg_type, params in neg_types:
            _ = instantiate("negmas.sao." + neg_type, **params)
예제 #13
0
def test_from_outcomes():
    issues = Issues(price=[2, 3], cost=[1, 2, 3], delivery=["yes", "no"])
    found = Issue.from_outcomes(Issue.enumerate(issues.issues))
    for i, f in zip(issues.issues, found):
        assert i.name == f.name
        assert all(a == b for a, b in zip(sorted(i.values), f._values))

    issues = Issues(price=(1, 7), cost=(0, 5), delivery=["yes", "no"])
    found = Issue.from_outcomes(Issue.enumerate(issues.issues,
                                                max_n_outcomes=1000),
                                numeric_as_ranges=True)
    for i, f in zip(issues.issues, found):
        v = sorted(i.values)
        assert i.name == f.name
        assert f._values[0] >= v[0] and f._values[1] <= v[1]
예제 #14
0
 def join(
     self,
     ami: AgentMechanismInterface,
     state: MechanismState,
     *,
     ufun: Optional["UtilityFunction"] = None,
     role: str = "agent",
 ) -> bool:
     if ufun is None:
         ufun = self.__ufun_received
     result = super().join(ami=ami, state=state, ufun=ufun, role=role)
     if (
         result
         and ufun is not None
         and (self.utility_file_name is None or self.domain_file_name is None)
     ):
         domain_file = tempfile.NamedTemporaryFile("w")
         self.domain_file_name = domain_file.name
         domain_file.write(Issue.to_xml_str(ami.issues))
         domain_file.close()
         utility_file = tempfile.NamedTemporaryFile("w")
         self.utility_file_name = utility_file.name
         utility_file.write(
             UtilityFunction.to_xml_str(
                 ufun, issues=ami.issues, discount_factor=self.discount
             )
         )
         utility_file.close()
     return result
예제 #15
0
def test_cannot_start_a_neg_with_no_outcomes():
    world = DummyWorld(n_steps=10)
    a, b = DummyAgent(name="a"), DummyAgent(name="b")
    world.join(a)
    world.join(b)
    assert not a.awi.request_negotiation_about(
        issues=[Issue((1, 0))], partners=[a.id, b.id], req_id="1234")
예제 #16
0
def test_issues_construction():
    issues = Issues(price=(0.0, 1.0), cost=[1, 2, 3], delivery=["yes", "no"])
    assert len(issues.issues) == 3
    assert str(
        issues
    ) == "price: (0.0, 1.0)\ncost: [1, 2, 3]\ndelivery: ['yes', 'no']"
    assert issues.is_infinite()
    assert not issues.is_finite()
    assert all(
        a == b
        for a, b in zip(issues.types, ["continuous", "discrete", "discrete"]))

    issues = Issues.from_single_issue(Issue(10, "issue"))
    assert len(issues.issues) == 1
    assert str(issues) == "issue: (0, 9)"

    issues = Issues(price=[2, 3], cost=[1, 2, 3], delivery=["yes", "no"])
    assert issues.is_finite()
    assert not issues.is_infinite()
    assert issues.cardinality == issues.num_outcomes == 2 * 3 * 2

    valid = issues.rand_valid()
    invalid = issues.rand_invalid()
    assert outcome_in_range(valid, issues.outcome_range)
    assert outcome_in_range(invalid, issues.outcome_range)
예제 #17
0
def test_single_agreement_gets_one_agreement(n_negs, strict):
    from negmas.mechanisms import Mechanism
    from negmas.sao import SAOSingleAgreementRandomController, AspirationNegotiator

    c = SAOSingleAgreementRandomController(strict=strict)
    negs = [
        SAOMechanism(issues=[Issue((0.0, 1.0), "price")],
                     n_steps=50,
                     outcome_type=tuple) for _ in range(n_negs)
    ]
    for i, neg in enumerate(negs):
        neg.add(
            AspirationNegotiator(aspiration_type="linear",
                                 name=f"opponent-{i}"),
            ufun=LinearUtilityFunction(weights=[1.0]),
        )
        neg.add(c.create_negotiator(name=f"against-{i}"))

    Mechanism.runall(negs, True)
    agreements = [neg.state.agreement for neg in negs]
    if strict:
        # assert that the controller never had multiple agreements
        assert sum(_ is not None for _ in agreements) == 1
    else:
        # assert that the controller never accepted twice. It may still have multiple agreements though
        assert (len([
            neg.state.agreement
            for neg in negs if neg.state.agreement is not None
            and neg.state.current_proposer.startswith("opponent")
        ]) < 2)
예제 #18
0
def test_loops_are_broken(keep_order):
    """Tests that loops formed by concurrent negotiations are broken for syn controllers"""
    from negmas.mechanisms import Mechanism
    from negmas.sao import SAOSingleAgreementAspirationController

    a, b, c = (
        SAOSingleAgreementAspirationController(
            ufun=MappingUtilityFunction(lambda x: x["price"]), strict=False
        ),
        SAOSingleAgreementAspirationController(
            ufun=MappingUtilityFunction(lambda x: x["price"]), strict=False
        ),
        SAOSingleAgreementAspirationController(
            ufun=MappingUtilityFunction(lambda x: x["price"]), strict=False
        ),
    )

    n1 = SAOMechanism(
        name="ab",
        issues=[Issue((0.0, 1.0), "price")],
        n_steps=50,
        outcome_type=dict,
    )
    n2 = SAOMechanism(
        name="ac",
        issues=[Issue((0.0, 1.0), "price")],
        n_steps=50,
        outcome_type=dict,
    )
    n3 = SAOMechanism(
        name="bc",
        issues=[Issue((0.0, 1.0), "price")],
        n_steps=50,
        outcome_type=dict,
    )

    n1.add(a.create_negotiator(name="a>b"))
    n1.add(b.create_negotiator(name="b>a"))
    n2.add(a.create_negotiator(name="a>c"))
    n2.add(c.create_negotiator(name="c>a"))
    n3.add(b.create_negotiator(name="b>c"))
    n3.add(c.create_negotiator(name="c>b"))
    negs = [n1, n2, n3]
    Mechanism.runall(negs, keep_order)

    agreements = [neg.state.agreement for neg in negs]
    assert not keep_order or sum(_ is not None for _ in agreements) > 0
예제 #19
0
def test_opponent_negotiator():
    from drl_negotiation.negotiator import MyOpponentNegotiator
    from negmas import Issue, SAOMechanism
    from drl_negotiation.utility_functions import MyUtilityFunction

    name = "test_opponent_negotiator"
    # seller
    weights = (0, 0.25, 1)
    issues = [
        Issue(values=10, name="quantity"),
        Issue(values=100, name="delivery_time"),
        Issue(values=100, name="unit_price")
    ]
    mechanism = SAOMechanism(issues=issues, n_steps=100)
    ufun = MyUtilityFunction(weights=weights, ami=mechanism.ami)
    opponent_negotiator = MyOpponentNegotiator(name=name, ufun=ufun)
    mechanism.add(opponent_negotiator)
예제 #20
0
 def step(self):
     global results
     self.current_step = self.awi.current_step
     if (self.current_step == 2 and self.name.endswith('1')) or (self.current_step == 4 and self.name.endswith('2')):
         issues = [Issue(10)]
         partners = self.awi.state['partners']
         self.request_negotiation(partners=[_.name for _ in partners] + [self.name], issues=issues)
         results.append(f'{self.name} started negotiation with {partners[0].name}')
     results.append(f'{self.name}: step {self.current_step}')
예제 #21
0
 def negotiator(self, is_seller: bool, issues=None, outcomes=None) -> SAONegotiator:
     if outcomes is None and (
         issues is None or not Issue.enumerate(issues, astype=tuple)
     ):
         return None
     params = self.negotiator_params
     params["ufun"] = self.create_ufun(
         is_seller=is_seller, outcomes=outcomes, issues=issues
     )
     return instantiate(self.negotiator_type, **params)
예제 #22
0
    def _start_negotiations(self, product, sell, step, qvalues, uvalues,
                            tvalues, partners):

        issues = [
            Issue(qvalues, name="quantity"),
            Issue(tvalues, name="time"),
            Issue(uvalues, name="uvalues"),
        ]

        for partner in partners:
            if partner in self.brothers:
                self.neg_extras["brother"] = True
            else:
                self.neg_extras["brother"] = False

            if sell:
                if self.did_sell:
                    self.neg_extras["threshold"] = min(
                        0.9, self.neg_extras["threshold"] + 0.05 * 2)
                else:
                    self.neg_extras["threshold"] = max(
                        0.4, self.neg_extras["threshold"] - 0.05 * 4)
            else:
                if self.did_buy:
                    self.neg_extras["threshold"] = min(
                        0.9, self.neg_extras["threshold"] + 0.05 * 2)
                else:
                    self.neg_extras["threshold"] = max(
                        0.4, self.neg_extras["threshold"] - 0.05 * 4)

            neg = self.negotiator(sell, issues=issues)

            self.awi.request_negotiation(
                is_buy=not sell,
                product=product,
                quantity=qvalues,
                unit_price=uvalues,
                time=tvalues,
                partner=partner,
                extra=self.neg_extras,
                negotiator=neg,
            )
예제 #23
0
def test_issue_generation_defaults():
    options = ["a", "b", "c"]
    issues = Issue.generate([(0.0, 1.0), options, 5])
    assert len(issues) == 3
    assert (issues[0].is_continuous() and issues[0].values[0] == 0.0
            and issues[0].values[1] == 1.0)
    for i, o in enumerate(options):
        assert issues[1].values[i] == o
    assert issues[2].values == 5
    for i, issue in enumerate(issues):
        assert str(i) == issue.name
예제 #24
0
    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
예제 #25
0
    def negotiator(self,
                   is_seller: bool,
                   issues=None) -> Optional[SAONegotiator]:
        """Creates a negotiator"""

        if issues is None or not Issue.enumerate(issues, astype=tuple):
            return None

        return AspirationNegotiator(
            ufun=self.create_ufun(is_seller=is_seller, issues=issues),
            assume_normalized=True,
        )
예제 #26
0
def test_lap_ufun_full_ranking():
    issues = [Issue(5, "Price"), Issue(5, "Distance")]
    gt = {(o["Price"], o["Distance"]): 0.2 * o["Price"] - 0.45 * o["Distance"]
          for o in Issue.enumerate(issues, astype=dict)}
    full_ranking = [
        _[0] for _ in sorted(
            zip(gt.keys(), gt.values()), key=lambda x: x[1], reverse=True)
    ]
    for kind in ("error_sums", "errors"):
        ufun = RankingLAPUfunLearner(issues=issues, degree=1, kind=kind)
        ufun.fit(ranking_list=full_ranking)
        learned_ranking = [
            _[0] for _ in sorted(
                zip(ufun.uvals.keys(), ufun.uvals.values()),
                key=lambda x: x[1],
                reverse=True,
            )
        ]
        if kind == "error_sums":
            assert full_ranking == learned_ranking, f"Failed on {kind}"
            assert (ufun.ranking_error(gt=MappingUtilityFunction(
                lambda o: 0.2 * o[0] - 0.45 * o[1])) == 0.0)
예제 #27
0
    def reset(self, env=None):
        self._dissociate()
        if env:
            self.set_env(env=env)
        self._action = None
        self._proposal_offer = None
        self._current_offer_offer = None

        if self.init_proposal:
            self._ip = Issue.sample(issues=[Issue(self._ip_range)],
                                    n_outcomes=1,
                                    astype=tuple)[0]
            self._rp = Issue.sample(issues=[Issue(self._rp_range)],
                                    n_outcomes=1,
                                    astype=tuple)[0]

            if "ip" in self.ufun.__dict__:
                self.ufun.ip = self._ip
                self.set_proposal_offer(self._ip)

            if "rp" in self.ufun.__dict__:
                self.ufun.rp = self._rp

        self.end_time = 1
예제 #28
0
 def step(self):
     global results
     if self.awi is None:
         return
     self.__current_step = self.awi.current_step
     if (self.__current_step == 2 and self.name.endswith("1")) or (
         self.__current_step == 4 and self.name.endswith("2")
     ):
         issues = [Issue(10, name="i1")]
         partners = self.awi.state["partners"]
         self._request_negotiation(
             partners=[_.name for _ in partners] + [self.name], issues=issues
         )
         results.append(f"{self.name} started negotiation with {partners[0].name}")
     results.append(f"{self.name}: step {self.__current_step}")
예제 #29
0
    def before_step(self):
        self.__endall = not self.awi.is_first_level and not self.awi.is_last_level
        if self.__endall:
            return
        # we assume that we are either in the first or the latest layer
        # and calculate our ufun limits and reserved value
        self.ufun.reserved_value = self.ufun.from_contracts([])
        self._reserved_value = self.ufun.reserved_value
        AspirationMixin.aspiration_init(
            self,
            max_aspiration=1.0,
            aspiration_type=float(random.randint(1, 4))
            if random.random() < 0.7 else random.random(),
            above_reserved_value=False,
        )
        # if self.awi.current_exogenous_input_quantity or self.awi.current_exogenous_output_quantity:
        #     breakpoint()
        self._limit = self.ufun.find_limit(True, int(self.awi.is_last_level),
                                           int(self.awi.is_first_level))
        self._max_utility = self._limit.utility
        urange = self._max_utility - self._reserved_value
        if urange <= 1e-5:
            urange = 1e-5
        self._urange = urange

        if self.awi.is_last_level:
            self._best = (self._limit.input_quantity, self._limit.input_price)
        else:
            self._best = (self._limit.output_quantity,
                          self._limit.output_price)

        # compile a list of all outcomes with their utilities and sort it
        # descendigly by utility
        issues = (self.awi.current_output_issues if self.awi.is_first_level
                  else self.awi.current_output_issues)
        outcomes = list(Issue.enumerate(issues, astype=tuple))
        self._outcomes = sorted(
            zip(
                ((self.ufun.from_offers([_], [self.awi.is_first_level]) -
                  self._reserved_value) / (self._urange) for _ in outcomes),
                outcomes,
            ),
            key=lambda x: -x[0],
        )
        self._last_index = 0
예제 #30
0
 def __init__(
     self,
     *args,
     issues: Optional[List[Issue]],
     outcomes: List[Outcome] = None,
     **kwargs,
 ):
     super().__init__(*args, **kwargs)
     if issues is None and outcomes is None:
         raise ValueError("Neither issues nor outcomes was given")
     self.issues = issues
     if outcomes is not None:
         self.outcomes = [
             outcome.values() if isinstance(outcome, dict) else
             outcome if isinstance(outcome, tuple) else outcome.astuple()
             for outcome in outcomes
         ]
     else:
         self.outcomes = Issue.enumerate(issues=issues, astype=tuple)
     self.issue_names = [issue.name for issue in issues]