Sznajd

The Sznajd model [1] is a binary opinion dynamics model inspired by the principle "United we stand, divided we fall." Each node holds a binary opinion \(h \in \{0, 1\}\). At each time step:

  1. a node \(u\) is selected uniformly at random from the network;

  2. a neighbor \(v \in N(u)\) of node \(u\) is selected uniformly at random;

  3. if \(u\) and \(v\) share the same opinion (\(h_u = h_v\)), all neighbors of both \(u\) and \(v\) adopt that shared opinion;

  4. if \(u\) and \(v\) disagree (\(h_u \neq h_v\)), no opinion change occurs.

Implementation

The Sznajd model propagates consensus along agreed-upon edges: when two connected nodes share the same opinion, they jointly persuade all of their neighbors to adopt that opinion. Self-loops are removed to prevent a node from influencing itself. The model uses max aggregation to broadcast the agreed opinion to the neighborhoods of the two concordant nodes.

Sznajd model diagram
  1. A node \(u\) is selected uniformly at random. A neighbor \(v \in N(u)\) is chosen uniformly at random.

  2. If \(u\) and \(v\) agree (\(h_u^{(k-1)} = h_v^{(k-1)}\)), construct an auxiliary signal vector over all nodes:

\[\begin{split}x_j = \begin{cases} h_u^{(k-1)}, & \text{if } j \in \{u, v\}, \\[6pt] -1, & \text{otherwise}. \end{cases}\end{split}\]
  1. Propagate \(x\) over the graph using max aggregation. Each node receives the maximum signal among its neighbors:

\[m_j^{(k)} = \max_{i \in N(j)}\, x_i\]

Nodes adjacent to \(u\) or \(v\) will receive \(h_u^{(k-1)} \in \{0,1\}\), while all other nodes receive \(-1\).

  1. Update opinions for nodes that received a valid signal:

\[\begin{split}h_j^{(k)} = \begin{cases} m_j^{(k)}, & \text{if } m_j^{(k)} \neq -1, \\[6pt] h_j^{(k-1)}, & \text{otherwise}. \end{cases}\end{split}\]

If \(u\) and \(v\) disagree (\(h_u^{(k-1)} \neq h_v^{(k-1)}\)), all opinions remain unchanged: \(h_j^{(k)} = h_j^{(k-1)}\) for every node \(j\).

Status

During the simulation, a node holds a binary opinion value:

Status

Value

Opinion

0 or 1

SznajdModel

class fs_gplib.Opinions.SznajdModel(data, seeds, device='cpu', rand_seed=None)[source]

Bases: DiffusionModel

Binary Sznajd opinion dynamics model on static graphs.

Inspired by "United we stand, divided we fall," each node holds a binary opinion \(h \in \{0, 1\}\). At each step: a node \(u\) is chosen uniformly at random; a neighbor \(v \in N(u)\) is chosen uniformly at random among neighbors of \(u\). If \(h_u = h_v\), all neighbors of both \(u\) and \(v\) adopt that shared opinion; if \(h_u \neq h_v\), no node changes opinion.

Self-loops are removed so a node cannot influence itself. Returned tensors encode opinion 0 or 1.

Parameters:
  • data (torch_geometric.data.Data) -- PyTorch Geometric Data representing \(G=(V,E)\). Must provide edge_index and num_nodes.

  • seeds (list[int] | float | None) -- Nodes with initial opinion 1. Pass a list of node IDs, a float in (0,1) to initialise that fraction with opinion 1, or None.

  • device (str | int) -- (optional) 'cpu' or a CUDA device index. Defaults to 'cpu'.

  • rand_seed (int | None) -- (optional) Random seed used when seeds is a float. Defaults to None.

run_iteration()[source]

Execute a single opinion-update step.

The internal node_status is updated so that subsequent calls continue from the latest opinion configuration.

Returns:

Node opinions after one step, shape (1, N).

Return type:

torch.Tensor

run_iterations(times)[source]

Execute times opinion-update steps sequentially.

The internal node_status is updated in-place so that subsequent calls continue from the latest opinion configuration.

Parameters:

times (int) -- Number of steps to run.

Returns:

Node opinions at final step, shape (1, N).

Return type:

torch.Tensor

run_epoch(iterations_times)[source]

Run a single Monte-Carlo epoch (one independent realisation).

Node opinions are re-initialised before the epoch starts.

Parameters:

iterations_times (int) -- Number of opinion-update steps per epoch.

Returns:

Node opinions at final step of the epoch, shape (1, N).

Return type:

torch.Tensor

run_epochs(epochs, iterations_times, batch_size=200)[source]

Run multiple independent Monte-Carlo epochs in batches.

Node opinions are re-initialised before the run.

Parameters:
  • epochs (int) -- Total number of independent realisations.

  • iterations_times (int) -- Number of opinion-update steps per epoch.

  • batch_size (int) -- (optional) Number of epochs processed in parallel per batch. Defaults to 200.

Returns:

Node opinions at final step of all epochs, shape (epochs, N).

Return type:

torch.Tensor

References