Updated Civil Unrest Model

Updated Civil Unrest Model preview image

1 collaborator

Default-person Artem Serdyuk (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by the author
Model was written in NetLogo 6.4.0 • Viewed 20 times • Downloaded 3 times • Run 0 times
Download the 'Updated Civil Unrest Model' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;extensions [ time ]

breed [ agents an-agent ]
breed [ cops cop ]

globals [
  k                    ; factor for determining arrest probability
  threshold           ; by how much must G > N to make someone rebel?

  ; Time tracking
  current-date        ; current simulation date
  wave-start-date     ; start date of current wave
  wave-duration       ; duration of current wave

  ; Wave parameters
  current-wave        ; current active wave type
  wave-number         ; which wave we're on
  wave-intensity      ; current wave intensity

  ; Social tension parameters
  immigration-tension    ; tracks immigration-related tension
  womens-rights-tension ; tracks women's rights related tension
  geopolitical-tension  ; tracks international relations tension
  corporate-tension     ; tracks corporate/economic tension

  ; Crisis indicators
  communication-crisis    ; poor international communication
  policy-crisis          ; controversial policy implementations
  economic-crisis        ; economic hardship indicators

  ; Population parameters
  base-protest-ready-percent  ; 20-25% normally
  crisis-protest-ready-percent ; 30-35% during crisis

  ; Statistics
  total-active-protesters
  female-active-protesters
  male-active-protesters
  cumulative-participants    ; total participants across all waves
]

agents-own [
  risk-aversion       ; R, fixed for the agent's lifetime
  perceived-hardship  ; H, ranging from 0-1
  active?             ; if true, then the agent is actively rebelling
  jail-term          ; how many turns in jail remain?

  gender             ; "female" or "male"
  protest-causes     ; list of causes they care about
  protest-energy     ; energy for protesting (0-1)
  protest-threshold  ; individual threshold for joining
  diaspora           ; specific community membership
  activism-level     ; how likely to join protests

  home-patch         ; where agent typically returns to
]

patches-own [
  neighborhood       ; surrounding patches within vision radius
  diaspora-density   ; concentration of specific communities
  urban-center?      ; is this a major city?
  protest-probability ; base likelihood of protest activity
]

to setup
  clear-all
  reset-ticks

  set k 2.3
  set threshold 0.1
  set current-date 0
  set wave-number 0
  set cumulative-participants 0

  ; Initialize tension levels
  set immigration-tension random-float 0.3
  set womens-rights-tension random-float 0.3
  set geopolitical-tension random-float 0.3
  set corporate-tension random-float 0.3

  ; Initialize crisis indicators
  set communication-crisis false
  set policy-crisis false
  set economic-crisis false

  ; Set population parameters
  set base-protest-ready-percent 0.225
  set crisis-protest-ready-percent 0.325

  setup-patches
  setup-agents
  setup-cops

  update-statistics
end 

to setup-patches
  ask patches [
    set pcolor gray - 1
    set neighborhood patches in-radius vision
    set urban-center? (random-float 1.0 < 0.1)
    set protest-probability ifelse-value urban-center?
      [ 0.3 + random-float 0.2 ]
      [ 0.1 + random-float 0.1 ]
    set diaspora-density random-float 1.0
  ]
end 

to setup-cops
  create-cops round (initial-cop-density * .01 * count patches) [
    move-to one-of patches with [ not any? turtles-here ]
    display-cop
  ]
end 

to-report assign-gender
  ; Based on sociology data showing 60-70% female participation
  report ifelse-value (random-float 1.0 < 0.65)
    [ "female" ]
    [ "male" ]
end 

to setup-agents
  create-agents round (initial-agent-density * .01 * count patches) [
    move-to one-of patches with [ not any? turtles-here ]
    set heading 0
    set home-patch patch-here

    ; Basic properties
    set risk-aversion random-float 1.0
    set perceived-hardship random-float 1.0
    set active? false
    set jail-term 0

    ; Advanced properties
    set gender assign-gender
    set protest-causes assign-causes
    set protest-energy random-float 1.0
    set protest-threshold calculate-protest-threshold
    set diaspora assign-diaspora
    set activism-level random-float 1.0

    display-agent
  ]
end 

to go
  ; Increment time and manage waves first
  manage-waves
  update-social-dynamics

  ask turtles [
    if (breed = agents and jail-term = 0) or breed = cops [ move ]
    if breed = agents and jail-term = 0 [ determine-behavior ]
    if breed = cops [ enforce ]
  ]

  ask agents [ if jail-term > 0 [ set jail-term jail-term - 1 ] ]

  ask agents [ display-agent ]
  ask cops [ display-cop ]

  update-statistics
  tick
end 

to enforce  ; cop procedure
  ; Use in-radius instead of patch variable
  let active-targets agents in-radius vision with [active? and breed = agents]

  if any? active-targets [
    let target min-one-of active-targets [
      ; Prioritize closer targets and those causing more disturbance
      distance myself - activism-level
    ]

    if target != nobody [
      move-to target
      ask target [
        set active? false
        set jail-term random max-jail-term

        if gender = "female" [
          set womens-rights-tension womens-rights-tension + 0.01
        ]
        if diaspora != "none" [
          set geopolitical-tension geopolitical-tension + 0.01
        ]
      ]
    ]
  ]
end 

to update-social-dynamics
  ; Update tension levels based on current events and conditions
  set immigration-tension update-tension immigration-tension policy-crisis
  set womens-rights-tension update-tension womens-rights-tension policy-crisis
  set geopolitical-tension update-tension geopolitical-tension communication-crisis
  set corporate-tension update-tension corporate-tension economic-crisis

  ; Update crisis indicators based on evolving conditions
  if random-float 1.0 < 0.001 [ toggle-crisis "communication" ]
  if random-float 1.0 < 0.001 [ toggle-crisis "policy" ]
  if random-float 1.0 < 0.001 [ toggle-crisis "economic" ]
end 

to-report update-tension [current-tension crisis?]
  let new-tension current-tension

  ; Natural decay
  set new-tension new-tension * 0.99

  ; Crisis impact
  if crisis? [ set new-tension new-tension + 0.05 ]

  ; Random fluctuation
  set new-tension new-tension + (random-float 0.02 - 0.01)

  ; Ensure bounds
  report max (list 0 (min (list 1 new-tension)))
end 

to toggle-crisis [crisis-type]
  if crisis-type = "communication" [
    set communication-crisis not communication-crisis
    if communication-crisis [ set geopolitical-tension geopolitical-tension + 0.2 ]
  ]
  if crisis-type = "policy" [
    set policy-crisis not policy-crisis
    if policy-crisis [
      set immigration-tension immigration-tension + 0.2
      set womens-rights-tension womens-rights-tension + 0.2
    ]
  ]
  if crisis-type = "economic" [
    set economic-crisis not economic-crisis
    if economic-crisis [ set corporate-tension corporate-tension + 0.2 ]
  ]
end 

to manage-waves
  ; Increment current date
  set current-date current-date + 1

  ; Check for wave end conditions
  if current-wave != 0 [
    if current-date - wave-start-date > wave-duration [
      set current-wave 0
      set wave-intensity 0
    ]
  ]

  ; Check for new wave start conditions
  if current-wave = 0 and should-start-new-wave? [
    set wave-number wave-number + 1
    set wave-start-date current-date
    set current-wave select-wave-cause
    set wave-intensity calculate-wave-intensity
    set wave-duration calculate-wave-duration
  ]
end 

to start-new-wave
  set wave-number wave-number + 1
  set wave-start-date current-date
  set current-wave select-wave-cause
  set wave-intensity calculate-wave-intensity
  set wave-duration calculate-wave-duration

  ; Trigger immediate effects
  ask agents [
    if member? current-wave protest-causes [
      set perceived-hardship perceived-hardship * 1.2
    ]
  ]
end 

to end-current-wave
  set current-wave 0
  set wave-intensity 0

  ; Cool down effects
  ask agents [
    set perceived-hardship perceived-hardship * 0.9
  ]
end 

to update-wave-intensity
  let elapsed-time current-date - wave-start-date
  let peak-time wave-duration / 2

  ; Calculate bell curve intensity
  let time-factor (- ((elapsed-time - peak-time) ^ 2) / (2 * (wave-duration / 4) ^ 2))
  let new-intensity wave-intensity * exp time-factor

  ; Add random fluctuations
  set wave-intensity new-intensity * (0.9 + random-float 0.2)

  ; Intensity affected by active protesters
  let active-ratio count agents with [active?] / count agents
  if active-ratio > 0.1 [
    set wave-intensity wave-intensity * (1 + active-ratio)
  ]
end 

to-report should-start-new-wave?
  ; Base probability from social tensions
  let total-tension (
    immigration-tension * 0.25 +
    womens-rights-tension * 0.35 +
    geopolitical-tension * 0.2 +
    corporate-tension * 0.2
  )

  ; Wave probability increases with:
  ; 1. Higher tensions
  let wave-probability total-tension * 0.1

  ; 2. Existing protest activity
  let active-ratio count agents with [active?] / count agents
  if active-ratio > 0.05 [
    set wave-probability wave-probability * (1 + active-ratio * 4)
  ]

  ; 3. Crisis conditions
  if communication-crisis [ set wave-probability wave-probability * 1.5 ]
  if policy-crisis [ set wave-probability wave-probability * 1.5 ]
  if economic-crisis [ set wave-probability wave-probability * 1.5 ]

  ; 4. Time since last wave
  if wave-number > 0 [
    let time-since-last-wave current-date - wave-start-date
    if time-since-last-wave > 100 [
      set wave-probability wave-probability * 1.3
    ]
  ]

  ; Threshold check with randomization
  report random-float 1.0 < wave-probability
end 

to-report select-wave-cause
  ; Calculate weighted probabilities based on current tensions
  let total-weight (
    immigration-tension * immigration-weight +
    womens-rights-tension * womens-rights-weight +
    geopolitical-tension * geopolitics-weight +
    corporate-tension * corporate-weight
  )

  let r random-float total-weight
  let cumulative 0

  set cumulative cumulative + (immigration-tension * immigration-weight)
  if r < cumulative [ report "immigration" ]

  set cumulative cumulative + (womens-rights-tension * womens-rights-weight)
  if r < cumulative [ report "womens-rights" ]

  set cumulative cumulative + (geopolitical-tension * geopolitics-weight)
  if r < cumulative [ report "geopolitics" ]

  report "corporate"
end 

to-report calculate-wave-intensity
  let base-intensity 0.002 ; Base intensity for ~500K participants

  ; Adjust based on cause-specific tension
  if current-wave = "immigration" [ set base-intensity base-intensity * (1 + immigration-tension) ]
  if current-wave = "womens-rights" [ set base-intensity base-intensity * (1 + womens-rights-tension) ]
  if current-wave = "geopolitics" [ set base-intensity base-intensity * (1 + geopolitical-tension) ]
  if current-wave = "corporate" [ set base-intensity base-intensity * (1 + corporate-tension) ]

  ; Adjust for crisis conditions
  if communication-crisis [ set base-intensity base-intensity * 1.3 ]
  if policy-crisis [ set base-intensity base-intensity * 1.3 ]
  if economic-crisis [ set base-intensity base-intensity * 1.3 ]

  ; Add random variation
  set base-intensity base-intensity * (0.8 + random-float 0.4)

  report precision base-intensity 3
end 

to-report assign-causes
  let causes []

  ; Check each cause based on weights from sociology data
  if random-float 1.0 < immigration-weight [ set causes lput "immigration" causes ]
  if random-float 1.0 < womens-rights-weight [ set causes lput "womens-rights" causes ]
  if random-float 1.0 < geopolitics-weight [ set causes lput "geopolitics" causes ]
  if random-float 1.0 < corporate-weight [ set causes lput "corporate" causes ]

  ; Ensure each agent has at least one cause
  if empty? causes [ set causes list (one-of ["immigration" "womens-rights" "geopolitics" "corporate"]) [] ]

  report causes
end 

to-report assign-diaspora
  ; Based on sociology data mentioning Ukrainian diaspora specifically
  let r random-float 1.0
  report ifelse-value (r < 0.05)  ; Small percentage for specific diaspora groups
    [ one-of ["ukrainian" "other"] ]
    [ "none" ]
end 

to-report calculate-protest-threshold
  let base-threshold 0.5

  if gender = "female" [ set base-threshold base-threshold * 0.8 ]
  if diaspora != "none" [ set base-threshold base-threshold * 0.9 ]

  ; Fixed to use actual crisis variables:
  ifelse communication-crisis or policy-crisis or economic-crisis [
    set base-threshold base-threshold * (1 - crisis-protest-ready-percent)
  ] [
    set base-threshold base-threshold * (1 - base-protest-ready-percent)
  ]

  report base-threshold
end 

to-report calculate-grievance  ; agent procedure
  ; Use the interface slider directly
  let base-grievance perceived-hardship * (grievance-multiplier - government-legitimacy)

  ; Cap at reasonable values
  set base-grievance min (list 1 base-grievance)

  ; Rest of the function remains the same
  if current-wave != 0 [
    if member? current-wave protest-causes [
      set base-grievance base-grievance * (1 + wave-intensity)
    ]
  ]

  ; Identity-based grievance multipliers
  if gender = "female" and member? "womens-rights" protest-causes [
    set base-grievance base-grievance * 1.2
  ]

  ; Social tension effects
  if member? "immigration" protest-causes [
    set base-grievance base-grievance * (1 + immigration-tension * 0.8)
  ]
  if member? "womens-rights" protest-causes [
    set base-grievance base-grievance * (1 + womens-rights-tension * 0.8)
  ]
  if member? "geopolitics" protest-causes [
    set base-grievance base-grievance * (1 + geopolitical-tension * 0.8)
  ]
  if member? "corporate" protest-causes [
    set base-grievance base-grievance * (1 + corporate-tension * 0.8)
  ]

  report base-grievance
end 

to-report estimated-arrest-probability  ; agent procedure
  let c count cops in-radius vision
  let a 1 + count agents in-radius vision with [active?]

  ; Based on original model's formula with slight modification for dynamic scenarios
  report 1 - exp (- k * floor (c / a))
end 

to display-agent
  ifelse visualization = "2D"
    [ display-agent-2d ]
    [ display-agent-3d ]
end 

to display-agent-2d
  set shape "circle"
  ifelse active?
    [ set color red ]
    [ ifelse jail-term > 0
        [ set color black + 3 ]
        [ set color scale-color green perceived-hardship 1.5 -0.5 ]
    ]
end 

to display-agent-3d
  ifelse active?
    [ set shape "person active" ]
    [ ifelse jail-term > 0
        [ set shape "person jailed" ]
        [ set shape "person quiet" ]
    ]
  ; Color represents grievance level
  set color scale-color green perceived-hardship 1.5 -0.5
end 

to move
  if movement? or breed = cops [
    ifelse breed = agents and not active? [
      ; Non-protesting agents prefer to stay near home
      move-toward-home
    ] [
      ; Active agents and cops look for strategic positions
      let potential-moves neighborhood with [
        not any? cops-here and
        not any? agents-here with [ jail-term > 0 ]
      ]

      if any? potential-moves [
        ; Cops prefer to move toward clusters of active agents
        ifelse breed = cops [
          let active-nearby-patches neighborhood with [
            any? agents-here with [ active? ]
          ]
          ifelse any? active-nearby-patches [
            move-to one-of active-nearby-patches
          ] [
            move-to one-of potential-moves
          ]
        ] [
          ; Active agents try to avoid cops while staying in protest areas
          move-to one-of potential-moves
        ]
      ]
    ]
  ]
end 

to move-toward-home
  ; Only agents have home patches, not cops
  if breed = agents [
    let my-home [home-patch] of self
    if distance my-home > vision [
      face my-home
      let target-patch min-one-of (patch-set patch-ahead 1 patch-right-and-ahead 45 1 patch-left-and-ahead 45 1) [
        distance my-home
      ]
      if target-patch != nobody and not any? turtles-on target-patch [
        move-to target-patch
      ]
    ]
  ]
end 

to display-cop
  set color cyan
  ifelse visualization = "2D"
    [ set shape "triangle" ]
    [ set shape "person soldier" ]
end 

to-report calculate-wave-duration
  let base-duration 30

  ; Longer duration for higher intensity waves
  set base-duration base-duration * (1 + wave-intensity * 10)

  ; Adjust for crisis conditions
  if communication-crisis or policy-crisis or economic-crisis [
    set base-duration base-duration * 1.2
  ]

  ; Add random variation
  report base-duration + random 20
end 

to determine-behavior
  let current-grievance calculate-grievance
  let arrest-prob estimated-arrest-probability

  ; Use the interface slider directly
  set active? (current-grievance - (risk-aversion * risk-weight) * arrest-prob > threshold-base-value)

  ; Track if agent just became active
  if active? and not was-active? [
    set cumulative-participants cumulative-participants + 1
  ]
end 

to-report was-active?
  report active?
end 

; [Rest of the original procedures remain the same: move, enforce, display-agent, etc.]

to update-statistics
  set total-active-protesters count agents with [ active? ]
  set female-active-protesters count agents with [ active? and gender = "female" ]
  set male-active-protesters count agents with [ active? and gender = "male" ]
end 

There are 2 versions of this model.

Uploaded by When Description Download
Artem Serdyuk 16 days ago Time extension excluded Download this version
Artem Serdyuk 18 days ago Initial upload Download this version

Attached files

File Type Description Last updated
Updated Civil Unrest Model.png preview Preview for 'Updated Civil Unrest Model' 18 days ago, by Artem Serdyuk Download

This model does not have any ancestors.

This model does not have any descendants.