Beispiel #1
0
def test_checkpoint(
    tmp_path, exist_ok, with_name, with_info, single_checkpoint, step_attribs
):

    x = WithStep()

    fname = unique_name("abc", rand_digits=10, add_time=True, sep=".")
    try:
        file_name = x.checkpoint(
            path=tmp_path,
            file_name=fname if with_name else None,
            info={"r": 3} if with_info else None,
            exist_ok=exist_ok,
            single_checkpoint=single_checkpoint,
            step_attribs=step_attribs,
        )
        assert (
            file_name.name.split(".")[0].isnumeric()
            or single_checkpoint
            or all(_ in bad_attribs for _ in set(step_attribs))
            or not any(hasattr(x, _) for _ in step_attribs)
        )
    except ValueError as e:
        if "exist_ok" in str(e):
            assert not exist_ok
        else:
            raise e

    x = MyEntity()

    fname = unique_name("abc", rand_digits=10, add_time=True, sep=".")
    try:
        file_name = x.checkpoint(
            path=tmp_path,
            file_name=fname if with_name else None,
            info={"r": 3} if with_info else None,
            exist_ok=exist_ok,
            single_checkpoint=single_checkpoint,
            step_attribs=step_attribs,
        )
        assert (
            file_name.name.split(".")[0].isnumeric()
            or single_checkpoint
            or all(_ in bad_attribs for _ in set(step_attribs))
            or not any(hasattr(x, _) for _ in step_attribs)
        )
    except ValueError as e:
        if "exist_ok" in str(e):
            assert not exist_ok
        else:
            raise e
Beispiel #2
0
def test_nothing_happens_with_do_nothing(buy_missing, n_processes, initial_balance):
    world = generate_world(
        [DoNothingAgent],
        buy_missing_products=buy_missing,
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/doing_nothing/"
            f"{'Buy' if buy_missing else 'Fine'}_p{n_processes}_b{initial_balance}",
            add_time=True,
            rand_digits=4,
        ),
        initial_balance=initial_balance,
        bankruptcy_limit=initial_balance,
        compact=COMPACT,
        no_logs=NOLOGS,
    )
    world.run()
    assert len(world.contracts_per_step) == 0
    for a, f, p in world.afp:
        if is_system_agent(a.id):
            continue
        if (
            a.awi.my_input_product == 0
            or a.awi.my_input_product == a.awi.n_processes - 1
        ):
            assert f.current_balance <= initial_balance, (
                f"{a.name} (process {a.awi.my_input_product} of {a.awi.n_processes})'s balance "
                f"should go down"
            )
