Version_20250913-1_Spread of Opinions Influenced by Group Effects
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This simulator was designed from research by the Public Opinion Research Group.
It models how opinions on political or social issues spread inside a population, using a multi-agent system.
This work has focused on modelling the Quebec electorate facing political issues. Surveys have revealed the close relationship among the electorate between the bias level on these issues and the importance of representations underlying the accession of voters to these issues, i.e. the significance of this adhesion for each voter.
The operation of this multi-agent simulator is based on this relationship. It models the transmission in a population of a bipolar view.
Four factors are used to simulate the rules of meme transmission: prevalence, polarization of opinion, influence, and social links.
- Prevalence simulates the quality and quantity of mental representations an individual may have about an issue or “meme”. A meme can be more or less prominent or polarised in the mind of its owner.
- Polarization expresses how strongly opinions are opposed.
- Influence is the ability of individuals to convince others.
- Social links simulate the relations of proximity or randomness among individuals who share similar memes or hold opposing opinions.
Agents carry: - an opinion (−1 to +1), - a prevalence (strength/salience), - an influence (capacity to convince), - and a set of social links.
The model studies the co-evolution of: 1. Individual convictions, 2. Salience of issues (prevalence), 3. Influence capacities, 4. Social network structure.
HOW TO USE IT
Basic operation
- Choose the population size in
pop
. - Press Setup to generate agents and their initial links (the background is set to black).
- Press Go to run or pause the simulation.
Agents in 3D: - X axis: opinion (–1 = left, +1 = right), - Y axis: prevalence (0–99), - Z axis: influence (0–1).
Links (ties) are coloured: - Green: both agents share the same sign (homophily), - Gray: opposite signs (bridges).
Their thickness is controlled by the slider linktick
.
Use the show-links?
switch to display or hide ties.
Social network dynamics
Links are created or removed according to opinion distance:
link-removal-threshold
: maximum opinion gap above which a link can be removed.link-formation-threshold
: maximum gap for forming new ties.prob
: probability applied to link removal/creation.linksdown
: maximum number of links removed per tick.linksup
: maximum number of links created per tick.
The
bridge-prob
slider lets you add a probability of creating bridges between opposite camps (see below).
Loading data
Use in_file to import a text file with space-separated columns:
choice_iter
selects which iteration to load, allowing you to replay or branch from a saved configuration.
Meta-influencers
Meta-influencers are agents given a very high ability to convince others (influence = 1
at setup).
You can configure them as follows:
meta-influencers-selection
: choose their group (All, Left, or Right).meta-influencers
: proportion of the population designated as meta-influencers.prev-low
/prev-high
: restrict eligible agents based on prevalence.meta-links
,meta-min
,meta-max
: control how many extra social links they can create.meta-ok
: toggle their activation during the simulation.- The Influent button allows you to add new ones during a run.
Influence dynamics when
vary-influence
is ONMeta-influencers (and any agent initially set with
influence = 1
) do not keep a fixed persuasion strength.
Their ability to convince others adapts based on how effective they are:
- When an agent successfully changes the target’s opinion, its
influence
value increases (up to1
).- When the attempt fails, its
influence
value decreases (down to0
).Over time, agents who frequently persuade others become stronger influencers, while those who fail repeatedly lose their power.
Prevalence & influence dynamics
modulation-prevalence
+rate-modulation
: adjust prevalence as opinions shift.rate-infl
: speed at which influence increases or decreases after adoption attempts.noise
: introduces random opinion drift (external shocks).polarization-factor
: lowers adoption probability when opinions are very far apart.
External events
You can perturb the system:
- Define opinion bounds (
low_meme
,high_meme
) and prevalence bounds (low-prev
,high-prev
). - Choose
event_size
(opinion shift) andprev_change
(prevalence shift). - Trigger:
- Manually with the event button,
- Automatically by enabling
auto_event
and settingtick-event
.
>Meme_set
can restrict the event to agents classified at startup as left or right.
- Manually with the event button,
NEW & ENHANCED FEATURES
- 3D view: agents plotted by opinion (X), prevalence (Y), and influence (Z).
- Dynamic links: continuously updated as opinions evolve.
- Link colouring:
- Green → same-signed opinions,
- Gray → opposite signs (including links with meta-influencers).
- Green → same-signed opinions,
- Meta-influencer links managed with limits (
meta-min
→meta-max
). - Prevalence modulation and noise integrated into adoption rules.
- CSV export per trial: logs statistics every tick.
- Toggle
show-links?
to display or hide ties. - Background set to black at setup.
Group impact parameters
These controls determine how much the alignment of an agent’s neighbours affects adoption.
group-impact-weight
Strength of the group effect (0 = none, 1 = full).
🔢 group-k
– Number of Neighbours Considered
Defines how many linked neighbours of the target are examined when calculating the group alignment (only if group-impact-mode = "k-nearest"
).
1
: only the single closest neighbour.3–5
: focus on the most similar contacts.20+
: approximate the behaviour of"all"
.
If
k
exceeds the agent’s number of neighbours, all are used.
group-impact-alpha
Controls how the level of consensus influences adoption:
[ f(g) = g^{\alpha} ]
| Symbol | Definition | Role |
|--------|------------|------|
| g
| Fraction of neighbours aligned with the influencer’s sign. | Measures consensus strength. |
| α
| Non-linearity (group-impact-alpha
): 1
= linear, <1
= concave (minorities matter), >1
= convex (requires strong majority). | Shapes the weight of consensus. |
| f(g)
| Group impact factor applied to the base probability. | |
Combined scaling
[ P' = P \times \big[(1 - w) + w \times (g^{\alpha})\big] ]
| Symbol | Meaning |
|--------|---------|
| P
= base adoption probability (prevalence gap, distance, influence). |
| w
= group-impact-weight
, how much group effect matters. |
| g
= alignment fraction. |
| α
= non-linearity parameter. |
| P'
= final probability after group effect. |
💡 Small α
gives power to small aligned minorities; large α
means only strong consensus affects adoption.
Additional parameters: prevalence-weight
, adoption-floor
, bridge-prob
prevalence-weight
Sets how strongly the prevalence gap boosts adoption chances.
- Low (0–0.3): prevalence barely matters.
- Medium (0.4–0.6): balanced.
- High (0.7–1.0): large prevalence advantage can overcome sign difference.
adoption-floor
Guarantees a minimum probability of adoption, preventing deadlocks in highly segregated networks.
bridge-prob
Adds random bridges between agents of opposite signs, bypassing the formation threshold.
| Slider | Role | Effect on links | Effect on inversions |
|--------|------|-----------------|----------------------|
| prevalence-weight
| Strength of prevalence advantage | — | Higher chance of adoption when neighbour’s prevalence is high |
| adoption-floor
| Minimum adoption probability | — | Keeps change possible across camps |
| bridge-prob
| Cross-camp link probability | Creates “bridges” | Increases exposure to opposite signs |
USER INTERFACE CONTROLS
General commands
- Setup, Go
- in_file, auto_event
refresh
,cumulative
Population & iterations
pop
, nb_try
, max_iter
, threshold
, tick-event
External events
event
, On_to_left
, meme_set
, event_size
, prev_change
Meta-influencers
meta-influencers
, meta-influencers-selection
, meta-links
, meta-min
, meta-max
, prev-low
, prev-high
, vary-influence
, meta-ok
Opinion & prevalence
rate-infl
, modulation-prevalence
, rate-modulation
, noise
, polarization-factor
Social network
prob
, linksdown
, linksup
, link-removal-threshold
, link-formation-threshold
Group impact
group-impact-weight
, group-impact-alpha
, group-k
, group-impact-mode
Advanced sliders
prevalence-weight
, adoption-floor
, bridge-prob
Links & display
show-links?
, linktick
— link thickness
Colours: green (same sign), gray (opposite).
Monitors & graph
Track proportions, medians (opinion, prevalence, influence), inversions, fractal dimension, and link stats.
THINGS TO NOTICE
- Observe how opinions converge or polarize depending on prevalence, influence, and network structure.
- Meta-influencers grow or lose power based on persuasion success when
vary-influence
is enabled. - Bridges and adoption-floor help avoid stagnation, while prevalence-weight controls how strongly salience tips adoption.
- Link colours: green = homophily, gray = cross-camp ties.
NETLOGO FEATURES
- 3D visualization of agents and links.
- Export results via file or CSV.
CREDITS AND REFERENCES
- Original concept: Public Opinion Research Group
- NetLogo implementation & enhancements: Pierre-Alain Cotnoir (2023–2025)
- AI-assisted design: GPT-4 & GPT-5
- Email: pacotnoir@gmail.com
Comments and Questions
extensions [sound nw] ;; For using sound and Network package globals [ min-prevalence max-prevalence meta-influencers-droit meta-influencers-gauche iter change total inversion try major fractale ordonnee abcisse profondeur list_data file-in in_data repet_data links-dead links-create meta-agents meta-links meta-create ;; === CSV export === csv-export ;; bool: activer/désactiver l’export CSV par essai (widget UI: switch) csv-basename ;; string: préfixe fichier CSV (widget UI: input), ex: "run" csv-file ;; nom du fichier CSV de l’essai courant csv-open? ;; bool: fichier CSV ouvert ? ;; === Paramètres d’inversion / ponts (peuvent être des sliders UI) === ;prevalence-weight ;; >= 0 ; amplification du rôle de Δprégnance ;;adoption-floor ;; [0..1] ; plancher minimal pour la pénalité de polarisation ;;bridge-prob ;; [0..1] ; probabilité de créer un lien-pont (opinion éloignée) ] turtles-own [ opinion ;; [-1, 1] prevalence ;; [min-prevalence, max-prevalence] agent-type ;; "Right side" | "Left side" influence ;; [0, 1] opinion-previous influence-previous ;; Coordonnées 3D propres à chaque agent x3d y3d z3d ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SETUP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup clear-all set repet_data false set iter 0 set min-prevalence 0 set max-prevalence 99 set-default-shape turtles "person" set try 1 set major 0 set links-dead 0 set links-create 0 set meta-create 0 set meta-agents 0 set change 0 set total 0 set inversion 0 set fractale 0 if vary-influence = true [ set meta-links meta-min ] ;; === Defaults CSV si widgets pas encore ajoutés === if not is-boolean? csv-export [ set csv-export false ] if (not is-string? csv-basename) or (csv-basename = "") [ set csv-basename "run" ] set csv-open? false ;; === Defaults IMPACT DE GROUPE (si widgets absents) === if (not is-string? group-impact-mode) [ set group-impact-mode "all" ] ;; "all" | "k-nearest" if (not is-number? group-k) [ set group-k 10 ] if (not is-number? group-impact-weight) [ set group-impact-weight 0.5 ] ;; 0..1 if (not is-number? group-impact-alpha) [ set group-impact-alpha 1.0 ] ;; >=0.1 ;; === Default show-links? si widget absent === if not is-boolean? show-links? [ set show-links? false ] ;; === Defaults inversions/ponts (si pas de sliders) === if (not is-number? prevalence-weight) [ set prevalence-weight 1.5 ] ;; amplification Δprégnance if (not is-number? adoption-floor) [ set adoption-floor 0.02 ] ;; plancher pénalité polarisation if (not is-number? bridge-prob) [ set bridge-prob 0.10 ] ;; probabilité de créer un "pont" set-background-black create rapport end to create ;; Créer les agents Right side create-turtles pop / 2 [ set agent-type "Right side" set opinion random-float 1 ;; (0,1) set color blue set prevalence random-float (opinion * 100) set influence random-float 1 set opinion-previous opinion set influence-previous influence update-3d self ] ;; Créer les agents Left side create-turtles pop / 2 [ set agent-type "Left side" set opinion (random-float 1 - 1) ;; (-1,0) set color red set prevalence random-float (abs opinion * 100) set influence random-float 1 set opinion-previous opinion set influence-previous influence update-3d self ] ;; Création des méta-influenceurs (selon vos réglages UI) influenceurs reset-ticks ;; Initialisation réseau via vos règles (créera des liens si conditions réunies) set total 0 set change 0 update-networks ;; Colorer/afficher les liens dès l’initialisation recolor-links apply-link-visibility end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SORTIES / RAPPORT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to rapport ;; titles for Statistics or Values inside compute-statistics if output = "Statistics" [ output-print (word "Try ; " "Iter ; " "Opinion global ; " "Opinion right side ; " "Opinion left side ; " "Prevalence right side ; " "Prevalence left side ; " "Influence right side ; " "Influence left side ; " "Left % ; " "Right % ; " "Links-Remove ; " "Links-Create ; " "Inversion % ; " "change ; " "total ; " "fractale") ] if output = "Values" [ output-print (word "Try ; " "Ticks ; " "Agents ; " "Prevalence ; " "Opinion ; " "Influence ; " "meme droit") ] if output = "File" [ ask turtles [ let pre prevalence let mem opinion let infl influence let ti ticks output-print (word ti " " pre " " mem " " infl) ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; META-INFLUENCEURS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to influenceurs ;; All if meta-influencers-selection = "All" [ let k round (count turtles * meta-influencers / 100) if k > 0 [ ask n-of k turtles [ if (prevalence >= prev-low and prevalence <= prev-high) [ set influence 1 set color yellow set meta-agents meta-agents + 1 ] ] ] ] ;; Right side if meta-influencers-selection = "Right side" [ set meta-influencers-droit round (count turtles * meta-influencers / 100) let candidates turtles with [opinion > 0] let k min list meta-influencers-droit count candidates if k > 0 [ ask n-of k candidates [ if (prevalence > prev-low and prevalence <= prev-high) [ set influence 1 set color yellow set meta-agents meta-agents + 1 ] ] ] ] ;; Left side if meta-influencers-selection = "Left side" [ set meta-influencers-gauche round (count turtles * meta-influencers / 100) let candidates turtles with [opinion < 0] let k min list meta-influencers-gauche count candidates if k > 0 [ ask n-of k candidates [ if (prevalence > prev-low and prevalence <= prev-high) [ set influence 1 set color yellow set meta-agents meta-agents + 1 ] ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; BOUCLE PRINCIPALE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go ifelse (iter < max_iter) [ set iter iter + 1 set meta-create 0 ;; plafond de création de liens autour des méta-influenceurs par tick ;; Ouvrir le CSV au premier tick de l’essai if (iter = 1 and csv-export and not csv-open?) [ csv-begin ] if auto_event = true [ if (tick-event = iter) [ event ] ] if meta-ok = true [ meta ] update-opinions if network = true [ update-networks ] recolor-links apply-link-visibility ;; montrer/cacher les liens selon show-links? if output = "Statistics" [ let avg-opinion mean [opinion] of turtles let positive-opinion safe-median (turtles with [opinion >= 0]) "opinion" let negative-opinion safe-median (turtles with [opinion < 0]) "opinion" let positive-prevalence (safe-median (turtles with [opinion >= 0]) "prevalence") / 100 let negative-prevalence (safe-median (turtles with [opinion < 0]) "prevalence") / 100 let positive-influence safe-median (turtles with [opinion >= 0]) "influence" let negative-influence safe-median (turtles with [opinion < 0]) "influence" let Left% (count turtles with [opinion < 0]) / (pop / 100) let Right% (count turtles with [opinion >= 0]) / (pop / 100) let ti iter output-print (word try " ; " ti " ; " avg-opinion " ; " positive-opinion " ; " negative-opinion " ; " positive-prevalence " ; " negative-prevalence " ; " positive-influence " ; " negative-influence " ; " Left% " ; " Right% " ; " links-dead " ; " links-Create " ; " inversion " ; " change " ; " total " ; " fractale) ] tick ;; “Fractale” via changement de base sûr if (change > 1 and total > 1) [ set fractale (ln total) / (ln change) ] if (cumulative = false) [ set change 0 set total 0 ] colorer ;; rafraîchir le graphique if (refresh = true) [ if ticks > 200 [ reset-ticks clear-plot ] ] if threshold <= (count turtles with [opinion > 0]) / (pop / 100) [ set major major + 1 ] ;; Écrire une ligne CSV par tick if csv-export [ csv-row ] ] [ ifelse (try < nb_try) [ ;; Fin d’essai: fermer le CSV de l’essai courant if csv-export [ csv-end ] ;; réinitialisation pour l’essai suivant set try try + 1 set major 0 clear-turtles clear-plot set change 0 set total 0 set fractale 0 set meta-links meta-min set iter 0 set links-create 0 set links-dead 0 set meta-create 0 set meta-agents 0 set min-prevalence 0 set max-prevalence 99 ifelse (repet_data = true) [ data ] [ create set meta-links meta-min ;;set meta-agents 0 ] ] [ ;; Fin de toutes les répétitions: fermer CSV si encore ouvert if csv-export [ csv-end ] sound:play-note "Tubular Bells" 60 64 1 stop ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MISE À JOUR DES OPINIONS (intègre l'effet de groupe + correctifs) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-opinions ask turtles [ set opinion-previous opinion let target one-of link-neighbors if target != nobody [ ;; différence de prégnance, avec petite tolérance let raw-dprev ([prevalence] of target) - prevalence if raw-dprev < 1 [ set raw-dprev 0 ] let dprev raw-dprev / max-prevalence ;; ~ [0,1] if dprev > 0 [ ;; distance sur le signe absolu (favorise des inversions quand Δprégnance est fort) let dmem abs(abs(opinion) - abs([opinion] of target)) ;; base-prob amplifiée par prevalence-weight (PAS de seconde division) let base-prob dprev * prevalence-weight ;; pénalité de polarisation bornée par adoption-floor let pol-penalty max list adoption-floor (1 - polarization-factor * dmem) ;; influence du voisin let p-adopt base-prob * pol-penalty * [influence] of target ;; effet de groupe (voisins du RECEVEUR alignés avec le SIGNE de l'émetteur) let sgn-emetteur sign ([opinion] of target) let gprob group-alignment-effective self sgn-emetteur let w group-impact-weight let alpha group-impact-alpha set p-adopt p-adopt * ((1 - w) + (w * (gprob ^ alpha))) ;; garde-fous if p-adopt < 0 [ set p-adopt 0 ] if p-adopt > 1 [ set p-adopt 1 ] ;; tirage d'adoption if random-float 1 < p-adopt [ let old-opinion opinion set opinion [opinion] of target set total total + 1 ;; dynamique d'influence set influence-previous influence if vary-influence = true [ if abs(old-opinion) > abs(opinion) [ set influence min (list 1 (influence + rate-infl)) if (influence-previous < 1 and influence = 1) [ if meta-ok = true [ if meta-links < meta-max [ set meta-links meta-links + 1 ] set meta-agents meta-agents + 1 ] set color yellow ] ] if abs(old-opinion) < abs(opinion) [ set influence max (list 0 (influence - rate-infl)) if (influence < influence-previous and influence-previous = 1) [ if meta-ok = true [ set meta-agents meta-agents - 1 ifelse opinion >= 0 [ set color blue ] [ set color red ] ] ] ] ] ;; comptage des inversions (changement de signe) if (sign old-opinion) != (sign opinion) [ set change change + 1 ] ] ] ] ;; modulation de la prévalence if modulation-prevalence = true [ if prevalence > abs opinion * 100 [ set prevalence prevalence - abs(opinion - opinion-previous) * influence * Rate-modulation ] if prevalence < abs opinion * 100 [ set prevalence prevalence + abs(opinion - opinion-previous) * influence * Rate-modulation ] if prevalence < min-prevalence [ set prevalence min-prevalence ] if prevalence > max-prevalence [ set prevalence max-prevalence ] ] ;; bruit additif if random-float 1 < noise [ set opinion opinion + (random-float 0.4 - 0.2) if opinion > 1 [ set opinion 1 ] if opinion < -1 [ set opinion -1 ] ] ;; mise à jour position 3D update-3d self ;; logging fin de boucle agent if (output = "Values" or output = "File") [ compute-statistics ] ] ;; inversion % (après la boucle) ifelse (total > 0) [ set inversion (100 * change / total) ] [ set inversion 0 ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; COLORATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to colorer ask turtles [ if color != yellow [ ifelse opinion >= 0 [ set color blue ] [ set color red ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MISE À JOUR DU RÉSEAU (robuste + ponts + coloration + switch show-links?) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-networks ;; suppression de liens let doomed links with [ abs([opinion] of end1 - [opinion] of end2) > (link-removal-threshold / 100) ] let doomedProb doomed with [ random-float 1 < prob ] let n-remove min (list linksdown count doomedProb) if n-remove > 0 [ ask n-of n-remove doomedProb [ die ] set links-dead links-dead + n-remove ] ;; formation de liens let j linksup while [j > 0] [ let t one-of turtles if t = nobody [ stop ] ask t [ let myop opinion let candidates other turtles with [ not link-neighbor? myself ] let pool-homo candidates with [ abs(opinion - myop) < (link-formation-threshold / 100) ] let pool-bridge candidates with [ (sign opinion) != (sign myop) ] let friend nobody if any? pool-bridge and (random-float 1 < bridge-prob) [ set friend max-one-of pool-bridge [ abs(opinion - myop) ] ] if (friend = nobody) and any? pool-homo [ set friend min-one-of pool-homo [ abs(opinion - myop) ] ] if friend != nobody and (random-float 1 < prob) [ create-link-with friend set links-create links-create + 1 let same-sign? (sign opinion) = (sign [opinion] of friend) ask link-with friend [ set color (ifelse-value same-sign? [ green ] [ gray ]) set thickness linktick if show-links? [ show-link ] ] ] ] set j j - 1 ] end to meta ;; 1) On n'agit pas si le réseau est gelé if not network [ stop ] ;; 2) Pour chaque agent, tenter un lien vers un méta ask turtles [ ;; candidats = méta-influenceurs (jaunes) non encore liés à moi, ;; et qui n'ont pas dépassé leur plafond individuel de liens (meta-links) let pool other turtles with [ color = yellow and not link-neighbor? myself and (count link-neighbors) < meta-links ] if any? pool [ let friend one-of pool create-link-with friend ;; couleur/épaisseur cohérentes let same-sign? (sign opinion) = (sign [opinion] of friend) ask link-with friend [ set color (ifelse-value same-sign? [ green ] [ gray ]) set thickness linktick if show-links? [ show-link ] ] ] ] end ;; Applique la visibilité globale des liens selon le switch show-links? to apply-link-visibility ifelse show-links? [ ask links [ show-link ] ] [ ask links [ hide-link ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; STATISTIQUES RUNTIMES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to compute-statistics if output = "Values" [ let pre prevalence let mem opinion let infl influence let ag who let ti ticks let ess try let memed (count turtles with [opinion > 0]) / (pop / 100) let maj major output-print (word ess " ; " ti " ; " ag " ; " pre " ; " mem " ; " infl " ; " memed) ] if output = "File" [ let pre prevalence let mem opinion let infl influence let ti ticks output-print (word ti " " pre " " mem " " infl) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; I/O : LECTURE FICHIER D’AGENTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to in_file ;; File d'entrée carefully [ set file-in user-file if (file-in != false) [ set list_data [] file-open file-in while [not file-at-end?] [ set list_data sentence list_data (list (list file-read file-read file-read file-read)) ] file-close user-message "File uploaded!" set in_data true ] ] [ user-message "File read error" ] data end to data clear-turtles clear-links let tick_to_load choice_iter ifelse (is-list? list_data) [ let filtered_data filter [ row -> first row = tick_to_load ] list_data create-turtles length filtered_data [ let my_index who let agent_data item my_index filtered_data set prevalence item 1 agent_data set opinion item 2 agent_data set influence item 3 agent_data if influence = 1 [set meta-agents meta-agents + influence] set opinion-previous opinion set influence-previous influence if opinion < 0 [ set color red set agent-type "Left side" ] if opinion > 0 [ set color blue set agent-type "Right side" ] if influence = 1 [ set color yellow ] ;; Position initiale (2D/3D) update-3d self ] ] [ set in_data false user-message "Read error" ] ;; créer des liens selon vos règles update-networks apply-link-visibility recolor-links influenceurs update-opinions set repet_data true end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ÉVÉNEMENT EXTERNE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to event ;; moving agents to the right or left side by increasing or decreasing the prevalence ask turtles [ ifelse meme_set = true [ if (to_left = false) [ if agent-type = "Right side" [ if opinion < 0 [ set opinion opinion + event_size if opinion > 1 [ set opinion 1 ] ] ] ] if (to_left = true) [ if agent-type = "Left side" [ if opinion > 0 [ set opinion opinion - event_size if opinion < -1 [ set opinion -1 ] ] ] ] ] [ if (to_left = false) [ if (opinion < high_meme and opinion > low_meme and prevalence < high-prev and prevalence > low-prev) [ set opinion opinion + event_size if (prev_change != 0) [ set prevalence prevalence + prev_change ] if opinion > 1 [ set opinion 1 ] ] ] if (to_left = true) [ if (opinion > low_meme and opinion < high_meme and prevalence > low-prev and prevalence < high-prev) [ set opinion opinion - event_size if (prev_change != 0) [ set prevalence prevalence + prev_change ] if opinion < -1 [ set opinion -1 ] ] ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; UTILITAIRES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to set-background-black ask patches [ set pcolor black ] end to update-3d [agt] ask agt [ set x3d opinion * 16 set y3d prevalence / 6 set z3d influence * 16 setxyz x3d y3d z3d ] end to-report safe-median [agentset varname] if not any? agentset [ report 0 ] report median [ runresult varname ] of agentset end to-report sign [x] ifelse x > 0 [ report 1 ] [ ifelse x < 0 [ report -1 ] [ report 0 ] ] end to recolor-links ask links [ let s1 sign [opinion] of end1 let s2 sign [opinion] of end2 ifelse s1 = s2 [ set color green ] [ set color gray ] set thickness linktick ] end ;; --------------------------------------------------------------------------- ;; IMPACT DE GROUPE (tous les voisins liés) ;; Retourne la proportion de voisins liés dont le signe d'opinion = sign-ref. ;; Si aucun voisin lié : retourne 0.5 (neutre). ;; --------------------------------------------------------------------------- to-report group-alignment-all [agt sign-ref] let nbrs [link-neighbors] of agt if not any? nbrs [ report 0.5 ] let same count nbrs with [ (sign opinion) = sign-ref ] report same / count nbrs end ;; --------------------------------------------------------------------------- ;; IMPACT DE GROUPE (k plus proches en opinion) ;; Choisit les k voisins liés les plus proches en opinion de agt, ;; puis renvoie la même proportion (même signe = sign-ref). ;; Si aucun voisin lié : 0.5 (neutre). ;; --------------------------------------------------------------------------- to-report group-alignment-k [agt sign-ref k] let nbrs [link-neighbors] of agt let deg count nbrs if deg = 0 [ report 0.5 ] let kk max list 1 min list deg floor k let agop [opinion] of agt let pool min-n-of kk nbrs [ abs(opinion - agop) ] if not any? pool [ report 0.5 ] let same count pool with [ (sign opinion) = sign-ref ] report same / count pool end ;; --------------------------------------------------------------------------- ;; IMPACT DE GROUPE EFFECTIF selon le mode sélectionné ("all" | "k-nearest") ;; --------------------------------------------------------------------------- to-report group-alignment-effective [agt sign-ref] ifelse (group-impact-mode = "k-nearest") [ report group-alignment-k agt sign-ref group-k ] [ report group-alignment-all agt sign-ref ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; EXPORT CSV (par essai) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to csv-begin if not csv-export [ stop ] set csv-file (word csv-basename "-" try ".csv") file-close-all if file-exists? csv-file [ file-delete csv-file ] file-open csv-file set csv-open? true ;; En-tête standardisé file-print "try,iter,tick,left_pct,right_pct,avg_opinion,med_op_right,med_op_left,med_prev_right,med_prev_left,med_infl_right,med_infl_left,links_remove,links_create,inversion_pct,change,total,fractale,major" end to csv-row if not csv-open? [ stop ] let avg-opinion mean [opinion] of turtles let opR safe-median (turtles with [opinion >= 0]) "opinion" let opL safe-median (turtles with [opinion < 0]) "opinion" let prevR (safe-median (turtles with [opinion >= 0]) "prevalence") / 100 let prevL (safe-median (turtles with [opinion < 0]) "prevalence") / 100 let inflR safe-median (turtles with [opinion >= 0]) "influence" let inflL safe-median (turtles with [opinion < 0]) "influence" let leftpct (count turtles with [opinion < 0]) / (pop / 100) let rightpct (count turtles with [opinion >= 0]) / (pop / 100) file-print (word try "," iter "," ticks "," leftpct "," rightpct "," avg-opinion "," opR "," opL "," prevR "," prevL "," inflR "," inflL "," links-dead "," links-create "," inversion "," change "," total "," fractale "," major) end to csv-end if csv-open? [ file-close set csv-open? false ] end
There are 6 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Version_20250913-1_Spread of Opinions Influenced by Group Effects.png | preview | Preview for 'Version_20250913-1_Spread of Opinions Influenced by Group Effects' | about 15 hours ago, by Pierre-Alain Cotnoir | Download |
This model does not have any ancestors.
This model does not have any descendants.