Experiment class

class defSim.Experiment.Experiment(simulations: Optional[List[defSim.Simulation.Simulation]] = None, network: Optional[networkx.classes.graph.Graph] = None, communication_regime: List = 'one-to-one', topology: str = 'grid', network_parameters: dict = {}, attributes_initializer: str = 'random_categorical', attribute_parameters: dict = {}, focal_agent_selector: str = 'random', focal_agent_parameters: dict = {}, neighbor_selector: str = 'random', neighbor_parameters: dict = {}, influence_function: str = 'similarity_adoption', influence_parameters: dict = {}, influenceable_attributes: Optional[list] = None, network_modifiers: Optional[List[defSim.network_evolution_sim.network_evolution_sim.NetworkModifier]] = None, network_modifier_parameters: dict = {}, dissimilarity_measure: str = 'hamming', tickwise: list = [], stop_condition: str = 'max_iteration', stop_condition_parameters: dict = {}, max_iterations: int = 100000, output_realizations: list = [], output_folder_path: Optional[str] = None, output_file_types: List[str] = [], repetitions: int = 1, seed: Optional[int] = None)

Bases: object

The main class for creating and running experiments. Each simulation consists of 7 modular components, where each component is independent from the others and can thus be replaced by a different implementation of that component. These components are:

The network structure - Can either be loaded from empirical data or initialized with the NetworkGenerator.

The AttributesInitializer - This component initializes the attributes of each agent in the network and can also be used to add attributes during the simulation.

The FocalAgentSelector - Each simulation step, this component picks an agent from the network, either randomly or based on their characteristics.

The neighborhoodSelector - Selects a subset of the agents in the network based on the focal agent given by the FocalAgentSelector

The InfluenceFunction - Determines how the selected agent and the selected neighborhood influence each other.

The NetworkModifier - Changes the structure of the network during the simulation.

The DissimilarityCalculator - Determines how the dissimilarity/distance between two agents is calculated

These components have different concrete implementations that might take specific parameters that are passed as a dictionary. In these dictionaries, the keys are the names of the parameters and the values their respective value. It is also possible to pass a list of values as the dictionary value, which then creates a simulation for each value, making it possible to easily compare simulation runs with e.g. different number of agents.

Alternatively, customizations outside of these parameters can be applied to individual simulations. These simulations can then be passed as a list and executed as an experiment.

Parameters
  • simulations (List[Simulation] or None) – This is a list of simulations to run. If simulations is not None, no new simulations are generated regardless of parameters specified.

  • network (nx.Graph, np.array or String) – This is either a preloaded networkx graph, an adjacency matrix as a numpy array, the full path to a file with and edge list, or “list”. If “list”, a list of networks can be passed to one of the parameter dicts (suggested: network_parameters) which will be iterated over in the simulations of the experiment.

  • communication_regime (List or String = "one-to-one") – Options are “one-to-one”, “one-to-many” and “many-to-one”. For this parameter, it is possible to pass a list of multiple of these options.

  • topology (String = "grid") – Options are “grid”, “ring” and “spatial_random_graph”.

  • network_parameters (dict = {}) – This dictionary should contain all optional parameters for creating the network structure. Refer to the specific documentation of the network types to see what can be modified.

  • attributes_initializer (String = “random_categorical” or AttributesInitializer) – Either be a custom AttributesInitializer or a string that selects from the predefined choices: [“random_categorical”, “random_continuous”…]

  • attribute_parameters (dict = {}) – Optional dictionary that includes the name of attributes you want to set and a list of possible values for each.

  • focal_agent_selector (str = “random” or FocalAgentSelector) – Either a custom FocalAgentSelector or a string that selects from the predefined options [“random”, …]

  • focal_agent_parameters (dict = {}) – Optional dictionary that includes the parameters for the FocalAgentSelector.

  • neighbor_selector (str = “random” or NeighborSelector) – Either a custom NeighborSelector or a string that selects from the predefined options [“random”, “similar”, …}

  • neighbor_parameters (dict = {}) – Optional dictionary that includes the parameters for the NeighborSelector.

  • influence_function (str = “similarity_adoption” or InfluenceOperator) – Either a custom influence function or a string that selects from the predefined options [“similarity_adoption”, “bounded_confidence”, “weighted_linear”, …}

  • influence_parameters (dict = {}) – Optional dictionary that includes the parameters for the InfluenceFunction.

  • influenceable_attributes (list = []) – With this list you select all attributes that are allowed to be changed by the influence function. If the list is empty, all attributes are affected by influence.

  • network_modifiers (NetworkModifier or List = None) – A modifier or list of modifiers to apply to the network after initialization. Each modifier should be derived from the NetworkModifier base class.

  • dissimilarity_measure (String = “hamming” or DissimilarityCalculator) – Either a custom DissimilarityCalculator or a string that selects from the predefined options [“hamming”, “euclidean”, …}

  • tickwise (List = []) – A list containing the names of all agent attributes that should be recorded at every timestep.

  • stop_condition (String = "pragmatic_convergence") – Determines at what point a simulation is supposed to stop. Options include “strict_convergence”, which means that it is theoretically not possible anymore for any agent to influence another, “pragmatic_convergence”, which means that it is assumed that little change is possible anymore, and “max_iteration” which just stops the simulation after a certain amount of time steps.

  • stop_condition_parameters (dict = {}) – This dictionary should contain all optional parameters that influence how convergence is determined.

  • max_iterations (int = 100000) – The maximum number of iterations a Simulation should run.

  • output_realizations (list = [str or OutputTableCreator]) – This optional list should contain all output to generate at the end of each run, by name for defaults or as class inheriting from OutputTableCreator

  • output_folder_path (str or pathlib.Path) – If not None, the output table is saved to file(s) in this location.

  • output_file_types (List[str or DataFileCreator]) – Determines which types of output files will be saved at output_folder_path. See tools.CreateDataFiles for options.

  • repetitions (int = 1) – How often each simulation should be repeated.

  • seed (int = random.randint(10000, 99999)) – Optionally set seed for replicability.

