nxsim 0.1.2
nxsim is a Python package for simulating agents in a network.
License: Apache License, Version 2.0
Keywords: networks, simulation, complex networks, discrete event simulation, forward simulation, temporal networks

`nxsim`_
========

Nxsim is a Python package for simulating agents connected by any type of
network using SimPy and Networkx in Python 3.4.

Install
-------

::

    pip3 install nxsim  # from PyPI
    pip3 install git+git://github.com/kentwait/nxsim.git  # from GitHub


Quickstart
----------

Nxsim provides a framework for doing forward-time simulations of events
occurring in a network. It uses Networkx to create a network and SimPy 3
to create agents over each node in the network.

To create a simulation, nxsim requires a graph generated by Networkx and
an “agent” class to populate each node of the network.

First, create a graph using Networkx.

::

    import networkx as nx

    number_of_nodes = 10
    G = nx.complete_graph(number_of_nodes)

Then, subclass *BaseNetworkAgent* to create your own agent based on your
needs.

::

    from nxsim import BaseNetworkAgent

    # Just like subclassing a process in SimPy
    class MyAgent(BaseNetworkAgent):
        def __init__(self, environment=None, agent_id=0, state=()):  # Make sure to have these three keyword arguments
            super().__init__(environment=environment, agent_id=agent_id, state=state)
            # Add your own attributes here

        def run(self):
            # Add your behaviors here

Notice that “agents” in nxsim use the same concepts as “processes” in
SimPy 3 except that their interactions can be limited by the graph in
the simulation environment. For more information about SimPy, they have
a great introduction posted on their `website`_.

Here is a graph-based example:

::

    import random
    from nxsim import BaseNetworkAgent

    class ZombieOutbreak(BaseNetworkAgent):
        def __init__(self, environment=None, agent_id=0, state=()):
            super().__init__(environment=environment, agent_id=agent_id, state=state)
            self.bite_prob = 0.05

        def run(self):
            while True:
                if self.state['id'] == 1:
                    self.zombify()
                    yield self.env.timeout(1)
                else:
                    yield self.env.event()

        def zombify(self):
            normal_neighbors = self.get_neighboring_agents(state_id=0)
            for neighbor in normal_neighbors:
                if random.random() < self.bite_prob:
                    neighbor.state['id'] = 1  # zombie
                    print(self.env.now, self.id, neighbor.id, sep='\t')
                    break

You can now set-up your simulation by creating a *NetworkSimulation*
instance.

::

    from nxsim import NetworkSimulation

    # Initialize agent states. Let's assume everyone is normal.
    # Add keys as as necessary, but "id" must always refer to that state category
    init_states = [{'id': 0, } for _ in range(number_of_nodes)]

    # Seed a zombie
    init_states[5] = {'id': 1}
    sim = NetworkSimulation(topology=G, states=init_states, agent_type=ZombieOutbreak,
                            max_time=30, dir_path='sim_01', num_trials=1, logging_interval=1.0)

And finally, start it up.

::

    sim.run_simulation()

Running the simulation saves pickled dictionaries into the *dir\_path*
folder, in this case to “sim\_01”. Now, let’s retrieve the history and
states of the trial

::

    trial = BaseLoggingAgent.open_trial_state_history(dir_path='sim_01', trial_id=0)

And plot the number of zombies per time interval using matplotlib:

::

    from matplotlib import pyplot as plt
    zombie_census = [sum([1 for node_id, state in g.items() if state['id'] == 1]) for t,g in trial.items()]
    plt.plot(zombie_census)

And that’s it!

Note
====

This package is still under development. If you encounter a bug, please
file an issue at https://github.com/kentwait/nxsim/issues to get it
resolved.

Acknowledgment
==============

Thanks to Joé Schaul for bringing `ComplexNetworkSim`_ to the world.
This project is a SimPy 3- and Python 3.4-compatible fork of
ComplexNetworkSim.

Links
=====

-  `nxsim - Github`_
-  `nxsim - PyPI`_
-  `SimPy v3.0 Documentation`_
-  `Networkx v1.9 Documentation`_
-  `matplotlib v1.4.3 Documentation`_
-  `ComplexNetworkSim Documentation`_

.. _nxsim: https://github.com/kentwait/nxsim
.. _website: https://simpy.readthedocs.org/en/latest/simpy_intro/index.html
.. _ComplexNetworkSim: https://github.com/jschaul/ComplexNetworkSim
.. _nxsim - Github: https://github.com/kentwait/nxsim
.. _nxsim - PyPI: https://pypi.python.org/pypi/nxsim
.. _SimPy v3.0 Documentation: https://simpy.readthedocs.org/en/latest/contents.html
.. _Networkx v1.9 Documentation: http://networkx.github.io/documentation/networkx-1.9.1
.. _matplotlib v1.4.3 Documentation: http://matplotlib.org/users/
.. _ComplexNetworkSim Documentation: https://pythonhosted.org/ComplexNetworkSim