# Attraction-Repulsion Weighted Hegselmann-Krause¶

The Attraction-Repulsion Weighted Hegselmann-Krause was introduced by Toccaceli et al. in 2020 [1].

This model is a variation of the Weighted Hegselmann-Krause (WHK). To model the attraction and repulsion of opinions, during each iteration an agent $$i$$ is randomly selected along with one of its neighbors, $$j$$ - not taking into account the $$\epsilon$$ threshold. Once identified the pair-wise interaction, the absolute value of the difference between the opinions of $$i$$ and $$j$$ is computed. If such a value is lower than $$\epsilon$$ then the attractive interaction occurs and the following update rule are applied:

$\begin{split}x_i(t+1)=\begin{cases} x_i(t) - \frac{sum_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) \geq 0, x_i(t) > x_j(t) }\\ x_i(t) + \frac{sum_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) \geq 0, x_i(t) < x_j(t) } \\ x_i(t) + \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) < 0, x_i(t) > x_j(t) }\\ x_i(t) - \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) < 0, x_i(t) < x_j(t) } \\ x_i(t) - \frac{sum_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) < 0, sum_{op} > 0}\\ x_i(t) + \frac{sum,_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) < 0, sum_{op} < 0}\\ x_i(t) + \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) \geq 0, sum_{op} > 0}\\ x_i(t) - \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) \geq 0, sum_{op} < 0}\\ \end{cases}\end{split}$

where $$sum_{op} = x_i(t) + x_j(t)w_{i,j}$$.

If the difference between $$x_i(t)$$ and $$x_j(t)$$ exceeds $$\epsilon$$ then the repulsive interaction occurs and the following update rule are applied:

$\begin{split}x_i(t+1)=\begin{cases} x_i(t) + \frac{sum{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) \geq 0, x_i(t) > x_j(t) }\\ x_i(t) - \frac{sum_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) \geq 0, x_i(t) < x_j(t) } \\ x_i(t) - \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) < 0, x_i(t) > x_j(t) }\\ x_i(t) + \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) < 0, x_i(t) < x_j(t) } \\ x_i(t) + \frac{sum_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) < 0, sum_{op} > 0}\\ x_i(t) - \frac{sum_{op}}{2} (1-x_i(t)) & \text{if x_i(t) \geq 0, x_j(t) < 0, sum_{op} < 0}\\ x_i(t) - \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) \geq 0, sum_{op} > 0}\\ x_i(t) + \frac{sum_{op}}{2} (1+x_i(t)) & \text{if x_i(t) < 0, x_j(t) \geq 0, sum_{op} < 0}\\ \end{cases}\end{split}$

where $$sum_{op} = x_i(t) + x_j(t)w_{i,j}$$.

## Statuses¶

Node statuses are continuous values in [-1,1].

## Parameters¶

Name Type Value Type Default Mandatory Description
epsilon Model float in [0, 1] True Bounded confidence threshold
perc_stubborness Model float in [0, 1] 0 False Percentage of stubborn agent
similarity Model int in {0, 1} 0 False The method use the feature of the nodes ot not
option_for_stubbornness Model int in {-1,0, 1} 0 False Define distribution of stubborns
weight Edge float in [0, 1] 0.1 False Edge weight
stubborn Node int in {0, 1} 0 False The agent is stubborn or not
vector Node Vector of float in [0, 1] [] False Vector represents the character of the node

## Methods¶

The following class methods are made available to configure, describe and execute the simulation:

### Configure¶

class ndlib.models.opinions.ARWHKModel.ARWHKModel(graph)

Model Parameters to be specified via ModelConfig :param epsilon: bounded confidence threshold from the HK model (float in [0,1]) :param perc_stubborness: Percentage of stubborn agent (float in [0,1], default 0) :param option_for_stubbornness: Define distribution of stubborns (in {-1, 0, 1}, default 0) :param similarity: the method uses the similarity or not ( in {0,1}, default 0) :param weight: the weight of edges (float in [0,1]) :param stubborn: The agent is stubborn or not ( in {0,1}, default 0) :param vector: represents the character of the node (list in [0,1], default [])

ARWHKModel.__init__(graph)

Model Constructor :param graph: A networkx graph object

ARWHKModel.set_initial_status(self, configuration)

Override behaviour of methods in class DiffusionModel. Overwrites initial status using random real values.

ARWHKModel.reset(self)

Reset the simulation setting the actual status to the initial configuration.

### Describe¶

ARWHKModel.get_info(self)

Describes the current model parameters (nodes, edges, status)

Returns: a dictionary containing for each parameter class the values specified during model configuration
ARWHKModel.get_status_map(self)

Specify the statuses allowed by the model and their numeric code

Returns: a dictionary (status->code)

### Execute Simulation¶

ARWHKModel.iteration(self)

Execute a single model iteration

Returns: Iteration_id, Incremental node status (dictionary code -> status)
ARWHKModel.iteration_bunch(self, bunch_size)

Execute a bunch of model iterations

Parameters: bunch_size – the number of iterations to execute node_status – if the incremental node status has to be returned. progress_bar – whether to display a progress bar, default False a list containing for each iteration a dictionary {“iteration”: iteration_id, “status”: dictionary_node_to_status}

## Example¶

In the code below is shown an example of instantiation and execution of an ARWHK model simulation on a random graph: we set the initial set of infected nodes as 1% of the overall population, assign an epsilon value of 0.32, the percentage of stubborness equal 0.2, the distribution of stubborness equal 0 and a weight equal 0.2 to all the edges.

import networkx as nx
import ndlib.models.ModelConfig as mc
import ndlib.models.opinions as opn

# Network topology
g = nx.erdos_renyi_graph(1000, 0.1)

# Model selection
model = opn.ARWHKModel(g)

# Model Configuration
config = mc.Configuration()

# Setting the edge parameters
weight = 0.2
if isinstance(g, nx.Graph):
edges = g.edges
else:
edges = [(g.vs[e.tuple[0]]['name'], g.vs[e.tuple[1]]['name']) for e in g.es]

for e in edges: