<jupyter_start><jupyter_text>SCML: A negotiation game**<NAME> and <NAME>**    **AAAI 2022 Tutorial**  InstallationTo get started, you only need to install NegMAS. It comes with all its dependencies.<jupyter_code># !pip install scml
# agents from SCML 2019 to SCML 2021 (not needed for this tutorial)
# !pip install scml-agents
# Visualizer
# !pip install scml-vis<jupyter_output><empty_output><jupyter_text>Importing what we need<jupyter_code># for reproducibility
import random

random.seed(1)

# importing what we need. As usual, it is not recommended to import *
from scml import *
from negmas import Outcome, ResponseType<jupyter_output><empty_output><jupyter_text>And visualization stuff<jupyter_code># setup disply parameters
%matplotlib inline
import matplotlib.pyplot as plt
plt.rc('figure', figsize=(18, 6))        # set figure size
from rich import print
from rich.progress import track
import warnings
warnings.filterwarnings('ignore')

def savefig(name, fig=None):
    if fig is None:
        fig = plt.gcf()
    for ext in ("pdf", "png"):
        plt.savefig(f"{name}.{ext}", pad_inches=0.0, bbox_inches="tight")<jupyter_output><empty_output><jupyter_text>Running an SCML World Simulation<jupyter_code>def run_simulation(agent_types, plot=True):
    world = SCML2020OneShotWorld(
        **SCML2020OneShotWorld.generate(
            agent_types,
            n_steps=10,
            random_agent_types=True,
        ),
        construct_graphs=plot,
    )
    world.run()
    if not plot:
        return world
    world.draw(
        what=["contracts-concluded"],
        steps=(0, world.n_steps - 1),
    )
    return world<jupyter_output><empty_output><jupyter_text>Now that we know how to run a simulation, let's write a simple function for evaluating agents in a world<jupyter_code>from collections import defaultdict


def evaluate(worlds):
    from scml.scml2020 import is_system_agent

    type_scores = defaultdict(float)
    type_counts = defaultdict(int)
    for world in worlds:
        agent_scores = world.scores()
        for aid, a in world.agents.items():
            if is_system_agent(aid):
                continue
            type_scores[a.type_name.split(":")[-1]] += agent_scores[aid]
            type_counts[a.type_name.split(":")[-1]] += 1
    for t in type_scores.keys():
        type_scores[t] /= type_counts[t]
    plt.figure()
    plt.bar(x=type_scores.keys(), height=type_scores.values())
    return type_scores<jupyter_output><empty_output><jupyter_text>Let's run a negotiation with two of the built-in agents<jupyter_code>world = run_simulation([RandomOneShotAgent, GreedyOneShotAgent])<jupyter_output><empty_output><jupyter_text>and evaluate it<jupyter_code>evaluate([world])<jupyter_output><empty_output><jupyter_text>Developing our own agentLet's start with an agent that *literally* does nothing to see the interface<jupyter_code>class MyOneShotDoNothing(OneShotAgent):
    def propose(self, negotiator_id, state):
        return None

    def respond(self, negotiator_id, state, offer):
        return ResponseType.END_NEGOTIATION<jupyter_output><empty_output><jupyter_text>Sanity check<jupyter_code>world = run_simulation([MyOneShotDoNothing, RandomOneShotAgent])<jupyter_output><empty_output><jupyter_text>We can see some of the statics collected<jupyter_code>world.stats_df.plot(y=["n_negotiation_successful", "n_negotiation_failed"])<jupyter_output><empty_output><jupyter_text>Now, let's try a really simple agent.- Assume that you will be getting just one agreement every step.- Try to get the best agreement using a time-based concession strategy- Once you get an agreement, end all others<jupyter_code>from negmas import PolyAspiration
class MyConcedingAgent(OneShotAgent):
    """ Concedes slowly on every negotiation assuming it will be the only one with agreement. """
    asp = PolyAspiration(1.0, "boulware")
    has_agreement = False

    def propose(self, negotiator_id, state):
        if self.has_agreement:
            return None
        u = self.asp.utility_at(state.relative_time)
        inv = self.ufun.invert()
        candidates = inv.within_fractions((u, 1.0))
        return candidates[0] if candidates else inv.best

    def respond(self, negotiator_id, state, offer):
        if self.has_agreement:
            return ResponseType.END_NEGOTIATION
        u = self.asp.utility_at(state.relative_time)
        if self.ufun(offer) >= u:
            return ResponseType.ACCEPT_OFFER
        return ResponseType.REJECT_OFFER

    def on_negotiation_success(self, contract, mechanism) -> None:
        self.has_agreement = True

    def step(self):
        self.has_agreement = False
world = run_simulation([MyConcedingAgent, RandomOneShotAgent, GreedyOneShotAgent])<jupyter_output><empty_output><jupyter_text>And we can look again at the success rate of negotiations<jupyter_code>world.stats_df.plot(y=["n_negotiation_successful", "n_negotiation_failed"])<jupyter_output><empty_output><jupyter_text>and evaluat the three agents<jupyter_code>scores = evaluate([world])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09609313338595106, 'fraction_numerical': 0.008287292817679558, 'mean_word_length': 4.4098185699039485, 'pattern_counts': {'":': 2, '<': 55, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '421230', 'license': 'MIT', 'n_tokens_mistral': 1686, 'n_tokens_neox': 1603, 'n_words': 389, 'path': 'scml.ipynb', 'repo_name': 'yasserfarouk/Aaai2022AutomatedNegotiation', 'size': '5084'}