Run a session of the SCML world

The SCML world (Supply Chain Management League) ships as an example world with NegMAS. It is used as one of the leagues of ANAC 2019.

In this tutorial, you will test a run of this world.

Firstly, let’s import everything from the SCML app

from negmas.apps.scml import *

There are several ways to create an SCML world. One of the simplest is to use one of the class methods of the SCMLWorld class.

The resulting world will have 100 production steps so simulating it will take several minutes. To speed up the simulation, use a small number of n_steps (e.g. 10)

If you want to just test your installation (and do not care whether you get an accurate indicator of agent performance), you can set the number of steps to a small value (e.g. n_steps=10).

world = SCMLWorld.chain_world(agent_names_reveal_type=True, n_steps=100, n_intermediate_levels=1, compact=True, log_file_name='')

For debugging purposes, we set agent_names_reveal_type to true to be able to know the type of an agent from its name. During the actual ANAC 2019 competition this is passed as False preventing agents from knowing the type of other agents by just inspecting their name. Now you can run this world simulation by just calling run.

world.run()

Let’s see what happened in this run. Firstly, how many negotiations were conducted over time

plt.plot(world.stats['n_negotiations'])
plt.xlabel('Simulation Step')
plt.ylabel('N. Negotiations')
plt.show()
../_images/01.run_scml2019_7_0.png

It is clear that many negotiations happened at the beginning of the simulation with smaller number later. That is expected as the consumers publish their calls for proposals early on.

Several other statistics are available:

print(list(world.stats.keys()))
['n_cfps_on_board_before', 'n_registered_negotiations_before', 'n_contracts_executed', 'n_contracts_cancelled', 'n_breaches', 'breach_level', 'n_contracts_signed', 'n_contracts_concluded', 'n_negotiations', 'n_negotiation_rounds_successful', 'n_negotiation_rounds_failed', 'n_registered_negotiations_after', 'activity_level', 'n_cfps', 'n_cfps_on_board_after', 'n_contracts_nullified', 'n_bankrupt', '_balance_bank', '_balance_society', '_balance_insurance', '_storage_insurance', 'balance_m_0', 'storage_m_0', 'balance_m_1', 'storage_m_1', 'balance_m_2', 'storage_m_2', 'balance_m_3', 'storage_m_3', 'balance_m_4', 'storage_m_4', 'balance_c_0', 'storage_c_0', 'balance_c_1', 'storage_c_1', 'balance_c_2', 'storage_c_2', 'balance_c_3', 'storage_c_3', 'balance_c_4', 'storage_c_4', 'balance_greedy@1_0', 'storage_greedy@1_0', 'balance_greedy@1_1', 'storage_greedy@1_1', 'balance_greedy@1_2', 'storage_greedy@1_2', 'balance_greedy@1_3', 'storage_greedy@1_3', 'balance_greedy@1_4', 'storage_greedy@1_4', 'balance_greedy@2_0', 'storage_greedy@2_0', 'balance_greedy@2_1', 'storage_greedy@2_1', 'balance_greedy@2_2', 'storage_greedy@2_2', 'balance_greedy@2_3', 'storage_greedy@2_3', 'balance_greedy@2_4', 'storage_greedy@2_4', 'market_size', 'production_failures', '_market_size_total']

We can for example check the activity level of this world (defined as the total amount of money transferred due to trade)

plt.plot(world.stats['activity_level'])
plt.xlabel('Simulation Step')
plt.ylabel('Activitiy Level ($)\nTotal Money Transferred')
plt.show()
../_images/01.run_scml2019_11_0.png

We can see a picture of contracting in this world as follows:

plt.plot(world.stats['n_contracts_concluded'], label='Concluded Contracts')
plt.plot(world.stats['n_contracts_cancelled'], label='Cancelled Contracts')
plt.plot(world.stats['n_contracts_signed'], label='Signed Contracts')
plt.plot(world.stats['n_contracts_executed'], label='Executed Contracts')
plt.legend()
plt.xlabel('Simulation Step')
plt.ylabel('N. Contracts')
plt.show()
../_images/01.run_scml2019_13_0.png

We can also check the breaches that happened

plt.plot(world.stats['breach_level'])
plt.xlabel('Simulation Step')
plt.ylabel('Total Breach Level')
plt.show()
../_images/01.run_scml2019_15_0.png

It is also possible to focus on the behavior of some specific agent. Let’s first find who was the winner (the factory manager that got maximum wealth). Notice that there can be multiple winners

winner_profits = [round(100.0 * world.stats[f'balance_{_}'][-1] / world.stats[f'balance_{_}'][0] - 100.0, 2) for _ in world.winners]
print(f"{world.winners} won at {winner_profits}%")
[greedy@2_3] won at [44.77]%

What was the balance of this winner over time:

for winner in world.winners:
    plt.plot(world.stats[f'balance_{winner}'], label=f'{winner}\n({winner.__class__.__name__})')
plt.legend()
plt.xlabel('Simulation Step')
plt.ylabel('Winner\'s Balance ($)')
plt.show()
../_images/01.run_scml2019_19_0.png

Let’s check how did its total storage change over time:

for winner in world.winners:
    plt.plot(world.stats[f'storage_{winner}'], label=winner)
plt.xlabel('Simulation Step')
plt.ylabel('Player\'s Total Storage (item)')
plt.legend()
plt.show()
../_images/01.run_scml2019_21_0.png

We can actually check what happens to ALL competitors:

for name, _ in sorted(((_.name, _) for _ in world.factory_managers), key=lambda x: x[0]):
    plt.plot(world.stats[f'balance_{name}'], label=name)
plt.xlabel('Simulation Step')
plt.ylabel('Player Balance ($)')
plt.legend()
plt.show()
../_images/01.run_scml2019_23_0.png

Download Notebook.