Beispiel #3
0
def test_world_auto_checkpoint(tmp_path, single_checkpoint, checkpoint_every,
                               exist_ok):
    import shutil

    new_folder: Path = tmp_path / unique_name("empty", sep="")
    new_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(new_folder)
    new_folder.mkdir(parents=True, exist_ok=True)
    filename = "mechanism"
    n_steps = 20

    world = DummyWorld(
        n_steps=n_steps,
        checkpoint_every=checkpoint_every,
        checkpoint_folder=new_folder,
        checkpoint_filename=filename,
        extra_checkpoint_info=None,
        exist_ok=exist_ok,
        single_checkpoint=single_checkpoint,
    )

    world.run()

    if 0 < checkpoint_every <= n_steps:
        if single_checkpoint:
            assert len(list(new_folder.glob("*"))) == 2, print(
                f"World ran for: {world.current_step}")
        else:
            assert len(list(new_folder.glob("*"))) >= 2 * (max(
                1, world.current_step // checkpoint_every))
    elif checkpoint_every > n_steps:
        assert len(list(new_folder.glob("*"))) == 2
    else:
        assert len(list(new_folder.glob("*"))) == 0
Beispiel #4
0
def test_agents_go_bankrupt(n_processes):
    buy_missing = True
    world = generate_world(
        [RandomAgent],
        buy_missing_products=buy_missing,
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/bankrupt/"
            f"{'Buy' if buy_missing else 'Fine'}_p{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        initial_balance=0,
        bankruptcy_limit=0,
        n_steps=10,
        compact=COMPACT,
        no_logs=NOLOGS,
    )
    world.run()
    #    assert len(world.signed_contracts) + len(world.cancelled_contracts) == 0
    for a, f, p in world.afp:
        if is_system_agent(a.id):
            continue
        if (
            a.awi.my_input_product == 0
            or a.awi.my_input_product == a.awi.n_processes - 1
        ):
            assert f.current_balance <= 0, (
                f"{a.name} (process {a.awi.my_input_product} of {a.awi.n_processes})'s balance "
                f"should go down"
            )
            assert f.is_bankrupt, (
                f"{a.name} (process {a.awi.my_input_product} of {a.awi.n_processes}) should "
                f"be bankrupt (balance = {f.current_balance}, inventory={f.current_inventory})"
            )
Beispiel #5
0
 def __init__(self, name: str = None) -> None:
     if name is not None:
         name = str(name)
     self.__uuid = (f'{name}-' if name is not None else "") + str(
         uuid.uuid4())
     if name is None or len(name) == 0:
         name = unique_name('', add_time=False, rand_digits=16)
     self.__name = name
     super().__init__()
Beispiel #6
0
def test_is_nonzero_file(tmpdir):
    f_name = unique_name("")
    f = tmpdir / f_name
    assert is_nonzero_file(str(f)) is False

    with open(f, "w") as tst_file:
        tst_file.write("")
    assert is_nonzero_file(str(f)) is False

    with open(f, "w") as tst_file:
        tst_file.write("test")
    assert is_nonzero_file(str(f)) is True
Beispiel #7
0
def test_can_run_with_a_single_agent_type(agent_type, n_processes):
    world = generate_world(
        [agent_type],
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/{agent_type.__name__}" f"Fine{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        compact=COMPACT,
        no_logs=NOLOGS,
    )
    world.run()
    save_stats(world, world.log_folder)
def test_negotiator_ids_are_partner_ids():
    n_processes = 5
    world = generate_world(
        [MyOneShotAgent],
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/{MyOneShotAgent.__name__}" f"Fine{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        compact=True,
        no_logs=True,
    )
    world.run()
def test_ind_negotiators_genius():
    n_processes = 5
    world = generate_world(
        [MyGeniusIndNeg],
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/{MyIndNeg.__name__}" f"Fine{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        compact=True,
        no_logs=True,
    )
    world.run()
Beispiel #10
0
def test_something_happens_with_random_agents(n_processes):
    world = generate_world(
        [RandomOneShotAgent],
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/do_something/" f"Fine_p{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        compact=COMPACT,
        no_logs=NOLOGS,
        n_steps=15,
    )
    world.run()
    assert len(world.signed_contracts) + len(world.cancelled_contracts) != 0
Beispiel #11
0
def test_can_run_with_a_multiple_agent_types(agent_types, n_processes):
    world = generate_world(
        agent_types,
        name=unique_name(
            f"scml2020tests/multi/{'-'.join(_.__name__[:3] for _ in agent_types)}/"
            f"Fine_p{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        n_processes=n_processes,
        compact=COMPACT,
        no_logs=NOLOGS,
    )
    world.run()
    save_stats(world, world.log_folder)
Beispiel #12
0
def test_can_run_with_a_multiple_agent_types(agent_types, buy_missing, n_processes):
    world = generate_world(
        agent_types,
        buy_missing_products=buy_missing,
        name=unique_name(
            f"scml2020tests/multi/{'-'.join(_.__name__[:3] for _ in agent_types)}/"
            f"{'Buy' if buy_missing else 'Fine'}_p{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        n_processes=n_processes,
        initial_balance=10_000,
        compact=COMPACT,
        no_logs=NOLOGS,
    )
    world.run()
    save_stats(world, world.log_folder)
Beispiel #13
0
def test_auto_checkpoint(tmp_path, single_checkpoint, checkpoint_every,
                         exist_ok):
    import shutil

    new_folder: Path = tmp_path / unique_name("empty", sep="")
    new_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(new_folder)
    new_folder.mkdir(parents=True, exist_ok=True)
    filename = "mechanism"

    n_outcomes, n_negotiators = 5, 3
    n_steps = 50
    mechanism = SAOMechanism(
        outcomes=n_outcomes,
        n_steps=n_steps,
        offering_is_accepting=True,
        avoid_ultimatum=False,
        checkpoint_every=checkpoint_every,
        checkpoint_folder=new_folder,
        checkpoint_filename=filename,
        extra_checkpoint_info=None,
        exist_ok=exist_ok,
        single_checkpoint=single_checkpoint,
    )
    ufuns = MappingUtilityFunction.generate_random(n_negotiators,
                                                   outcomes=n_outcomes)
    for i in range(n_negotiators):
        mechanism.add(
            AspirationNegotiator(name=f"agent{i}"),
            ufun=ufuns[i],
            aspiration_type="conceder",
        )

    mechanism.run()

    if 0 < checkpoint_every <= n_steps:
        if single_checkpoint:
            assert len(list(new_folder.glob("*"))) == 2
        else:
            assert len(list(new_folder.glob("*"))) >= 2 * (max(
                1, mechanism.state.step // checkpoint_every))
    elif checkpoint_every > n_steps:
        assert len(list(new_folder.glob("*"))) == 2
    else:
        assert len(list(new_folder.glob("*"))) == 0
Beispiel #14
0
def test_builtin_aspiration():
    from negmas.helpers import get_full_type_name

    from scml.oneshot import SingleAgreementAspirationAgent

    n_processes = 2
    world = generate_world(
        [SingleAgreementAspirationAgent],
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/{SingleAgreementAspirationAgent.__name__}Fine{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        compact=True,
        no_logs=True,
    )
    world.run()
Beispiel #15
0
def test_something_happens_with_random_agents(buy_missing, n_processes):
    world = generate_world(
        [RandomAgent],
        buy_missing_products=buy_missing,
        n_processes=n_processes,
        name=unique_name(
            f"scml2020tests/single/do_something/"
            f"{'Buy' if buy_missing else 'Fine'}_p{n_processes}",
            add_time=True,
            rand_digits=4,
        ),
        initial_balance=10_000,
        bankruptcy_limit=10_000,
        compact=COMPACT,
        no_logs=NOLOGS,
        n_steps=15,
    )
    world.run()
    assert len(world.signed_contracts) + len(world.cancelled_contracts) != 0
Beispiel #16
0
def test_world_auto_checkpoint(tmp_path, single_checkpoint, checkpoint_every, exist_ok):
    import shutil

    new_folder: Path = tmp_path / unique_name("empty", sep="")
    new_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(new_folder)
    new_folder.mkdir(parents=True, exist_ok=True)
    filename = "scml"
    n_steps = 5

    world = SCMLWorld.chain_world(
        log_file_name="",
        n_steps=n_steps,
        n_factories_per_level=1,
        consumer_kwargs={
            "negotiator_type": "negmas.sao.NiceNegotiator",
            "consumption_horizon": 2,
        },
        miner_kwargs={"negotiator_type": "negmas.sao.NiceNegotiator"},
        checkpoint_every=checkpoint_every,
        checkpoint_folder=new_folder,
        checkpoint_filename=filename,
        extra_checkpoint_info=None,
        exist_ok=exist_ok,
        single_checkpoint=single_checkpoint,
    )

    world.run()

    if 0 < checkpoint_every <= n_steps:
        if single_checkpoint:
            assert len(list(new_folder.glob("*"))) == 2, print(
                f"SCML2020World ran for: {world.current_step}"
            )
        else:
            assert len(list(new_folder.glob("*"))) >= 2 * (
                max(1, world.current_step // checkpoint_every)
            )
    elif checkpoint_every > n_steps:
        assert len(list(new_folder.glob("*"))) == 2
    else:
        assert len(list(new_folder.glob("*"))) == 0
Beispiel #17
0
def anac2020_config_generator(
    n_competitors: int,
    n_agents_per_competitor: int,
    agent_names_reveal_type: bool = False,
    non_competitors: Optional[Tuple[Union[str, SCML2020Agent]]] = None,
    non_competitor_params: Optional[Tuple[Dict[str, Any]]] = None,
    compact: bool = True,
    *,
    n_steps: Union[int, Tuple[int, int]] = (50, 100),
    n_processes: Tuple[int, int] = (2, 5),
    min_factories_per_level: int = 2,  # strictly guaranteed
    max_factories_per_level: int = 6,  # not strictly guaranteed
    n_lines: int = 10,
    **kwargs,
) -> List[Dict[str, Any]]:

    if non_competitors is None:
        non_competitors = tuple(DefaultAgent)
    if isinstance(n_processes, Iterable):
        n_processes = tuple(n_processes)
    else:
        n_processes = [n_processes, n_processes]

    n_steps = _intin(n_steps)

    n_processes = randint(*n_processes)
    n_agents = n_agents_per_competitor * n_competitors
    n_default_managers = (
        min(
            n_processes * max_factories_per_level,
            max(0, n_processes * min_factories_per_level),
        )
        - n_agents
    )
    n_defaults = integer_cut(n_default_managers, n_processes, 0)

    n_a_list = integer_cut(n_agents, n_processes, 0)
    for i, n_a in enumerate(n_a_list):
        if n_a + n_defaults[i] < min_factories_per_level:
            n_defaults[i] = min_factories_per_level - n_a
        if n_a + n_defaults[i] > max_factories_per_level and n_defaults[i] > 1:
            n_defaults[i] = max(1, min_factories_per_level - n_a)
    n_f_list = [a + b for a, b in zip(n_defaults, n_a_list)]
    n_factories = sum(n_f_list)

    if non_competitor_params is None:
        non_competitor_params = [{}] * len(non_competitors)

    non_competitors = [get_full_type_name(_) for _ in non_competitors]

    max_def_agents = len(non_competitors) - 1
    agent_types = [None] * n_factories
    manager_params = [None] * n_factories
    first_in_level = 0
    for level in range(n_processes):
        n_d = n_defaults[level]
        n_f = n_f_list[level]
        assert (
            n_d <= n_f
        ), f"Got {n_f} total factories at level {level} out of which {n_d} are default!!"
        for j in range(n_f):
            if j >= n_f - n_d:  # default managers are last managers in the list
                def_indx = randint(0, max_def_agents)
                agent_types[first_in_level + j] = non_competitors[def_indx]
                params_ = copy.deepcopy(non_competitor_params[def_indx])
                if agent_names_reveal_type:
                    params_["name"] = f"_df_{level}_{j}"
                else:
                    params_[
                        "name"
                    ] = (
                        f"_df_{level}_{j}"
                    )  # because I use name to know that this is a default agent in evaluate.
                    # @todo do not use name to identify default agents in evaluation
                manager_params[first_in_level + j] = params_
        first_in_level += n_f

    world_name = unique_name("", add_time=True, rand_digits=4)
    agent_types = [
        get_full_type_name(_) if isinstance(_, SCML2020Agent) else _
        for _ in agent_types
    ]
    world_params = dict(
        name=world_name,
        agent_types=agent_types,
        time_limit=7200 + 3600,
        neg_time_limit=120,
        neg_n_steps=20,
        neg_step_time_limit=10,
        negotiation_speed=21,
        breach_penalty=0.2,
        interest_rate=0.08,
        bankruptcy_limit=1.0,
        initial_balance=None,
        start_negotiations_immediately=False,
        n_agents_per_process=n_f_list,
        n_processes=n_processes,
        n_steps=n_steps,
        n_lines=n_lines,
        compact=compact,
    )
    world_params.update(kwargs)
    config = {
        "world_params": world_params,
        "compact": compact,
        "scoring_context": {},
        "non_competitors": non_competitors,
        "non_competitor_params": non_competitor_params,
        "agent_types": agent_types,
        "agent_params": manager_params,
    }
    config.update(kwargs)
    return [config]
Beispiel #18
0
def test_can_run_from_checkpoint(tmp_path, single_checkpoint, checkpoint_every,
                                 exist_ok):
    import shutil

    new_folder: Path = tmp_path / unique_name("empty", sep="")
    second_folder: Path = tmp_path / unique_name("second", sep="")
    new_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(new_folder)
    new_folder.mkdir(parents=True, exist_ok=True)
    filename = "mechanism"
    second_folder.mkdir(parents=True, exist_ok=True)

    n_outcomes, n_negotiators = 5, 3
    n_steps = 50
    mechanism = SAOMechanism(
        outcomes=n_outcomes,
        n_steps=n_steps,
        offering_is_accepting=True,
        avoid_ultimatum=False,
        checkpoint_every=checkpoint_every,
        checkpoint_folder=new_folder,
        checkpoint_filename=filename,
        extra_checkpoint_info=None,
        exist_ok=exist_ok,
        single_checkpoint=single_checkpoint,
    )
    ufuns = MappingUtilityFunction.generate_random(n_negotiators,
                                                   outcomes=n_outcomes)
    for i in range(n_negotiators):
        mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i])

    mechanism.run()
    files = list(new_folder.glob("*"))
    if 0 < checkpoint_every <= n_steps:
        if single_checkpoint:
            assert len(list(new_folder.glob("*"))) == 2
        else:
            assert len(list(new_folder.glob("*"))) >= 2 * (max(
                1, mechanism.state.step // checkpoint_every))
    elif checkpoint_every > n_steps:
        assert len(list(new_folder.glob("*"))) == 2
    else:
        assert len(list(new_folder.glob("*"))) == 0

    runner = CheckpointRunner(folder=new_folder)

    assert len(runner.steps) * 2 == len(files)
    assert runner.current_step == -1
    assert runner.loaded_object is None

    runner.step()

    assert runner.current_step == (0 if not single_checkpoint else
                                   runner.steps[-1])
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.reset()
    assert len(runner.steps) * 2 == len(files)
    assert runner.current_step == -1
    assert runner.loaded_object is None

    runner.goto(runner.last_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.next_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.previous_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.first_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.reset()

    runner.run()
Beispiel #19
0
def test_can_run_from_checkpoint(tmp_path, checkpoint_every, exist_ok, copy,
                                 fork_after_reset):
    import shutil

    new_folder: Path = tmp_path / unique_name("empty", sep="")
    second_folder: Path = tmp_path / unique_name("second", sep="")
    new_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(new_folder)
    new_folder.mkdir(parents=True, exist_ok=True)
    second_folder.mkdir(parents=True, exist_ok=True)
    shutil.rmtree(second_folder)
    second_folder.mkdir(parents=True, exist_ok=True)

    filename = "mechanism"

    n_outcomes, n_negotiators = 5, 3
    n_steps = 50
    mechanism = SAOMechanism(
        outcomes=n_outcomes,
        n_steps=n_steps,
        offering_is_accepting=True,
        avoid_ultimatum=False,
        checkpoint_every=checkpoint_every,
        checkpoint_folder=new_folder,
        checkpoint_filename=filename,
        extra_checkpoint_info=None,
        exist_ok=exist_ok,
        single_checkpoint=False,
    )
    ufuns = MappingUtilityFunction.generate_random(n_negotiators,
                                                   outcomes=n_outcomes)
    for i in range(n_negotiators):
        mechanism.add(
            AspirationNegotiator(name=f"agent{i}"),
            ufun=ufuns[i],
            aspiration_type="conceder",
        )

    mechanism.run()
    files = list(new_folder.glob("*"))
    if 0 < checkpoint_every <= n_steps:
        assert len(list(new_folder.glob("*"))) >= 2 * (max(
            1, mechanism.state.step // checkpoint_every))
    elif checkpoint_every > n_steps:
        assert len(list(new_folder.glob("*"))) == 2
    else:
        assert len(list(new_folder.glob("*"))) == 0

    runner = CheckpointRunner(folder=new_folder)

    assert len(runner.steps) * 2 == len(files)
    assert runner.current_step == -1
    assert runner.loaded_object is None

    runner.step()

    assert runner.current_step == 0
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.reset()
    assert len(runner.steps) * 2 == len(files)
    assert runner.current_step == -1
    assert runner.loaded_object is None

    runner.goto(runner.last_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.next_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.previous_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.first_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.reset()

    if fork_after_reset:
        m = runner.fork(copy_past_checkpoints=copy, folder=second_folder)
        assert m is None
        return
    runner.step()
    m = runner.fork(copy_past_checkpoints=copy, folder=second_folder)

    if copy:
        step = runner.current_step
        assert len(list(second_folder.glob("*"))) >= 2
        assert len(list(second_folder.glob(f"*{step}.mechanism"))) > 0
    else:
        assert len(list(second_folder.glob("*"))) == 0

    assert isinstance(m, SAOMechanism)
    step = m.current_step
    m.step()
    assert m.current_step == step + 1

    state = m.run()
    assert state.agreement is not None

    runner.reset()
    assert len(runner.steps) * 2 == len(files)
    assert runner.current_step == -1
    assert runner.loaded_object is None

    runner.goto(runner.last_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.next_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.previous_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.goto(runner.first_step, exact=True)
    assert isinstance(runner.loaded_object, SAOMechanism)
    assert runner.loaded_object.state.step == runner.current_step

    runner.reset()

    runner.run()
Beispiel #20
0
def create(
    ctx,
    name,
    timeout,
    log,
    verbosity,
    reveal_names,
    runs,
    configs,
    max_runs,
    competitors,
    world_config,
    jcompetitors,
    non_competitors,
    compact,
    agents,
    log_ufuns,
    log_negs,
    raise_exceptions,
    steps_min,
    steps_max,
    path,
    cw,
    world_generator,
    config_generator,
    assigner,
    scorer,
    java_interop_class,
):
    if len(config_generator is None or config_generator.strip()) == 0:
        print(
            "ERROR: You did not specify a config generator. Use --config-generator to specify one and see the "
            "documentation of the create_tournament method in negmas.situated for details about it."
            "\nThe following must be explicitly specified to create a tournament: a world-generator, "
            "an assigner, a scorer, and a config-generator.")

        return -4

    if len(world_generator is None or world_generator.strip()) == 0:
        print(
            "ERROR: You did not specify a world generator. Use --world-generator to specify one and see the "
            "documentation of the create_tournament method in negmas.situated for details about it."
            "\nThe following must be explicitly specified to create a tournament: a world-generator, "
            "an assigner, a scorer, and a config-generator.")

        return -3

    if len(assigner is None or assigner.strip()) == 0:
        print(
            "ERROR: You did not specify an assigner. Use --assigner to specify one and see the documentation"
            " of the create_tournament method in negmas.situated for details about it."
            "\nThe following must be explicitly specified to create a tournament: a world-generator, "
            "an assigner, a scorer, and a config-generator.")

        return -2

    if len(scorer is None or scorer.strip()) == 0:
        print(
            "ERROR: You did not specify a scorer. Use --scorer to specify one and see the documentation of the "
            "create_tournament method in negmas.situated for details about it."
            "\nThe following must be explicitly specified to create a tournament: a world-generator, "
            "an assigner, a scorer, and a config-generator.")

        return -1

    if (jcompetitors is not None and len(jcompetitors) > 0
            and len(java_interop_class.strip()) == 0):
        print(
            f"ERROR: You are passing java competitors but not java interop "
            f"class (use --java-interop-class "
            f" to pass the name of that class or do not pass java competitors"
            f" [--jcompetitors])")

        return -5

    if len(path) > 0:
        sys.path.append(path)
    kwargs = {}

    if world_config is not None and len(world_config) > 0:
        for wc in world_config:
            kwargs.update(load(wc))
    warning_n_runs = 2000

    if timeout <= 0:
        timeout = None

    if name == "random":
        name = unique_name(base="", rand_digits=0)
    ctx.obj["tournament_name"] = name

    if max_runs <= 0:
        max_runs = None

    if compact:
        log_ufuns = False

    if not compact:
        if not reveal_names:
            print("You are running the tournament with --debug. Will reveal "
                  "agent types in their names")
        reveal_names = True
        verbosity = max(1, verbosity)

    worlds_per_config = (None if max_runs is None else int(
        round(max_runs / (configs * runs))))

    all_competitors = competitors.split(";")
    all_competitors_params = [dict() for _ in range(len(all_competitors))]

    if jcompetitors is not None and len(jcompetitors) > 0:
        jcompetitor_params = [{
            "java_class_name": _
        } for _ in jcompetitors.split(";")]
        jcompetitors = [java_interop_class] * len(jcompetitor_params)
        all_competitors += jcompetitors
        all_competitors_params += jcompetitor_params
        print(
            "You are using some Java agents. The tournament MUST run serially")

        if not jnegmas_bridge_is_running():
            print(
                "Error: You are using java competitors but jnegmas bridge is not running\n\nTo correct this issue"
                " run the following command IN A DIFFERENT TERMINAL because it will block:\n\n"
                "$ negmas jnegmas")
            exit(1)

    permutation_size = 1
    recommended = runs * configs * permutation_size

    if worlds_per_config is not None and worlds_per_config < 1:
        print(
            f"You need at least {(configs * runs)} runs even with a single permutation of managers."
            f".\n\nSet --max-runs to at least {(configs * runs)} (Recommended {recommended})"
        )

        return

    if max_runs is not None and max_runs < recommended:
        print(
            f"You are running {max_runs} worlds only but it is recommended to set {max_runs} to at least "
            f"{recommended}. Will continue")

    steps = (steps_min, steps_max)

    if worlds_per_config is None:
        n_comp = len(all_competitors)
        n_worlds = permutation_size * runs * configs

        if n_worlds > warning_n_runs:
            print(
                f"You are running the maximum possible number of permutations for each configuration. This is roughly"
                f" {n_worlds} simulations (each for {steps} steps). That will take a VERY long time."
                f"\n\nYou can reduce the number of simulations by setting --configs>=1 (currently {configs}) or "
                f"--runs>= 1 (currently {runs}) to a lower value. "
                f"\nFinally, you can limit the maximum number of worlds to run by setting --max-runs=integer."
            )
            # if (
            #     not input(f"Are you sure you want to run {n_worlds} simulations?")
            #     .lower()
            #     .startswith("y")
            # ):
            #     exit(0)
            max_runs = int(
                input(
                    f"Input the maximum number of simulations to run. Zero to run all of the {n_worlds} "
                    f"simulations. ^C or a negative number to exit [0 : {n_worlds}]:"
                ))

            if max_runs == 0:
                max_runs = None

            if max_runs is not None and max_runs < 0:
                exit(0)
            worlds_per_config = (None if max_runs is None else int(
                round(max_runs / (configs * runs))))

    if len(jcompetitors) > 0:
        print(
            "You are using java-competitors. The tournament will be run serially"
        )
        parallelism = "serial"

    non_competitor_params = None

    if len(non_competitors) < 1:
        non_competitors = None
    else:
        non_competitors = non_competitors.split(";")

    print(f"Tournament will be run between {len(all_competitors)} agents: ")
    pprint(all_competitors)
    print("Non-competitors are: ")
    pprint(non_competitors)
    results = create_tournament(
        competitors=all_competitors,
        competitor_params=all_competitors_params,
        non_competitors=non_competitors,
        non_competitor_params=non_competitor_params,
        agent_names_reveal_type=reveal_names,
        n_competitors_per_world=cw,
        n_configs=configs,
        n_runs_per_world=runs,
        max_worlds_per_config=worlds_per_config,
        base_tournament_path=log,
        total_timeout=timeout,
        name=name,
        verbose=verbosity > 0,
        n_agents_per_competitor=agents,
        world_generator=world_generator,
        config_generator=config_generator,
        config_assigner=assigner,
        score_calculator=scorer,
        compact=compact,
        n_steps=steps,
        log_ufuns=log_ufuns,
        log_negotiations=log_negs,
        ignore_agent_exceptions=not raise_exceptions,
        ignore_contract_execution_exceptions=not raise_exceptions,
        parallelism=parallelism,
        **kwargs,
    )

    ctx.obj["tournament_name"] = results.name
    ctx.obj["tournament_log_folder"] = log
    ctx.obj["compact"] = compact
    print(
        f"Saved all configs to {str(results)}\nTournament name is {results.name}"
    )
Beispiel #21
0
def main(worlds, factorial, variables, name, steps, compact, log, jobs):
    fixed_vars["n_steps"] = steps
    fixed_vars["compact"] = compact
    fixed_vars["no_logs"] = not log
    ind_vars = {
        "borrow_on_breach": [True, False],
        "buy_missing_products": [True, False],
        "production_buy_missing": [True, False],
        "exogenous_buy_missing": [True, False],
        "production_no_borrow": [True, False],
        "exogenous_no_borrow": [True, False],
        "exogenous_force_max": [True, False],
        "breach_penalty;production_penalty;exogenous_penalty": [
            (0.15, 0.15, 0.15),
            (0.25, 0.25, 0.25),
        ],
        "interest_rate": [0.04, 0.08],
        "signing_delay": [0, 1],
    }

    if variables is not None and variables != "all":
        variables = ";".split(variables)
        ind_vars = {k: v for k, v in ind_vars.items() if k in variables}

    untested = list(set(ind_vars.keys()) - set(variables))
    for v in untested:
        if ";" in v:
            vs = v.split(";")
            vals = random.sample(ind_vars[v], 1)[0]
            fixed_vars.update(dict(zip(vs, vals)))
            continue
        fixed_vars[v] = random.sample(ind_vars[v], 1)[0]

    constraints = (
        Constraint(
            condition_vars=["borrow_on_breach"],
            condition_values=[[False]],
            conditioned_var="production_no_borrow",
            feasible_values=[True],
        ),
        Constraint(
            condition_vars=["borrow_on_breach"],
            condition_values=[[False]],
            conditioned_var="exogenous_no_borrow",
            feasible_values=[True],
        ),
        Constraint(
            condition_vars=["exogenous_force_max"],
            condition_values=[[False]],
            conditioned_var="production_no_borrow",
            feasible_values=[False],
        ),
        Constraint(
            condition_vars=["exogenous_force_max"],
            condition_values=[[True]],
            conditioned_var="exogenous_buy_missing",
            feasible_values=[True],
        ),
    )
    print(
        f"Running experiment:\n"
        f"Independent Variables {list(ind_vars.keys())}\nDependent Variables: {list(dep_vars.keys())}\n"
        f"Untested Variables: {list(fixed_vars.keys())}\n"
        f"n. runs per world: {worlds} ({'factorial' if factorial else 'non-factorial'})"
    )
    path = (Path.home() / "negmas" / "experiments" /
            unique_name("E" if name is None else name, add_time=True, sep=""))
    path.mkdir(parents=True, exist_ok=True)
    run(ind_vars, fixed_vars, worlds, factorial, constraints,
        n_jobs=jobs).to_csv(path / "results.csv")
Beispiel #22
0
def test_unique_name_with_path(tmpdir):
    a = unique_name(str(tmpdir))
    assert a.startswith(str(tmpdir))
Beispiel #23
0
def test_unique_name_no_time():
    assert len(unique_name("", add_time=False)) == 8
Beispiel #24
0
def create(
    ctx,
    name,
    steps,
    ttype,
    timeout,
    log,
    verbosity,
    reveal_names,
    runs,
    configs,
    max_runs,
    competitors,
    world_config,
    jcompetitors,
    non_competitors,
    compact,
    factories,
    agents,
    log_ufuns,
    log_negs,
    raise_exceptions,
    steps_min,
    steps_max,
    path,
    cw,
):
    if len(path) > 0:
        sys.path.append(path)
    kwargs = {}
    if world_config is not None and len(world_config) > 0:
        for wc in world_config:
            kwargs.update(load(wc))
    warning_n_runs = 2000
    if timeout <= 0:
        timeout = None
    if name == "random":
        name = unique_name(base="", rand_digits=0)
    ctx.obj["tournament_name"] = name
    if max_runs <= 0:
        max_runs = None
    if compact:
        log_ufuns = False

    if not compact:
        if not reveal_names:
            print(
                "You are running the tournament with --debug. Will reveal agent types in their names"
            )
        reveal_names = True
        verbosity = max(1, verbosity)

    worlds_per_config = (None if max_runs is None else int(
        round(max_runs / (configs * runs))))

    all_competitors = competitors.split(";")
    for i, cp in enumerate(all_competitors):
        if "." not in cp:
            all_competitors[i] = "negmas.apps.scml.factory_managers." + cp
    all_competitors_params = [dict() for _ in range(len(all_competitors))]
    if jcompetitors is not None and len(jcompetitors) > 0:
        jcompetitor_params = [{
            "java_class_name": _
        } for _ in jcompetitors.split(";")]
        for jp in jcompetitor_params:
            if "." not in jp["java_class_name"]:
                jp["java_class_name"] = (
                    "jnegmas.apps.scml.factory_managers." +
                    jp["java_class_name"])
        jcompetitors = ["negmas.apps.scml.JavaFactoryManager"
                        ] * len(jcompetitor_params)
        all_competitors += jcompetitors
        all_competitors_params += jcompetitor_params
        print(
            "You are using some Java agents. The tournament MUST run serially")
        if not jnegmas_bridge_is_running():
            print(
                "Error: You are using java competitors but jnegmas bridge is not running\n\nTo correct this issue"
                " run the following command IN A DIFFERENT TERMINAL because it will block:\n\n"
                "$ negmas jnegmas")
            exit(1)

    # if ttype.lower() == "anac2019std":
    #     if (
    #         "negmas.apps.scml.factory_managers.GreedyFactoryManager"
    #         not in all_competitors
    #     ):
    #         all_competitors.append(
    #             "negmas.apps.scml.factory_managers.GreedyFactoryManager"
    #         )
    #         all_competitors_params.append({})

    permutation_size = len(all_competitors) if "sabotage" not in ttype else 1
    recommended = runs * configs * permutation_size
    if worlds_per_config is not None and worlds_per_config < 1:
        print(
            f"You need at least {(configs * runs)} runs even with a single permutation of managers."
            f".\n\nSet --max-runs to at least {(configs * runs)} (Recommended {recommended})"
        )
        return

    if max_runs is not None and max_runs < recommended:
        print(
            f"You are running {max_runs} worlds only but it is recommended to set {max_runs} to at least "
            f"{recommended}. Will continue")

    if ttype == "anac2019std":
        agents = 1

    if steps is None:
        steps = (steps_min, steps_max)

    if worlds_per_config is None:
        n_comp = len(all_competitors) if ttype != "anac2019sabotage" else 2
        n_worlds = permutation_size * runs * configs
        if n_worlds > warning_n_runs:
            print(
                f"You are running the maximum possible number of permutations for each configuration. This is roughly"
                f" {n_worlds} simulations (each for {steps} steps). That will take a VERY long time."
                f"\n\nYou can reduce the number of simulations by setting --configs>=1 (currently {configs}) or "
                f"--runs>= 1 (currently {runs}) to a lower value. "
                f"\nFinally, you can limit the maximum number of worlds to run by setting --max-runs=integer."
            )
            # if (
            #     not input(f"Are you sure you want to run {n_worlds} simulations?")
            #     .lower()
            #     .startswith("y")
            # ):
            #     exit(0)
            max_runs = int(
                input(
                    f"Input the maximum number of simulations to run. Zero to run all of the {n_worlds} "
                    f"simulations. ^C or a negative number to exit [0 : {n_worlds}]:"
                ))
            if max_runs == 0:
                max_runs = None
            if max_runs is not None and max_runs < 0:
                exit(0)
            worlds_per_config = (None if max_runs is None else int(
                round(max_runs / (configs * runs))))

    if len(jcompetitors) > 0:
        print(
            "You are using java-competitors. The tournament will be run serially"
        )
        parallelism = "serial"

    non_competitor_params = None
    if len(non_competitors) < 1:
        non_competitors = None
    else:
        non_competitors = non_competitors.split(";")
        for i, cp in enumerate(non_competitors):
            if "." not in cp:
                non_competitors[i] = "negmas.apps.scml.factory_managers." + cp

    if ttype.lower() == "anac2019std":
        if non_competitors is None:
            non_competitors = (DefaultGreedyManager, )
            non_competitor_params = ({}, )
        print(
            f"Tournament will be run between {len(all_competitors)} agents: ")
        pprint(all_competitors)
        print("Non-competitors are: ")
        pprint(non_competitors)
        results = create_tournament(
            competitors=all_competitors,
            competitor_params=all_competitors_params,
            non_competitors=non_competitors,
            non_competitor_params=non_competitor_params,
            agent_names_reveal_type=reveal_names,
            n_competitors_per_world=cw,
            n_configs=configs,
            n_runs_per_world=runs,
            max_worlds_per_config=worlds_per_config,
            base_tournament_path=log,
            total_timeout=timeout,
            name=name,
            verbose=verbosity > 0,
            n_agents_per_competitor=1,
            world_generator=anac2019_world_generator,
            config_generator=anac2019_config_generator,
            config_assigner=anac2019_assigner,
            score_calculator=balance_calculator,
            min_factories_per_level=factories,
            compact=compact,
            n_steps=steps,
            log_ufuns=log_ufuns,
            log_negotiations=log_negs,
            ignore_agent_exceptions=not raise_exceptions,
            ignore_contract_execution_exceptions=not raise_exceptions,
            **kwargs,
        )
    elif ttype.lower() in ("anac2019collusion", "anac2019"):
        print(
            f"Tournament will be run between {len(all_competitors)} agents: ")
        pprint(all_competitors)
        print("Non-competitors are: ")
        pprint(non_competitors)
        results = create_tournament(
            competitors=all_competitors,
            competitor_params=all_competitors_params,
            non_competitors=non_competitors,
            non_competitor_params=non_competitor_params,
            agent_names_reveal_type=reveal_names,
            n_competitors_per_world=cw,
            n_configs=configs,
            n_runs_per_world=runs,
            max_worlds_per_config=worlds_per_config,
            base_tournament_path=log,
            total_timeout=timeout,
            name=name,
            verbose=verbosity > 0,
            n_agents_per_competitor=agents,
            world_generator=anac2019_world_generator,
            config_generator=anac2019_config_generator,
            config_assigner=anac2019_assigner,
            score_calculator=balance_calculator,
            min_factories_per_level=factories,
            compact=compact,
            n_steps=steps,
            log_ufuns=log_ufuns,
            log_negotiations=log_negs,
            ignore_agent_exceptions=not raise_exceptions,
            ignore_contract_execution_exceptions=not raise_exceptions,
            **kwargs,
        )
    elif ttype.lower() == "anac2019sabotage":
        print(
            f"Tournament will be run between {len(all_competitors)} agents: ")
        pprint(all_competitors)
        print("Non-competitors are: ")
        pprint(non_competitors)
        results = create_tournament(
            competitors=all_competitors,
            competitor_params=all_competitors_params,
            agent_names_reveal_type=reveal_names,
            n_agents_per_competitor=agents,
            base_tournament_path=log,
            total_timeout=timeout,
            name=name,
            verbose=verbosity > 0,
            n_runs_per_world=runs,
            n_configs=configs,
            max_worlds_per_config=worlds_per_config,
            non_competitors=non_competitors,
            min_factories_per_level=factories,
            n_steps=steps,
            compact=compact,
            log_ufuns=log_ufuns,
            log_negotiations=log_negs,
            ignore_agent_exceptions=not raise_exceptions,
            ignore_contract_execution_exceptions=not raise_exceptions,
            non_competitor_params=non_competitor_params,
            world_generator=anac2019_world_generator,
            config_generator=anac2019_sabotage_config_generator,
            config_assigner=anac2019_sabotage_assigner,
            score_calculator=sabotage_effectiveness,
            **kwargs,
        )
    else:
        raise ValueError(f"Unknown tournament type {ttype}")
    ctx.obj["tournament_name"] = results.name
    ctx.obj["tournament_log_folder"] = log
    ctx.obj["compact"] = compact
    print(
        f"Saved all configs to {str(results)}\nTournament name is {results.name}"
    )
Beispiel #25
0
def scml(steps, levels, neg_speedup, negotiator, agents, horizon,
         min_consumption, max_consumption, transport, time, neg_time,
         neg_steps, sign, guaranteed, lines, retrials, use_consumer,
         max_insurance, riskiness, log):
    params = {
        "steps": steps,
        "levels": levels,
        "neg_speedup": neg_speedup,
        "negotiator": negotiator,
        "agents": agents,
        "horizon": horizon,
        "min_consumption": min_consumption,
        "max_consumption": max_consumption,
        "transport": transport,
        "time": time,
        "neg_time": neg_time,
        "neg_steps": neg_steps,
        "sign": sign,
        "guaranteed": guaranteed,
        "lines": lines,
        "retrials": retrials,
        "use_consumer": use_consumer,
        "max_insurance": max_insurance,
        "riskiness": riskiness
    }
    neg_speedup = neg_speedup if neg_speedup is not None and neg_speedup > 0 else None
    if min_consumption == max_consumption:
        consumption = min_consumption
    else:
        consumption = (min_consumption, max_consumption)
    customer_kwargs = {
        'negotiator_type': negotiator,
        'consumption_horizon': horizon
    }
    miner_kwargs = {'negotiator_type': negotiator, 'n_retrials': retrials}
    factory_kwargs = {
        'negotiator_type': negotiator,
        'n_retrials': retrials,
        'sign_only_guaranteed_contracts': guaranteed,
        'use_consumer': use_consumer,
        'riskiness': riskiness,
        'max_insurance_premium': max_insurance
    }
    if log.startswith('~/'):
        log_dir = Path.home() / log[2:]
    else:
        log_dir = Path(log)
    log_dir = log_dir / unique_name(base='scml', add_time=True, rand_digits=0)
    log_dir = log_dir.absolute()
    os.makedirs(log_dir, exist_ok=True)
    log_file_name = str(log_dir / 'log.txt')
    stats_file_name = str(log_dir / 'stats.json')
    params_file_name = str(log_dir / 'params.json')
    world = SCMLWorld.single_path_world(log_file_name=log_file_name,
                                        n_steps=steps,
                                        negotiation_speed=neg_speedup,
                                        n_intermediate_levels=levels,
                                        n_miners=agents,
                                        n_consumers=agents,
                                        n_factories_per_level=agents,
                                        consumption=consumption,
                                        consumer_kwargs=customer_kwargs,
                                        miner_kwargs=miner_kwargs,
                                        manager_kwargs=factory_kwargs,
                                        transportation_delay=transport,
                                        time_limit=time,
                                        neg_time_limit=neg_time,
                                        neg_n_steps=neg_steps,
                                        default_signing_delay=sign,
                                        n_lines_per_factory=lines)
    failed = False
    strt = perf_counter()
    try:
        for i in progressbar.progressbar(range(world.n_steps),
                                         max_value=world.n_steps):
            elapsed = perf_counter() - strt
            if world.time_limit is not None and elapsed >= world.time_limit:
                break
            if not world.step():
                break
    except Exception:
        exception = traceback.format_exc()
        failed = True
    elapsed = perf_counter() - strt

    def print_and_log(s):
        world.logdebug(s)
        print(s)

    world.logdebug(f'{pformat(world.stats, compact=True)}')
    world.logdebug(
        f'=================================================\n'
        f'steps: {steps}, horizon: {horizon}, time: {time}, levels: {levels}, agents_per_level: '
        f'{agents}, lines: {lines}, guaranteed: {guaranteed}, negotiator: {negotiator}\n'
        f'consumption: {consumption}'
        f', transport_to: {transport}, sign: {sign}, speedup: {neg_speedup}, neg_steps: {neg_steps}'
        f', retrials: {retrials}'
        f', neg_time: {neg_time}\n'
        f'==================================================')

    save_stats(world=world, log_dir=log_dir, params=params)

    if len(world.saved_contracts) > 0:
        data = pd.DataFrame(world.saved_contracts)
        data = data.sort_values(['delivery_time'])
        data = data.loc[:, [
            'seller_type', 'buyer_type', 'seller_name', 'buyer_name',
            'delivery_time', 'unit_price', 'quantity', 'product_name',
            'n_neg_steps', 'signed_at', 'concluded_at', 'cfp'
        ]]
        print_and_log(tabulate(data, headers='keys', tablefmt='psql'))
        n_executed = sum(world.stats['n_contracts_executed'])
        n_negs = sum(world.stats["n_negotiations"])
        n_contracts = len(world.saved_contracts)
        winners = [
            f'{_.name} gaining {world.a2f[_.id].balance / world.a2f[_.id].initial_balance - 1.0:0.0%}'
            for _ in world.winners
        ]
        print_and_log(f'{n_contracts} contracts :-) [N. Negotiations: {n_negs}'
                      f', Agreement Rate: {world.agreement_rate:0.0%}]')
        print_and_log(f'Executed: {world.contract_execution_fraction:0.0%}'
                      f', Breached: {world.breach_rate:0.0%}'
                      f', N. Executed: {n_executed}'
                      f', Business size: {world.business_size}\n'
                      f'Winners: {winners}\n'
                      f'Running Time {humanize_time(elapsed)}')
    else:
        print_and_log('No contracts! :-(')
        print_and_log(f'Running Time {humanize_time(elapsed)}')

    if failed:
        print(exception)
        world.logdebug(exception)
        print(f'FAILED at step {world.current_step} of {world.n_steps}\n')
Beispiel #26
0
def test_unique_name_defaults():
    a = unique_name("")
    assert len(a) == 8 + 1 + 6 + 8
Beispiel #27
0
def scml(
    steps,
    levels,
    neg_speedup,
    negotiator,
    agents,
    horizon,
    min_consumption,
    max_consumption,
    transport,
    time,
    neg_time,
    neg_steps,
    sign,
    guaranteed,
    lines,
    retrials,
    use_consumer,
    max_insurance,
    riskiness,
    competitors,
    jcompetitors,
    log,
    compact,
    log_ufuns,
    log_negs,
    reserved_value,
    balance,
    shared_profile,
    raise_exceptions,
    path,
    world_config,
):
    kwargs = dict(
        no_bank=True,
        no_insurance=False,
        prevent_cfp_tampering=True,
        ignore_negotiated_penalties=False,
        neg_step_time_limit=10,
        breach_penalty_society=0.02,
        premium=0.03,
        premium_time_increment=0.1,
        premium_breach_increment=0.001,
        max_allowed_breach_level=None,
        breach_penalty_society_min=0.0,
        breach_penalty_victim=0.0,
        breach_move_max_product=True,
        transfer_delay=0,
        start_negotiations_immediately=False,
        catalog_profit=0.15,
        financial_reports_period=10,
        default_price_for_products_without_one=1,
        compensation_fraction=0.5,
    )
    if world_config is not None and len(world_config) > 0:
        for wc in world_config:
            kwargs.update(load(wc))
    if len(path) > 0:
        sys.path.append(path)
    if max_insurance < 0:
        warnings.warn(
            f"Negative max insurance ({max_insurance}) is deprecated. Set --max-insurance=inf for always "
            f"buying and --max-insurance=0.0 for never buying. Will continue assuming --max-insurance=inf"
        )
        max_insurance = float("inf")

    if "." not in negotiator:
        negotiator = "negmas.sao." + negotiator

    params = {
        "steps": steps,
        "levels": levels,
        "neg_speedup": neg_speedup,
        "negotiator": negotiator,
        "agents": agents,
        "horizon": horizon,
        "min_consumption": min_consumption,
        "max_consumption": max_consumption,
        "transport": transport,
        "time": time,
        "neg_time": neg_time,
        "neg_steps": neg_steps,
        "sign": sign,
        "guaranteed": guaranteed,
        "lines": lines,
        "retrials": retrials,
        "use_consumer": use_consumer,
        "max_insurance": max_insurance,
        "riskiness": riskiness,
    }
    if compact:
        log_ufuns = False
        log_negs = False
    neg_speedup = neg_speedup if neg_speedup is not None and neg_speedup > 0 else None
    if min_consumption == max_consumption:
        consumption = min_consumption
    else:
        consumption = (min_consumption, max_consumption)
    customer_kwargs = {
        "negotiator_type": negotiator,
        "consumption_horizon": horizon
    }
    miner_kwargs = {"negotiator_type": negotiator, "n_retrials": retrials}
    factory_kwargs = {
        "negotiator_type": negotiator,
        "n_retrials": retrials,
        "sign_only_guaranteed_contracts": guaranteed,
        "use_consumer": use_consumer,
        "riskiness": riskiness,
        "max_insurance_premium": max_insurance,
        "reserved_value": reserved_value,
    }
    if log.startswith("~/"):
        log_dir = Path.home() / log[2:]
    else:
        log_dir = Path(log)
    world_name = unique_name(base="scml", add_time=True, rand_digits=0)
    log_dir = log_dir / world_name
    log_dir = log_dir.absolute()
    os.makedirs(log_dir, exist_ok=True)

    exception = None

    def _no_default(s):
        return not (s.startswith("negmas.apps.scml")
                    and s.endswith("GreedyFactoryManager"))

    all_competitors = competitors.split(";")
    for i, cp in enumerate(all_competitors):
        if "." not in cp:
            all_competitors[i] = "negmas.apps.scml.factory_managers." + cp
    all_competitors_params = [
        dict() if _no_default(_) else factory_kwargs for _ in all_competitors
    ]
    if jcompetitors is not None and len(jcompetitors) > 0:
        jcompetitor_params = [{
            "java_class_name": _
        } for _ in jcompetitors.split(";")]
        for jp in jcompetitor_params:
            if "." not in jp["java_class_name"]:
                jp["java_class_name"] = (
                    "jnegmas.apps.scml.factory_managers." +
                    jp["java_class_name"])
        jcompetitors = ["negmas.apps.scml.JavaFactoryManager"
                        ] * len(jcompetitor_params)
        all_competitors += jcompetitors
        all_competitors_params += jcompetitor_params
        print(
            "You are using some Java agents. The tournament MUST run serially")
        parallelism = "serial"
        if not jnegmas_bridge_is_running():
            print(
                "Error: You are using java competitors but jnegmas bridge is not running\n\nTo correct this issue"
                " run the following command IN A DIFFERENT TERMINAL because it will block:\n\n"
                "$ negmas jnegmas")
            exit(1)

    world = SCMLWorld.chain_world(
        n_steps=steps,
        negotiation_speed=neg_speedup,
        n_intermediate_levels=levels,
        n_miners=agents,
        n_consumers=agents,
        n_factories_per_level=agents,
        consumption=consumption,
        consumer_kwargs=customer_kwargs,
        miner_kwargs=miner_kwargs,
        default_manager_params=factory_kwargs,
        transportation_delay=transport,
        time_limit=time,
        neg_time_limit=neg_time,
        neg_n_steps=neg_steps,
        default_signing_delay=sign,
        n_lines_per_factory=lines,
        compact=compact,
        agent_names_reveal_type=True,
        log_ufuns=log_ufuns,
        manager_types=all_competitors,
        manager_params=all_competitors_params,
        log_negotiations=log_negs,
        log_folder=log_dir,
        name=world_name,
        shared_profile_per_factory=shared_profile,
        initial_wallet_balances=balance,
        ignore_agent_exceptions=not raise_exceptions,
        ignore_contract_execution_exceptions=not raise_exceptions,
        **kwargs,
    )
    failed = False
    strt = perf_counter()
    try:
        for i in progressbar.progressbar(range(world.n_steps),
                                         max_value=world.n_steps):
            elapsed = perf_counter() - strt
            if world.time_limit is not None and elapsed >= world.time_limit:
                break
            if not world.step():
                break
    except Exception:
        exception = traceback.format_exc()
        failed = True
    elapsed = perf_counter() - strt

    def print_and_log(s):
        world.logdebug(s)
        print(s)

    world.logdebug(f"{pformat(world.stats, compact=True)}")
    world.logdebug(
        f"=================================================\n"
        f"steps: {steps}, horizon: {horizon}, time: {time}, levels: {levels}, agents_per_level: "
        f"{agents}, lines: {lines}, guaranteed: {guaranteed}, negotiator: {negotiator}\n"
        f"consumption: {consumption}"
        f", transport_to: {transport}, sign: {sign}, speedup: {neg_speedup}, neg_steps: {neg_steps}"
        f", retrials: {retrials}"
        f", neg_time: {neg_time}\n"
        f"==================================================")

    save_stats(world=world, log_dir=log_dir, params=params)

    if len(world.saved_contracts) > 0:
        data = pd.DataFrame(world.saved_contracts)
        data = data.sort_values(["delivery_time"])
        data = data.loc[data.signed_at >= 0, [
            "seller_type",
            "buyer_type",
            "seller_name",
            "buyer_name",
            "delivery_time",
            "unit_price",
            "quantity",
            "product_name",
            "n_neg_steps",
            "signed_at",
        ], ]
        data.columns = [
            "seller_type",
            "buyer_type",
            "seller",
            "buyer",
            "t",
            "price",
            "q",
            "product",
            "steps",
            "signed",
        ]
        print_and_log(tabulate(data, headers="keys", tablefmt="psql"))

        data["product_id"] = np.array([_.id for _ in data["product"].values])
        d2 = (data.loc[(~(data["signed"].isnull())) &
                       (data["signed"] > -1), :].groupby(
                           ["product_id"]).apply(lambda x: pd.DataFrame([{
                               "uprice":
                               np.sum(x["price"] * x["q"]) / np.sum(x["q"]),
                               "quantity":
                               np.sum(x["q"]),
                           }])))
        d2 = d2.reset_index().sort_values(["product_id"])
        products = dict(zip([_.id for _ in world.products], world.products))
        d2["Product"] = np.array(
            [products[_] for _ in d2["product_id"].values])
        d2 = d2.loc[:, ["Product", "uprice", "quantity"]]
        d2.columns = ["Product", "Avg. Unit Price", "Total Quantity"]
        print_and_log(tabulate(d2, headers="keys", tablefmt="psql"))

        n_executed = sum(world.stats["n_contracts_executed"])
        n_negs = sum(world.stats["n_negotiations"])
        n_contracts = len(world.saved_contracts)
        try:
            agent_scores = sorted(
                [[_.name, world.a2f[_.id].total_balance]
                 for _ in world.agents.values()
                 if isinstance(_, FactoryManager)],
                key=lambda x: x[1],
                reverse=True,
            )
            agent_scores = pd.DataFrame(data=np.array(agent_scores),
                                        columns=["Agent", "Final Balance"])
            print_and_log(
                tabulate(agent_scores, headers="keys", tablefmt="psql"))
        except:
            pass
        winners = [
            f"{_.name} gaining {world.a2f[_.id].total_balance / world.a2f[_.id].initial_balance - 1.0:0.0%}"
            for _ in world.winners
        ]
        print_and_log(
            f"{n_contracts} contracts :-) [N. Negotiations: {n_negs}, Agreement Rate: "
            f"{world.agreement_rate:0.0%}]"
            f" (rounds/successful negotiation: {world.n_negotiation_rounds_successful:5.2f}, "
            f"rounds/broken negotiation: {world.n_negotiation_rounds_failed:5.2f})"
        )
        print_and_log(
            f"Cancelled: {world.cancellation_rate:0.0%}, Executed: {world.contract_execution_fraction:0.0%}"
            f", Breached: {world.breach_rate:0.0%}, N. Executed: {n_executed}, Business size: "
            f"{world.business_size}\n"
            f"Winners: {winners}\n"
            f"Running Time {humanize_time(elapsed)}")
    else:
        print_and_log("No contracts! :-(")
        print_and_log(f"Running Time {humanize_time(elapsed)}")

    if failed:
        print(exception)
        world.logdebug(exception)
        print(f"FAILED at step {world.current_step} of {world.n_steps}\n")