Difference between revisions of "Traffic Accident Risk Analysis"

From Simulace.info
Jump to: navigation, search
Line 71: Line 71:
 
Because accidents last 90 ticks on a patch, any collision severely disrupts traffic, likely forcing more cars to queue or collide.
 
Because accidents last 90 ticks on a patch, any collision severely disrupts traffic, likely forcing more cars to queue or collide.
 
Despite that, 67 cars did manage to exit, though the blocked patches would have contributed to higher accident numbers and more emergent congestion.
 
Despite that, 67 cars did manage to exit, though the blocked patches would have contributed to higher accident numbers and more emergent congestion.
 +
 +
  
 
== Conclusion ==
 
== Conclusion ==
  
  
NetLogo model offers a flexible testbed for exploring how each factor contributes to — or mitigates — traffic accidents. Real-world calibration data (e.g., from TSK Praha) can refine the baseline accident probabilities, enabling more realistic scenario testing.
+
This NetLogo simulation allows users to vary key parameters—such as base speed, number of cars (density), road condition (good to very bad), driver-error rate, and accident duration—then observe metrics like average travel time, distance/time until accident, and accident hotspots. Results show that poor roads and high driver-error rates sharply increase collisions, while long accident durations intensify congestion. Conversely, safer infrastructure, lower driver-error rates, and faster incident clearance foster smoother traffic flow and fewer crashes, underlining the value of integrated traffic safety strategies.
  
 
== Code ==
 
== Code ==
 
Below is the NetLogo code implementing the simulation structure (patch definitions, accident logic, congestion metrics, etc.). Users can copy and paste it into a NetLogo environment to run their own experiments. For a complete listing, see the setup, go, and supporting procedures:
 
Below is the NetLogo code implementing the simulation structure (patch definitions, accident logic, congestion metrics, etc.). Users can copy and paste it into a NetLogo environment to run their own experiments. For a complete listing, see the setup, go, and supporting procedures:
 +
 +
 +
<code><nowiki>globals [
 +
  ;; Sliders / Switch in Interface:
 +
  ;;  - number-of-cars      (int)
 +
  ;;  - road-spacing        (int)
 +
  ;;  - base-speed          (float)
 +
  ;;  - driver-error-rate  (float)
 +
  ;;  - accident-duration  (int)
 +
  ;;  - traffic-lights?    (boolean switch)
 +
 +
  ;; Statistics
 +
  total-cars-reached-destination
 +
  total-cars-accident        ;; how many cars died in accidents (cumulative)
 +
  accident-count              ;; how many total accidents have started
 +
  average-speed
 +
  average-congestion
 +
  accident-percentage
 +
  sum-travel-time          ;; sum of time in system for all cars that exit
 +
  count-completed-cars      ;; how many cars reached destination
 +
  average-travel-time      ;; output metric
 +
  accident-count-good
 +
  accident-count-bad
 +
  accident-count-very-bad
 +
  sum-time-until-accident
 +
  sum-distance-until-accident
 +
  average-time-until-accident
 +
  average-distance-until-accident
 +
]
 +
 +
patches-own [
 +
  is-road?          ;; boolean: is this patch part of a road?
 +
  is-intersection?  ;; boolean: is this patch an intersection?
 +
  lane-direction    ;; forced heading: 0, 90, 180, 270, or -1 if intersection
 +
  traffic-light?    ;; does this patch have a traffic light?
 +
  light-state        ;; true=green, false=red
 +
  has-accident?      ;; boolean: accident currently on this patch?
 +
  accident-lifetime  ;; integer: how many ticks remain for this accident?
 +
  road-condition    ;; 0=good, 1=bad, 2=very bad (affects accident prob)
 +
]
 +
 +
breed [ cars car ]
 +