__init__(simulations: Optional[List[defSim.Simulation.Simulation]] = None, network: Optional[networkx.classes.graph.Graph] = None, communication_regime: List = 'one-to-one', topology: str = 'grid', network_parameters: dict = {}, attributes_initializer: str = 'random_categorical', attribute_parameters: dict = {}, focal_agent_selector: str = 'random', focal_agent_parameters: dict = {}, neighbor_selector: str = 'random', neighbor_parameters: dict = {}, influence_function: str = 'similarity_adoption', influence_parameters: dict = {}, influenceable_attributes: Optional[list] = None, network_modifiers: Optional[List[defSim.network_evolution_sim.network_evolution_sim.NetworkModifier]] = None, network_modifier_parameters: dict = {}, dissimilarity_measure: str = 'hamming', tickwise: list = [], stop_condition: str = 'max_iteration', stop_condition_parameters: dict = {}, max_iterations: int = 100000, output_realizations: list = [], output_folder_path: Optional[str] = None, output_file_types: List[str] = [], repetitions: int = 1, seed: Optional[int] = None)

Initialize self. See help(type(self)) for accurate signature.

estimate_runtime(sample_runs: Optional[int] = None, sample_steps: int = 10)

If simulations are specified, this function infers the experiment runtime from sampled runs/steps.

If no simulations are specified, function creates the parameterDictList if that hasn’t happened already and then infers from sampled runs the runtime of the whole experiment.

Runtime estimates are for running on a single core.

Parameters
  • sample_runs (int=None) – The number of entries in the parameterDictList to sample in order to estimate the runtime.

  • sample_steps (int=10) – The number of iterations executed in each simulation run to base the estimated runtime on.

Returns

estimated time of simulation in seconds

return_values()

This method returns the values stored in the Experiment object. Both default, and user-specified values are returned to the console to make the Experiment object more transparent.

Returns

True

run(parallel: bool = False, num_cores=8, show_progress: bool = True) → pandas.core.frame.DataFrame

If the experiment is defined by a list of simulations: Runs each simulation.

If the experiment is defined by parameter combinations: Starts the experiment by first creating the parameter_dict_list if that hasn’t happened already and then creates a simulation for each parameter combination in the parameter_dict_list.

If parallel is true, the simulations are run on multiple cores on the machine, their number determined by num_cores.

Parameters
  • parallel – Boolean that determines in which mode the simulations will run.

  • num_cores – Determines the number of cores in the machine that will be utilized for the execution.

  • show_progress – Boolean that determines whether to show a progress bar.

Returns

A dataframe that contains one row per Simulation.

run_on_cluster(chunk_size: int = 2400, batch_path: str = 'batchscripts', output_path: str = 'output', walltime: str = '30:00', partition: str = 'short')

This method can be used to execute large Experiments on a SLURM cluster. It creates a number of sbatch scripts that are immediatly executed to send jobs to the SLURM job manager. To be able to use this method the script with the Experiment must be executed on a SLURM server.

Parameters
  • chunk_size – Determines how many Simulations should run per node in the cluster.

  • batch_path – The path to the folder where the batchscripts will be created. If the folder not exists yet, it will be created.

  • output_path – The path to the folder where the output will be saved. If the folder not exists yet, it will be created.

  • walltime – The expected time one node maximally needs for computing its chunk of simulations.

  • partition – If the SLURM cluster has multiple partitions, it can be decided where to run the jobs with this parameter.