Version_20251017-1_Simulator v5_EN
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This simulator models how opinions spread and evolve in a connected population (multi-agent system). Each agent has an opinion (−1 to +1), a prevalence (0–99), an influence (0–1), and social links. The model tracks the co-evolution of opinions, prevalence (depth of internal representations), influence, and the network structure.
3D Representation
- X: opinion (−1 left, +1 right)
- Y: prevalence (0–99)
- Z: influence (0–1) Colors: blue (right), red (left), yellow (meta-influencer). Links: green (same sign), gray (opposite signs).
HOW TO USE
- Choose the population size with
pop
. - Click Setup (creates agents, black background, initializes
tick-event
toevent-init
). - Click Go to run/pause.
GENERAL CONTROLS
- Setup: initialize agents/network; sets
tick-event ← event-init
. - Go: start/stop the simulation.
- in_file: load agent states from a file (for
data
). - refresh: resets plots after ~200 ticks.
- cumulative: if OFF, resets
change
/total
every tick. - output: None | Statistics | Values | File.
POPULATION & ITERATIONS
pop
: number of agents (e.g., 100–5000).nb_try
,max_iter
,threshold
: repetitions, trial length, majority threshold.choice_iter
: iteration to replay when loading from file.
SOCIAL NETWORK (link dynamics)
link-removal-threshold
: opinion distance (in %) above which a link may be cut.link-formation-threshold
: maximum distance to allow a new link.prob
: probability applied to deletions/formations.linksdown
/linksup
: caps on links removed/created per tick.bridge-prob
: chance to create bridges across opposing camps.show-links?
: toggle link visibility;linktick
: visual thickness.
META-INFLUENCERS
Agents with fixed high influence (influence = 1).
meta-influencers-selection
: All / Right side / Left side.meta-influencers
: share of agents promoted to “meta”.prev-low
/prev-high
: prevalence eligibility bounds.meta-min
/meta-max
/meta-links
: min/max and current quota of meta links.meta-ok
: enables dynamic meta linking even ifvary-influence
= OFF.vary-influence
: if ON, influence increases after successes and decreases after setbacks.metablock
: if ON, metas cannot flip sign (veto on polarity changes).
At initialization (
setup
) and at the start of each new trial, the model setsmeta-links ← meta-min
ifvary-influence
= true ormeta-ok
= true (as in your code).
OPINION & PREVALENCE DYNAMICS
rate-infl
: speed of influence updates after adoption.noise
: probability of additive opinion noise.polarization-factor
: penalizes adoption across large opinion gaps.prevalence-weight
: weight of prevalence differences in adoption.adoption-floor
: minimum adoption probability (avoids strict zero).
Prevalence modulation (renamed in code)
mod-prev
(formerlymodulation-prevalence
): ON to adapt prevalence to current vs previous opinion.Rate-mod
(formerlyrate-modulation
): adjustment intensity.
GROUP EFFECT
group-impact-mode
: all (all linked neighbors) or k-nearest.group-k
: number of neighbors in k-nearest mode.group-impact-weight
: weight of neighborhood alignment in adoption.group-impact-alpha
: non-linearity<1
: small aligned clusters matter more,=1
: linear,>1
: only large aligned majorities matter.
REWARD MECHANISM
A successful emitter (who convinces a neighbor) receives a temporary bonus (tx-bonus
) that boosts future persuasion.
reward-step
: bonus increment per success.reward-cap
: cap on cumulative bonus.reward-scope
: both / left-only / right-only.reward-prev-delta
: increase in the target’s prevalence after adoption (optional).reward-decay
: bonus decay over ticks.
MEME-BASED REPRESENTATION (optional)
If use-memes?
= ON, opinion and prevalence derive from two stocks: meme-plus
(pro) and meme-minus
(anti).
meme-max
: soft cap for stocks.meme-gain
: increase upon received influence.meme-anti-leak
: cross-erosion (reduces the opposite stock).meme-decay
: forgetting rate. The model recalculates opinion (pro vs anti balance) and prevalence (total memes), under themetablock
veto.
EXOGENOUS EVENTS (bounded & probabilistic)
Targeting
meme_set
+to_left
: if ON, structural targeting by camp (Left side / Right side).- Otherwise, use bounds:
low_meme
/high_meme
(opinion window) andlow-prev
/high-prev
(prevalence window).
Effects on targeted agents
event_size
: opinion shift (toward the intended camp).prev_change
: prevalence change (clamped to [0,99]).event-prob-max
(0–1): maximum share of targeted agents that actually receive the shock (each agent drawsU(0,1)
).
Triggering
event
button: one-shot shock (manual).auto_event
+tick-event
: scheduled automatic shock at iterationtick-event
.
Repeated events (per your code)
event-init
: initial offset of the first event (onsetup
and at each new trial,tick-event ← event-init
).repeat-event
(switch): if ON, re-schedules the next event after each occurrence.event-pace
(≥ 1 tick recommended): spacing between repeated events.Scheduling logic:
- If
auto_event
= ON anditer = tick-event
→ runevent
. - If
repeat-event
= ON →tick-event ← tick-event + event-pace
. - Else (OFF) → no automatic re-scheduling (you may adjust
tick-event
manually). - If
auto_event
= OFF → each tick,tick-event ← iter + event-pace
(the next time you switch ON, the event fires ≈event-pace
ticks later).
- If
Quick examples
- Single calibration shock:
auto_event=ON
,repeat-event=OFF
,event-init=2
,event-prob-max=1.0
. - Periodic pulses:
auto_event=ON
,repeat-event=ON
,event-init=50
,event-pace=50
,event-prob-max=0.30
. - Diffuse perturbations:
repeat-event=ON
,event-pace=100
,event-prob-max=0.05
.
OUTPUTS / MONITORS / CSV
- Monitors: % left/right, medians (opinion/prevalence/influence), inversions, interactions, fractal dimension, links created/removed.
- Graph: time trajectories of key variables.
- CSV: if
csv-export
= ON, per-trial export with a standard header (basename-try.csv
).
THINGS TO WATCH
- Polarization, convergence, fragmentation.
- Roles of meta-influencers (and
metablock
), group effect, and reward. - Impact of memes (memory, cross-leak, decay).
- How repeated events and
event-prob-max
shape the global dynamics.
QUICK CHEAT SHEET — TYPICAL VALUES
| Parameter | Useful range | Tendency |
| ----------------------- | ------------ | ----------------------------------------------------------- |
| prevalence-weight
| 0–2 | ↑ makes prevalence gaps dominate adoption |
| adoption-floor
| 0–0.1 | ↑ allows more “noisy” cross-camp adoptions |
| bridge-prob
| 0–0.3 | ↑ creates more cross-camp bridges & inversions |
| group-impact-weight
| 0–1 | ↑ strengthens neighborhood alignment effect |
| group-impact-alpha
| 0.2–3 | <1 favors small aligned clusters; >1 needs large majorities |
| reward-step
| 0.01–0.1 | ↑ faster reinforcement of persuasive agents |
| reward-decay
| 0–0.05 | ↑ bonus fades faster |
| meme-anti-leak
| 0–0.5 | ↑ growth erodes the opposite stock more |
| event-prob-max
| 0–1 | ↑ more “massive” shocks per occurrence |
| event-pace
| ≥1 | ↓ means more frequent events (if repetition ON) |
| mod-prev
& Rate-mod
| — | adapt prevalence to opinion changes |
CREDITS
- Original concept: Public Opinion Research Group
- NetLogo implementation & enhancements: Pierre-Alain Cotnoir (2015–2025)
- AI-assisted design: GPT-4 & GPT-5 (2024–2025)
- Contact: 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 Interactions %Major ;; === CSV export === csv-export csv-basename csv-file csv-open? ;; === Paramètres d’inversion / ponts (sliders UI possibles) === ;;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) ;; === Paramètres de RÉCOMPENSE (sliders/inputs UI) === ;;reward-step ;; palier d’augmentation du bonus à chaque succès (ex: 0.05) ;;reward-cap ;; plafond du bonus cumulé (ex: 0.50) ;;reward-scope ;; "both" | "left-only" | "right-only" ;;reward-prev-delta ;; hausse de prégnance du ciblé au succès (ex: 0..5), 0 = off ;;reward-decay ;; décroissance du bonus par tick (ex: 0..0.01), 0 = off ] turtles-own [ opinion ;; [-1, 1] prevalence ;; [min-prevalence, max-prevalence] agent-type ;; "Right side" | "Left side" influence ;; [0, 1] opinion-previous influence-previous x3d y3d z3d ;; Mèmes (stock pro/anti) meme-plus meme-minus ;; variables utilitaires old-opinion proposed-opinion ;; Récompense de transmission (bonus multiplicatif p-adopt côté émetteur) tx-bonus ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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 tick-event event-init 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 or meta-ok = true [ set meta-links meta-min ] ;; === Defaults CSV === 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 === 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 ] if (not is-number? group-impact-alpha) [ set group-impact-alpha 1.0 ] ;; === Default switches === if not is-boolean? show-links? [ set show-links? false ] if not is-boolean? metablock [ set metablock false ] ;; === Defaults inversion/ponts === if (not is-number? prevalence-weight) [ set prevalence-weight 1.5 ] if (not is-number? adoption-floor) [ set adoption-floor 0.02 ] if (not is-number? bridge-prob) [ set bridge-prob 0.10 ] ;; === Defaults REWARD === if not is-number? reward-step [ set reward-step 0.05 ] if not is-number? reward-cap [ set reward-cap 0.50 ] if not is-string? reward-scope [ set reward-scope "both" ] if not is-number? reward-prev-delta [ set reward-prev-delta 0 ] if not is-number? reward-decay [ set reward-decay 0 ] ;; === Defaults MEMES === if not is-boolean? use-memes? [ set use-memes? false ] if not is-number? meme-max [ set meme-max 100 ] if not is-number? meme-gain [ set meme-gain 1.0 ] if not is-number? meme-anti-leak [ set meme-anti-leak 0.0 ] if not is-number? meme-decay [ set meme-decay 0.0 ] set-background-black create rapport end to create ;; 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 set tx-bonus 0 ;; init mèmes cohérente avec (prevalence, opinion) let tot initial-prevalence-to-memes prevalence ifelse opinion >= 0 [ set meme-plus tot * (0.5 + 0.5 * abs opinion) set meme-minus tot - meme-plus ] [ set meme-minus tot * (0.5 + 0.5 * abs opinion) set meme-plus tot - meme-minus ] update-3d self ] ;; 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 set tx-bonus 0 ;; init mèmes cohérente avec (prevalence, opinion) let tot initial-prevalence-to-memes prevalence ifelse opinion >= 0 [ set meme-plus tot * (0.5 + 0.5 * abs opinion) set meme-minus tot - meme-plus ] [ set meme-minus tot * (0.5 + 0.5 * abs opinion) set meme-plus tot - meme-minus ] update-3d self ] ;; Méta-influenceurs initiaux influenceurs reset-ticks set total 0 set change 0 set Interactions 0 set %Major 0 update-networks recolor-links apply-link-visibility end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SORTIES / RAPPORT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to rapport 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 ;" "meme plus ; " "meme minus") ] if output = "File" [ ; ask turtles [ ; let pre prevalence ;let mem opinion ; let infl influence ; let ti ticks output-print (word "ti ; " "pre ;" "mem ; " "infl ; " "agent") ; ] ] 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; OUTILS MÉTA / VETO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Un agent est "méta" s'il est jaune OU si son influence vaut 1 to-report meta? report (color = yellow) or (influence = 1) end ;; Change l'opinion en respectant le veto méta quand metablock = true. ;; Solution 1 (renforcement sans inversion) : ;; - si la nouvelle opinion change le signe d’un méta alors que metablock=ON, ;; on conserve le signe ACTUEL et on prend la magnitude MAX(abs(old), abs(new)). to maybe-set-opinion [ new-op ] let old-op opinion let bounded-op max list -1 min list 1 new-op if metablock and meta? and (sign old-op != sign bounded-op) [ let mag max list (abs old-op) (abs bounded-op) set opinion (sign old-op) * mag stop ] set opinion bounded-op end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; BOUCLE PRINCIPALE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go ifelse (iter < max_iter) [ if iter > 0 [ set Interactions (total / iter) ] if iter > 0 [ set %Major (major / iter * 100) ] set iter iter + 1 set meta-create 0 if (iter = 1 and csv-export and not csv-open?) [ csv-begin ] ifelse auto_event = true [ if (tick-event = iter) [event if repeat-event [set tick-event (tick-event + event-pace)]] ] [set tick-event (iter + event-pace)] if meta-ok = true [ meta ] update-opinions if network = true [ update-networks ] recolor-links apply-link-visibility 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 if (change > 1 and total > 1) [ set fractale (ln total) / (ln change) ] if (cumulative = false) [ set change 0 set total 0 ] colorer if (refresh = true) [ if ticks > 200 [ reset-ticks clear-plot ] ] if threshold <= (count turtles with [opinion > 0]) / (pop / 100) [ set major major + 1 ] if csv-export [ csv-row ] ] [ ifelse (try < nb_try) [ if csv-export [ csv-end ] 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 tick-event event-init 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 ] ] [ if csv-export [ csv-end ] sound:play-note "Tubular Bells" 60 64 1 stop ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MISE À JOUR DES OPINIONS (effet de groupe + récompenses + mèmes + veto méta) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-opinions ask turtles [ set opinion-previous opinion let target one-of link-neighbors if target != nobody [ ;; Δprégnance (tolérance 1) let raw-dprev ([prevalence] of target) - prevalence if raw-dprev < 1 [ set raw-dprev 0 ] let dprev raw-dprev / max-prevalence if dprev > 0 [ ;; distance mémique en valeur absolue des signes let dmem abs(abs(opinion) - abs([opinion] of target)) ;; base-prob + pénalité de polarisation let base-prob dprev * prevalence-weight let pol-penalty max list adoption-floor (1 - polarization-factor * dmem) ;; probabilité brute (sans groupe), pondérée par influence & tx-bonus de l’émetteur let p-adopt base-prob * pol-penalty * [influence] of target * (1 + [tx-bonus] of target) ;; effet de groupe 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))) ;; borne [0,1] if p-adopt < 0 [ set p-adopt 0 ] if p-adopt > 1 [ set p-adopt 1 ] ;; tirage if random-float 1 < p-adopt [ set old-opinion opinion set proposed-opinion [opinion] of target ifelse use-memes? [ ;; renforcement des mèmes du receveur selon le signe de l’émetteur transmit-memes target ;; opinion & prevalence dérivées des mèmes (protégées par metablock) recompute-from-memes ] [ ;; adoption « historique » protégée par veto maybe-set-opinion proposed-opinion ] ;; si veto/reflexion n’a pas modifié le signe et que rien n’a changé → pas de reward if opinion = old-opinion [ stop ] ;; succès de transmission set total total + 1 ;; récompense à l’émetteur si éligible let emitter-sign sign ([opinion] of target) let eligible? (reward-scope = "both") or (reward-scope = "left-only" and emitter-sign < 0) or (reward-scope = "right-only" and emitter-sign >= 0) if eligible? [ ask target [ set tx-bonus min (list reward-cap (tx-bonus + reward-step)) ] ] ;; option : hausse de prégnance du ciblé if reward-prev-delta > 0 [ set prevalence min (list max-prevalence (prevalence + reward-prev-delta)) ] ;; dynamique d’influence (logique existante) 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 (si non bloquée par veto/réflexion) if (sign old-opinion) != (sign opinion) [ set change change + 1 ] ] ] ] ;; modulation de la prévalence if mod-prev = true [ if prevalence > abs opinion * 100 [ set prevalence prevalence - abs(opinion - opinion-previous) * influence * Rate-mod ] if prevalence < abs opinion * 100 [ set prevalence prevalence + abs(opinion - opinion-previous) * influence * Rate-mod ] if prevalence < min-prevalence [ set prevalence min-prevalence ] if prevalence > max-prevalence [ set prevalence max-prevalence ] ] ;; bruit additif (protégé par veto/réflexion) if random-float 1 < noise [ let delta (random-float 0.4 - 0.2) maybe-set-opinion (opinion + delta) ] ;; décroissance des mèmes éventuelle if use-memes? [ decay-memes ] ;; update 3D update-3d self ;; logging if (output = "Values" or output = "File") [ compute-statistics ] ] ;; décroissance du bonus (optionnelle) if reward-decay > 0 [ ask turtles [ set tx-bonus max (list 0 (tx-bonus - reward-decay)) ] ] ;; inversion % ifelse (total > 0) [ set inversion (100 * change / total) ] [ set inversion 0 ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; COLORATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to colorer ask turtles [ ifelse meta? [ set color yellow ] [ ifelse opinion >= 0 [ set color blue ] [ set color red ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MISE À JOUR DU RÉSEAU (suppression/formation + ponts) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-networks ;; suppression 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 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 if not network [ stop ] ask turtles [ 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 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 to apply-link-visibility ifelse show-links? [ ask links [ show-link ] ] [ ask links [ hide-link ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; STATISTIQUES RUNTIME ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 let mplus meme-plus let mminus meme-minus output-print (word ess " ; " ti " ; " ag " ; " pre " ; " mem " ; " infl " ; " memed " ; " mplus " ; " mminus) ] if output = "File" [ let pre prevalence let mem opinion let infl influence let ti ticks let ag who output-print (word ti " ; " pre " ; " mem " ; " infl " ; " ag) ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; I/O : LECTURE FICHIER D’AGENTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to in_file 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 set tx-bonus 0 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 ] ;; init mèmes en cohérence let tot initial-prevalence-to-memes prevalence ifelse opinion >= 0 [ set meme-plus tot * (0.5 + 0.5 * abs opinion) set meme-minus tot - meme-plus ] [ set meme-minus tot * (0.5 + 0.5 * abs opinion) set meme-plus tot - meme-minus ] update-3d self ] ;influenceurs ] [ set in_data false user-message "Read error" ] update-networks apply-link-visibility recolor-links influenceurs update-opinions set repet_data true end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ÉVÉNEMENT EXTERNE (protégé par veto/réflexion) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to event ask turtles [ let event-prob random-float 1 ;; (0,1) if event-prob <= event-prob-max [ ifelse meme_set = true [ if (to_left = false) [ if agent-type = "Right side" [ if opinion < 0 [ maybe-set-opinion (opinion + event_size) ] ] ] if (to_left = true) [ if agent-type = "Left side" [ if opinion > 0 [ maybe-set-opinion (opinion - event_size) ] ] ] ] [ if (to_left = false) [ if (opinion < high_meme and opinion > low_meme and prevalence < high-prev and prevalence > low-prev) [ maybe-set-opinion (opinion + event_size) if (prev_change != 0) [ set prevalence min (list max-prevalence (prevalence + prev_change)) ] ] ] if (to_left = true) [ if (opinion > low_meme and opinion < high_meme and prevalence > low-prev and prevalence < high-prev) [ maybe-set-opinion (opinion - event_size) if (prev_change != 0) [ set prevalence min (list max-prevalence (prevalence + prev_change)) ] ] ] ] ;; init mèmes cohérente avec (prevalence, opinion) if use-memes? [ let tot initial-prevalence-to-memes prevalence ifelse opinion >= 0 [ set meme-plus tot * (0.5 + 0.5 * abs opinion) set meme-minus tot - meme-plus ] [ set meme-minus tot * (0.5 + 0.5 * abs opinion) set meme-plus tot - meme-minus ]] ] ] 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) 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) 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 ;; Sélecteur de mode 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 ;; Mapping prevalence -> stock initial de mèmes to-report initial-prevalence-to-memes [prev] report (prev / 99) * meme-max end ;; Recalcule opinion & prevalence à partir des mèmes (protégé par veto/réflexion) to recompute-from-memes let tot meme-plus + meme-minus if tot < 1e-6 [ set tot 1e-6 ] set proposed-opinion ((meme-plus - meme-minus) / tot) maybe-set-opinion proposed-opinion let scaled (tot / meme-max) * 99 if scaled < 0 [ set scaled 0 ] if scaled > 99 [ set scaled 99 ] set prevalence scaled end ;; Décroissance des mèmes to decay-memes if meme-decay <= 0 [ stop ] set meme-plus max list 0 (meme-plus * (1 - meme-decay)) set meme-minus max list 0 (meme-minus * (1 - meme-decay)) end ;; Transmission des mèmes d’un émetteur vers le receveur (self) to transmit-memes [emitter] let sgn sign [opinion] of emitter ifelse sgn >= 0 [ set meme-plus meme-plus + meme-gain set meme-minus max list 0 (meme-minus - meme-anti-leak * meme-gain) ] [ set meme-minus meme-minus + meme-gain set meme-plus max list 0 (meme-plus - meme-anti-leak * meme-gain) ] ;; plafonner en douceur let tot meme-plus + meme-minus if tot > meme-max [ let factor meme-max / tot set meme-plus meme-plus * factor set meme-minus meme-minus * factor ] 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 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 is only one version of this model, created 2 days ago by Pierre-Alain Cotnoir.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Version_20251017-1_Simulator v5_EN.png | preview | Preview for 'Version_20251017-1_Simulator v5_EN' | 2 days ago, by Pierre-Alain Cotnoir | Download |
This model does not have any ancestors.
This model does not have any descendants.