cars-own [
 +
  speed
 +
  max-speed
 +
  stopped-ticks
 +
  destination        ;; patch or nobody
 +
  birth-tick                ;; store the tick when the car is created
 +
  distance-traveled          ;; accumulates how far the car has moved
 +
]
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  1.  SETUP                                                  ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to setup
 +
  clear-all
 +
 +
  ;; Initialize stats
 +
  set total-cars-reached-destination 0
 +
  set total-cars-accident 0
 +
  set accident-count 0
 +
  set average-speed 0
 +
  set average-congestion 0
 +
 
 +
  set sum-travel-time 0
 +
  set count-completed-cars 0
 +
  set average-travel-time 0
 +
 
 +
  set accident-count-good 0
 +
  set accident-count-bad 0
 +
  set accident-count-very-bad 0
 +
 
 +
  set sum-time-until-accident 0
 +
  set sum-distance-until-accident 0
 +
  set average-time-until-accident 0
 +
  set average-distance-until-accident 0
 +
 +
  setup-roads
 +
  setup-intersections
 +
  setup-traffic-lights
 +
  setup-road-conditions
 +
 
 +
  reset-ticks
 +
 
 +
  create-initial-cars
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  2.  CREATE ROADS (TWO LANE, ONE-WAY)                        ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to setup-roads
 +
  ask patches [
 +
    set is-road? false
 +
    set is-intersection? false
 +
    set traffic-light? false
 +
    set light-state false
 +
    set has-accident? false
 +
    set accident-lifetime 0
 +
    set lane-direction 0
 +
    set road-condition 0
 +
    set pcolor green
 +
  ]
 +
 +
  ;; 2-lane roads in x or y dimension
 +
  let road-patches patches with [
 +
    (abs pxcor mod road-spacing <= 1) or
 +
    (abs pycor mod road-spacing <= 1)
 +
  ]
 +
 +
  ask road-patches [
 +
    set is-road? true
 +
    set pcolor grey
 +
  ]
 +
 +
  ;; Assign forced lane headings for non-intersection road patches
 +
  ask road-patches [
 +
    let x-road? (abs pxcor mod road-spacing <= 1)
 +
    let y-road? (abs pycor mod road-spacing <= 1)
 +
 +
    ;; purely vertical lane: pick 0 or 180
 +
    if (x-road? and not y-road?) [
 +
      ifelse (pxcor mod 2 = 0)
 +
        [ set lane-direction 0  ]  ;; "northbound"
 +
        [ set lane-direction 180 ]  ;; "southbound"
 +
    ]
 +
 +
    ;; purely horizontal lane: pick 90 or 270
 +
    if (y-road? and not x-road?) [
 +
      ifelse (pycor mod 2 = 0)
 +
        [ set lane-direction 90  ]  ;; "eastbound"
 +
        [ set lane-direction 270 ]  ;; "westbound"
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  3.  INTERSECTIONS                                          ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to setup-intersections
 +
  ask patches with [is-road?] [
 +
    let x-road? (abs pxcor mod road-spacing <= 1)
 +
    let y-road? (abs pycor mod road-spacing <= 1)
 +
 +
    ;; Intersection = patch that is both x-road & y-road
 +
    if (x-road? and y-road?) [
 +
      set is-intersection? true
 +
      set pcolor yellow
 +
      set lane-direction -1  ;; means "all directions possible here"
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  4.  TRAFFIC LIGHTS                                          ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to setup-traffic-lights
 +
  if traffic-lights? [
 +
    ;; Turn on lights at each intersection
 +
    ask patches with [is-intersection?] [
 +
      set traffic-light? true
 +
      set light-state true
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  5.  ROAD CONDITIONS                                        ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to setup-road-conditions
 +
  let sum-prob (good-road-probability + bad-road-probability)
 +
 
 +
  ask patches with [is-road?] [
 +
    let r random-float 1
 +
   
 +
    ifelse (r < good-road-probability) [
 +
      ;; (1) "Good" road
 +
      set road-condition 0
 +
      set pcolor grey
 +
     
 +
    ] [
 +
      ifelse (r < sum-prob) [
 +
        ;; (2) "Bad" road
 +
        set road-condition 1
 +
        set pcolor (grey - 2)
 +
       
 +
        ;; 5% chance to become "Very Bad" instead:
 +
        if random-float 1 < 0.05 [
 +
          set road-condition 2
 +
          set pcolor orange
 +
        ]
 +
       
 +
      ] [
 +
       
 +
        set road-condition 0
 +
        set pcolor grey
 +
      ]
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  6.  CREATE INITIAL CARS                                    ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to create-initial-cars
 +
  ask cars [ die ]  ;; remove any old cars
 +
 +
  let valid-starts patches with [
 +
    is-road? and
 +
    not has-accident? and
 +
    not any? cars-here
 +
  ]
 +
 +
  if not any? valid-starts [
 +
    user-message "No valid road patches for car creation!"
 +
    stop
 +
  ]
 +
 +
  create-cars min list number-of-cars (count valid-starts) [
 +
    set shape "car"
 +
    set color blue
 +
    set size 0.8
 +
 +
    ;; pick a random road patch
 +
    let start-patch one-of valid-starts
 +
    move-to start-patch
 +
    set valid-starts valid-starts with [self != start-patch]
 +
 +
    ;; If this patch is an intersection => pick a direction
 +
    ifelse ([lane-direction] of patch-here = -1)
 +
      [ set heading one-of [0 90 180 270] ]
 +
      [ set heading [lane-direction] of patch-here ]
 +
 +
    set speed 0
 +
    set max-speed base-speed
 +
    set stopped-ticks 0
 +
    set destination nobody
 +
    set distance-traveled 0
 +
    set birth-tick ticks
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  7.  GO (MAIN LOOP)                                          ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to go
 +
  if not any? cars [ stop ]
 +
 +
  update-traffic-lights
 +
  move-cars
 +
  check-accidents
 +
  clear-old-accidents
 +
  update-statistics
 +
 +
  tick
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  8.  UPDATE TRAFFIC LIGHTS                                  ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to update-traffic-lights
 +
  if traffic-lights? [
 +
    ask patches with [is-intersection? and traffic-light?] [
 +
      ;; simple toggle every 30 ticks
 +
      if (ticks mod 30 = 0) [
 +
        set light-state not light-state
 +
        set pcolor ifelse-value light-state [green] [red]
 +
      ]
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;;  9.  MOVE CARS                                              ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to move-cars
 +
  ask cars [
 +
    ;; Force lane direction
 +
    let patch-lane [lane-direction] of patch-here
 +
 +
    ifelse patch-lane = -1 [
 +
      ;; intersection => pick a new direction each tick or once
 +
      set heading one-of [0 90 180 270]
 +
    ]
 +
    [
 +
      ;; normal lane => enforce that heading
 +
      set heading patch-lane
 +
    ]
 +
 +
    ;; Decide if it's safe to move
 +
    let safe-to-move? true
 +
 +
    ;; Check traffic light
 +
    if [traffic-light?] of patch-here [
 +
      if not ([light-state] of patch-here) [
 +
        set safe-to-move? false
 +
      ]
 +
    ]
 +
 +
    ;; Check for cars ahead in same lane
 +
    if any? cars-on patch-ahead 1 [
 +
      set safe-to-move? false
 +
    ]
 +
 +
    ;;  Move or slow
 +
    ifelse safe-to-move? [
 +
      set speed min (list (speed + 0.1) max-speed)
 +
      forward speed
 +
      set distance-traveled distance-traveled + speed
 +
      set stopped-ticks 0
 +
    ] [
 +
      set speed max (list (speed - 0.2) 0)
 +
      set stopped-ticks (stopped-ticks + 1)
 +
    ]
 +
 +
;; if the car leaves the grid:
 +
    if not is-patch? patch-here [
 +
     
 +
      set count-completed-cars (count-completed-cars + 1)
 +
     
 +
      ;;  Add to sum-travel-time:
 +
      set sum-travel-time (sum-travel-time + (ticks - birth-tick))
 +
 +
      ;; Then die
 +
      die
 +
    ]
 +
 +
    if (max-pxcor - abs xcor) < 1 or (max-pycor - abs ycor) < 1 [
 +
      set total-cars-reached-destination (total-cars-reached-destination + 1)
 +
 +
      set count-completed-cars (count-completed-cars + 1)
 +
      set sum-travel-time (sum-travel-time + (ticks - birth-tick))
 +
     
 +
      die
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;; 10.  ACCIDENT LOGIC (EXPANDED)                              ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to check-accidents
 +
  ;; For each car, compute probability of an accident
 +
  ask cars [
 +
    if random-float 1 < calculate-accident-probability self [
 +
      create-accident self
 +
    ]
 +
  ]
 +
end
 +
 +
to-report calculate-accident-probability [ c ]
 +
  ;; Base accident probability from driver error
 +
  let base (driver-error-rate * 0.00025)
 +
 
 +
  ;;  Find the patch under turtle c (using c's pxcor, pycor)
 +
  let p patch ([pxcor] of c) ([pycor] of c)
 +
 
 +
  ;;  Road condition effect
 +
  if [road-condition] of p = 1 [
 +
    set base (base * 2)
 +
  ]
 +
  if [road-condition] of p = 2 [
 +
    set base (base * 2.6)
 +
  ]
 +
 
 +
  ;; Speed factor
 +
  let speed-ratio ([speed] of c / [max-speed] of c)
 +
  set base (base * (speed-ratio + 0.1))  ;; +0.1 so even slow cars have some chance
 +
 
 +
  ;; Congestion effect: how many other cars are within radius 1.5 of c
 +
  let nearby-cars count cars with [ distance c < 1.5 ]
 +
  set base (base + (nearby-cars * 0.0005))
 +
 
 +
  ;;  Intersection effect
 +
  if [is-intersection?] of p [
 +
    set base (base * 1.5)
 +
  ]
 +
 
 +
  ;; Cap at 1% (0.01) to avoid extreme probabilities
 +
  report min (list base 0.1)
 +
 
 +
end
 +
 +
 +
to create-accident [ c ]
 +
  set accident-count (accident-count + 1)
 +
  set total-cars-accident (total-cars-accident + 1)
 +
 +
  ;; Mark the patch
 +
  let px ([pxcor] of c)
 +
  let py ([pycor] of c)
 +
  ask patch px py [
 +
    set has-accident? true
 +
    set pcolor red
 +
    set accident-lifetime accident-duration
 +
 +
    ;; Accidents by Road Condition:
 +
    if (road-condition = 0) [ set accident-count-good (accident-count-good + 1) ]
 +
    if (road-condition = 1) [ set accident-count-bad (accident-count-bad + 1) ]
 +
    if (road-condition = 2) [ set accident-count-very-bad (accident-count-very-bad + 1) ]
 +
  ]
 +
 +
  ;; Time & Distance to Accident:
 +
  let time-until-accident (ticks - [birth-tick] of c)
 +
  let dist-until-accident ([distance-traveled] of c)
 +
  set sum-time-until-accident (sum-time-until-accident + time-until-accident)
 +
  set sum-distance-until-accident (sum-distance-until-accident + dist-until-accident)
 +
 +
  ;; kill the car
 +
  ask c [ die ]
 +
end
 +
 +
to clear-old-accidents
 +
  ;; Decrement accident-lifetime. When it hits 0, clear the patch.
 +
  ask patches with [has-accident?] [
 +
    set accident-lifetime (accident-lifetime - 1)
 +
    if (accident-lifetime <= 0) [
 +
      set has-accident? false
 +
      ;; restore color based on road-condition
 +
      if (road-condition = 0) [
 +
        set pcolor grey
 +
      ]
 +
      if (road-condition = 1) [
 +
        set pcolor (grey - 2)
 +
      ]
 +
      if (road-condition = 2) [
 +
        set pcolor orange
 +
      ]
 +
    ]
 +
  ]
 +
end
 +
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
;;; 11.  STATISTICS & PLOTS                                      ;;;
 +
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 +
 +
to update-statistics
 +
  let car-count count cars
 +
  let total-speed 0
 +
 +
  if car-count > 0 [
 +
    set total-speed sum [speed] of cars
 +
    set average-speed (total-speed / car-count)
 +
  ]
 +
  if car-count = 0 [
 +
    set average-speed 0
 +
  ]
 +
 +
 
 +
  set average-congestion count cars with [
 +
    (stopped-ticks >= 2) and (any? cars-on patch-ahead 1)
 +
  ]
 +
  if number-of-cars > 0 [
 +
    set accident-percentage ((accident-count / number-of-cars) * 100)
 +
  ]
 +
  ;;Average travel time for cars that completed trip
 +
  if count-completed-cars > 0 [
 +
    set average-travel-time (sum-travel-time / count-completed-cars)
 +
  ]
 +
  ;;Averages for time & distance until accident
 +
  if accident-count > 0 [
 +
    set average-time-until-accident (sum-time-until-accident / accident-count)
 +
    set average-distance-until-accident (sum-distance-until-accident / accident-count)
 +
  ]
 +
  ;; Plot them
 +
  carefully [
 +
    set-current-plot "Average Speed"
 +
    plot average-speed
 +
 +
    set-current-plot "Total Accidents"
 +
    plot accident-count
 +
 +
    set-current-plot "Average Congestion"
 +
    plot average-congestion
 +
  ] []
 +
end
 +
 +
</nowiki></code>
  
 
== References ==
 
== References ==

Revision as of 20:23, 10 January 2025

Introduction

This page introduces a NetLogo-based simulation that models traffic accident risk. The goal is to understand how road conditions, traffic density, and driver behavior intertwine to create or mitigate accidents. Various research sources underscore the need for a systematic approach to traffic safety, illustrating how driver reliability, infrastructure, and cultural factors shape accident outcomes (Sadauskas, 2011; Gstalter & Fastenmeier, 2010; TSK Praha, 2020; Nordfjærn et al., 2011).

Definition of the Problem

Road traffic accidents remain a pressing public health challenge, especially with the steady growth in vehicle numbers worldwide (Sadauskas, 2011). This proliferation escalates the likelihood of collisions, injuries, and fatalities. A robust traffic safety strategy thus necessitates examining:

Road conditions (from good to very bad).

Driver behavior and risk homeostasis (adjusting behavior based on perceived safety).

Environmental and societal factors that influence compliance with safety rules (Nordfjærn et al., 2011).

Moreover, the complexity of urban intersections can amplify error rates, as drivers face higher cognitive loads and multiple conflict points (Gstalter & Fastenmeier, 2010). In city contexts, baseline accident rates still vary considerably depending on infrastructure, as seen in real-world data (TSK Praha, 2020).

Method

A systematic approach to traffic safety integrates engineering, enforcement, and education — often referred to as the “Triple E” (Sadauskas, 2011):

Engineering: Vehicle and road design improvements (e.g., signage, intersections, lighting).

Education: Public awareness, driver training programs targeting risk perception and behavior.

Enforcement: Legal measures (speed limits, penalties) ensuring compliance with traffic rules.

Human Reliability Analysis (HRA) has also been adapted to driving tasks to quantify driver error probabilities at intersections (Gstalter & Fastenmeier, 2010). By defining “correct” driver actions and measuring deviations, one can estimate how road geometry, age, and psycho-social factors alter driver reliability.

Model

This simulation uses NetLogo to create a grid of patches representing:

Road segments: Assigned good, bad, or very bad condition.

Intersections: Potentially with traffic lights.

Cars (turtles): Move according to lane rules and can trigger accidents based on speed, congestion, and driver-error-rate.

Key points:

Accident Probability: Derived from a base driver-error-rate, amplified by intersection complexity, road condition, and local traffic density (Gstalter & Fastenmeier, 2010; Nordfjærn et al., 2011).

Baseline Rates: Inspired by real accident data (e.g., TSK Praha’s ročenka dopravy or Accident risks of different weather conditions) (TSK Praha, 2020) (Malin 2017).

Systematic Approach: Reflects suggestions for engineering (road condition logic), education (driver-error slider), and enforcement (speed constraints) in modeling different scenarios (Sadauskas, 2011).

Interface

Interface timm03.png


High Density, Poor Roads

LowDensity timm03.png

Because there are 100 cars with a fairly high driver-error-rate (0.05), multiple accidents occurred (10 total). However, they tended to happen later in the simulation (average time until accident over 300 ticks). Most cars (90 out of 100) still reached their destination—likely because accident-duration is very short (1 tick), so blocked patches quickly returned to normal. The relatively high base speed (0.8) also increased mobility, helping more cars finish faster, but also contributed to a moderate accident rate.

Low Density, Strict Limits

HighDensity timm03.png

Fewer cars (50), but also a much lower base speed (0.3), so cars move more slowly—leading to a higher average travel time (over 200 ticks). Because driver-error-rate is only 0.01 (lower chance of human error) and 70% roads are good, only 3 accidents occurred. Even with slow speed, many cars still took a long time to finish, as shown by the high travel time. Almost all cars managed to complete or crash within the time frame, with 47 successful arrivals.


Moderate Density, Extended Accident Duration

ModerateDensity timm03.png

Compared to the second screenshot, the big difference is accident-duration = 90 (very long). Even though speed is still 0.3 and the road condition/distribution is the same, the accident count has climbed to 13, and 16% of the cars ended up in accidents. Because accidents last 90 ticks on a patch, any collision severely disrupts traffic, likely forcing more cars to queue or collide. Despite that, 67 cars did manage to exit, though the blocked patches would have contributed to higher accident numbers and more emergent congestion.


Conclusion

This NetLogo simulation allows users to vary key parameters—such as base speed, number of cars (density), road condition (good to very bad), driver-error rate, and accident duration—then observe metrics like average travel time, distance/time until accident, and accident hotspots. Results show that poor roads and high driver-error rates sharply increase collisions, while long accident durations intensify congestion. Conversely, safer infrastructure, lower driver-error rates, and faster incident clearance foster smoother traffic flow and fewer crashes, underlining the value of integrated traffic safety strategies.

Code

Below is the NetLogo code implementing the simulation structure (patch definitions, accident logic, congestion metrics, etc.). Users can copy and paste it into a NetLogo environment to run their own experiments. For a complete listing, see the setup, go, and supporting procedures:


globals [ ;; Sliders / Switch in Interface: ;; - number-of-cars (int) ;; - road-spacing (int) ;; - base-speed (float) ;; - driver-error-rate (float) ;; - accident-duration (int) ;; - traffic-lights? (boolean switch) ;; Statistics total-cars-reached-destination total-cars-accident ;; how many cars died in accidents (cumulative) accident-count ;; how many total accidents have started average-speed average-congestion accident-percentage sum-travel-time ;; sum of time in system for all cars that exit count-completed-cars ;; how many cars reached destination average-travel-time ;; output metric accident-count-good accident-count-bad accident-count-very-bad sum-time-until-accident sum-distance-until-accident average-time-until-accident average-distance-until-accident ] patches-own [ is-road? ;; boolean: is this patch part of a road? is-intersection? ;; boolean: is this patch an intersection? lane-direction ;; forced heading: 0, 90, 180, 270, or -1 if intersection traffic-light? ;; does this patch have a traffic light? light-state ;; true=green, false=red has-accident? ;; boolean: accident currently on this patch? accident-lifetime ;; integer: how many ticks remain for this accident? road-condition ;; 0=good, 1=bad, 2=very bad (affects accident prob) ] breed [ cars car ] cars-own [ speed max-speed stopped-ticks destination ;; patch or nobody birth-tick ;; store the tick when the car is created distance-traveled ;; accumulates how far the car has moved ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 1. SETUP ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup clear-all ;; Initialize stats set total-cars-reached-destination 0 set total-cars-accident 0 set accident-count 0 set average-speed 0 set average-congestion 0 set sum-travel-time 0 set count-completed-cars 0 set average-travel-time 0 set accident-count-good 0 set accident-count-bad 0 set accident-count-very-bad 0 set sum-time-until-accident 0 set sum-distance-until-accident 0 set average-time-until-accident 0 set average-distance-until-accident 0 setup-roads setup-intersections setup-traffic-lights setup-road-conditions reset-ticks create-initial-cars end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 2. CREATE ROADS (TWO LANE, ONE-WAY) ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup-roads ask patches [ set is-road? false set is-intersection? false set traffic-light? false set light-state false set has-accident? false set accident-lifetime 0 set lane-direction 0 set road-condition 0 set pcolor green ] ;; 2-lane roads in x or y dimension let road-patches patches with [ (abs pxcor mod road-spacing <= 1) or (abs pycor mod road-spacing <= 1) ] ask road-patches [ set is-road? true set pcolor grey ] ;; Assign forced lane headings for non-intersection road patches ask road-patches [ let x-road? (abs pxcor mod road-spacing <= 1) let y-road? (abs pycor mod road-spacing <= 1) ;; purely vertical lane: pick 0 or 180 if (x-road? and not y-road?) [ ifelse (pxcor mod 2 = 0) [ set lane-direction 0 ] ;; "northbound" [ set lane-direction 180 ] ;; "southbound" ] ;; purely horizontal lane: pick 90 or 270 if (y-road? and not x-road?) [ ifelse (pycor mod 2 = 0) [ set lane-direction 90 ] ;; "eastbound" [ set lane-direction 270 ] ;; "westbound" ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 3. INTERSECTIONS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup-intersections ask patches with [is-road?] [ let x-road? (abs pxcor mod road-spacing <= 1) let y-road? (abs pycor mod road-spacing <= 1) ;; Intersection = patch that is both x-road & y-road if (x-road? and y-road?) [ set is-intersection? true set pcolor yellow set lane-direction -1 ;; means "all directions possible here" ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 4. TRAFFIC LIGHTS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup-traffic-lights if traffic-lights? [ ;; Turn on lights at each intersection ask patches with [is-intersection?] [ set traffic-light? true set light-state true ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 5. ROAD CONDITIONS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup-road-conditions let sum-prob (good-road-probability + bad-road-probability) ask patches with [is-road?] [ let r random-float 1 ifelse (r < good-road-probability) [ ;; (1) "Good" road set road-condition 0 set pcolor grey ] [ ifelse (r < sum-prob) [ ;; (2) "Bad" road set road-condition 1 set pcolor (grey - 2) ;; 5% chance to become "Very Bad" instead: if random-float 1 < 0.05 [ set road-condition 2 set pcolor orange ] ] [ set road-condition 0 set pcolor grey ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 6. CREATE INITIAL CARS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to create-initial-cars ask cars [ die ] ;; remove any old cars let valid-starts patches with [ is-road? and not has-accident? and not any? cars-here ] if not any? valid-starts [ user-message "No valid road patches for car creation!" stop ] create-cars min list number-of-cars (count valid-starts) [ set shape "car" set color blue set size 0.8 ;; pick a random road patch let start-patch one-of valid-starts move-to start-patch set valid-starts valid-starts with [self != start-patch] ;; If this patch is an intersection => pick a direction ifelse ([lane-direction] of patch-here = -1) [ set heading one-of [0 90 180 270] ] [ set heading [lane-direction] of patch-here ] set speed 0 set max-speed base-speed set stopped-ticks 0 set destination nobody set distance-traveled 0 set birth-tick ticks ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 7. GO (MAIN LOOP) ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go if not any? cars [ stop ] update-traffic-lights move-cars check-accidents clear-old-accidents update-statistics tick end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 8. UPDATE TRAFFIC LIGHTS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-traffic-lights if traffic-lights? [ ask patches with [is-intersection? and traffic-light?] [ ;; simple toggle every 30 ticks if (ticks mod 30 = 0) [ set light-state not light-state set pcolor ifelse-value light-state [green] [red] ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 9. MOVE CARS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to move-cars ask cars [ ;; Force lane direction let patch-lane [lane-direction] of patch-here ifelse patch-lane = -1 [ ;; intersection => pick a new direction each tick or once set heading one-of [0 90 180 270] ] [ ;; normal lane => enforce that heading set heading patch-lane ] ;; Decide if it's safe to move let safe-to-move? true ;; Check traffic light if [traffic-light?] of patch-here [ if not ([light-state] of patch-here) [ set safe-to-move? false ] ] ;; Check for cars ahead in same lane if any? cars-on patch-ahead 1 [ set safe-to-move? false ] ;; Move or slow ifelse safe-to-move? [ set speed min (list (speed + 0.1) max-speed) forward speed set distance-traveled distance-traveled + speed set stopped-ticks 0 ] [ set speed max (list (speed - 0.2) 0) set stopped-ticks (stopped-ticks + 1) ] ;; if the car leaves the grid: if not is-patch? patch-here [ set count-completed-cars (count-completed-cars + 1) ;; Add to sum-travel-time: set sum-travel-time (sum-travel-time + (ticks - birth-tick)) ;; Then die die ] if (max-pxcor - abs xcor) < 1 or (max-pycor - abs ycor) < 1 [ set total-cars-reached-destination (total-cars-reached-destination + 1) set count-completed-cars (count-completed-cars + 1) set sum-travel-time (sum-travel-time + (ticks - birth-tick)) die ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 10. ACCIDENT LOGIC (EXPANDED) ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to check-accidents ;; For each car, compute probability of an accident ask cars [ if random-float 1 < calculate-accident-probability self [ create-accident self ] ] end to-report calculate-accident-probability [ c ] ;; Base accident probability from driver error let base (driver-error-rate * 0.00025) ;; Find the patch under turtle c (using c's pxcor, pycor) let p patch ([pxcor] of c) ([pycor] of c) ;; Road condition effect if [road-condition] of p = 1 [ set base (base * 2) ] if [road-condition] of p = 2 [ set base (base * 2.6) ] ;; Speed factor let speed-ratio ([speed] of c / [max-speed] of c) set base (base * (speed-ratio + 0.1)) ;; +0.1 so even slow cars have some chance ;; Congestion effect: how many other cars are within radius 1.5 of c let nearby-cars count cars with [ distance c < 1.5 ] set base (base + (nearby-cars * 0.0005)) ;; Intersection effect if [is-intersection?] of p [ set base (base * 1.5) ] ;; Cap at 1% (0.01) to avoid extreme probabilities report min (list base 0.1) end to create-accident [ c ] set accident-count (accident-count + 1) set total-cars-accident (total-cars-accident + 1) ;; Mark the patch let px ([pxcor] of c) let py ([pycor] of c) ask patch px py [ set has-accident? true set pcolor red set accident-lifetime accident-duration ;; Accidents by Road Condition: if (road-condition = 0) [ set accident-count-good (accident-count-good + 1) ] if (road-condition = 1) [ set accident-count-bad (accident-count-bad + 1) ] if (road-condition = 2) [ set accident-count-very-bad (accident-count-very-bad + 1) ] ] ;; Time & Distance to Accident: let time-until-accident (ticks - [birth-tick] of c) let dist-until-accident ([distance-traveled] of c) set sum-time-until-accident (sum-time-until-accident + time-until-accident) set sum-distance-until-accident (sum-distance-until-accident + dist-until-accident) ;; kill the car ask c [ die ] end to clear-old-accidents ;; Decrement accident-lifetime. When it hits 0, clear the patch. ask patches with [has-accident?] [ set accident-lifetime (accident-lifetime - 1) if (accident-lifetime <= 0) [ set has-accident? false ;; restore color based on road-condition if (road-condition = 0) [ set pcolor grey ] if (road-condition = 1) [ set pcolor (grey - 2) ] if (road-condition = 2) [ set pcolor orange ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 11. STATISTICS & PLOTS ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-statistics let car-count count cars let total-speed 0 if car-count > 0 [ set total-speed sum [speed] of cars set average-speed (total-speed / car-count) ] if car-count = 0 [ set average-speed 0 ] set average-congestion count cars with [ (stopped-ticks >= 2) and (any? cars-on patch-ahead 1) ] if number-of-cars > 0 [ set accident-percentage ((accident-count / number-of-cars) * 100) ] ;;Average travel time for cars that completed trip if count-completed-cars > 0 [ set average-travel-time (sum-travel-time / count-completed-cars) ] ;;Averages for time & distance until accident if accident-count > 0 [ set average-time-until-accident (sum-time-until-accident / accident-count) set average-distance-until-accident (sum-distance-until-accident / accident-count) ] ;; Plot them carefully [ set-current-plot "Average Speed" plot average-speed set-current-plot "Total Accidents" plot accident-count set-current-plot "Average Congestion" plot average-congestion ] [] end

References

Sadauskas, V. (2011). Traffic safety strategies, Transport, 18(2), 79–83. DOI: 10.1080/16483840.2003.10414070 
Gstalter, H., & Fastenmeier, W. (2010). Reliability of drivers in urban intersections. Accident Analysis & Prevention, 42(1), 225–234. Link 
TSK Praha (2020). Ročenka dopravy – 2020. Link 
Nordfjærn, T., Jørgensen, S., & Rundmo, T. (2011). A cross-cultural comparison of road traffic risk perceptions, attitudes towards traffic safety, and driver behaviour. Journal of Risk Research, 14(6), 657–684. Link 
Fanny Malin (2017). Accident risks in different weather conditions. Link