SWITCH mobility

SWITCH mobility preview image

1 collaborator

Default-person Carole Adam (Author)

Tags

human mobility 

Tagged by Carole Adam 9 days ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.2.2 • Viewed 47 times • Downloaded 1 time • Run 0 times
Download the 'SWITCH mobility' modelDownload this modelEmbed this model

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


WHAT IS IT?

In this model, citizens of a virtual town can choose their mobility mode among 4 options: car, bike, bus, or walk. The urban management of the town defines values of each mode on 6 criterias: ecology, comfort, safety, trip duration, trip cost, and practicality. Citizens have individual preferences for these criteria, as well as individual constraints (distance, accessibility). Citizens can choose between accessible mobility modes either rationally, or by habit, or under the influence of perception biases. The urban management can be modified dynamically to observe the impact on modal choice distribution.

QUICK START GUIDE

1) Press SETUP to automatically initialise the town (urban values of the 4 modes on the 6 criterias) and the population. 2) Citizens appear on the map. Green cyclists, yellow pedestrians, red motorists, blue bus passengers. Their distance to the centre reflects their home-work distance; the 3 circles represent walking distance, cycling distance, maximal distance. The 4 sectors reflect their access to car / bus. 3) Press LOOP or STEP to run the simulation (infinite loop or one step) 4) In the "human factors" panel, choose if citizens are influenced by habits and/or biases. 5) In the "urban planning" panel, you can act on the town infrastructure by changing the value of any mode on any criterion (for instance increase the cost of car, or the safety of bike). You can also communicate to modify the priority of any criterion in the population. 6) Get feedback. The POLL button prints a report in the output panel. The map can show citizens with their choosen mode, and halo per decision type (see legend). The buttons PRIOS and VALS display histograms (must pause simulation first). 7) Observe the plots on the right: modal distribution in % of total population, happiness per usual mode, and types of decisions (habits, biases, constraint).

HOW IT WORKS

Rational decision is based on a multicriteria evaluation of each mode (weighed average of the mode evaluations on all 6 criteria, weighed by the individual priority for each criterion). The rational choice is the mobility mode that has the best global mark (whether that mark is biased or not). Two constraints are considered: home-work distance (that might exclude walk or bike), and access to a car or a bus stop (that is necessary to use these modes).

Two switches allow to (des)activate two kinds of human factors influencing the decision process, conducing to 4 kinds of decisions: * RATIONAL: the citizen computes scores of the 4 modes based on the objective mode evaluations (determined by the environment and infrastructure) and chooses the mode with the best score. * CONSTRAINED: if the best mode is not accessible, the agent falls back on the next best choice. * HABITS: citizens also remember a list of the modes used during their past trips, and compute their frequency, to deduce strength of habits. These are used as a probability to re-use the same mode in the future, before evaluating and comparing the modes. * BIASES: citizens apply a perception filter on the objective values of modes provided by the environment to obtain subjective values: they over-estimate the qualities of their mode and under-estimate its drawbacks, and reversely for the other modes. The strength of the filter increases with habits. They choose the mode with the best subjective score.

HOW TO USE IT

Possible interactions: * Urban management: for each mode (drop down menu selection) and each criteria (drop down menu selection), the current value (in %) is displayed and can be adjusted. Not all adjustments make sense, so choose wisely. * Communication / advertisement: the selected criteria (dropdown menu) will show its current average priority in the population, which can be adjusted. * A menu allows to choose a decision type to visualise citizens making this type of decision (white halo around them in map) and their count (monitor next to selector). * POLL button allows to get a report about the selected mode and criterion in the output panel. * PRIOS and VALS buttons show histograms of priorities and values (must pause simulation first).

Main map: * The agents are shown with the shape and color indicating their mobility mode, and a white halo for the type of decision (if concerned). * Switches allow to show/hide users of each mode. * Their distance to the centre reflects their home-work distance. * The map is divided in 4 quadrants, labelled with the corresponding constraint: access to car, bus, both, none. * Concentric circles materialise the distance that can be travelled by foot (inner circle, 5km), by bicycle (15km), and the maximal distance (outer circle). Citizens who live further must travel either by car or by bus.

Decision types. A menu allows to select a decision type and visualise on the map (a white halo around) citizens who chose their mode based on: * biases (their subjective decision differs from the objective best choice) * habits (did not evaluate modes before using same as usual) * bad habits (their habitual mode is reconducted despite not being best anymore) * constraint (best rational choice not available) * Revert to "neutral" to remove all halos.

Histograms (must pause simulation to observe): * Average subjective values of each mode on each criteria in the current urban setting. * Average priorities of each criteria among users of each mode.

Outputs plots: * Mobility distribution shows how many citizens use each mobility mode * Happiness plot: average satisfaction of users of each mobility mode * Decisions: percentage of users activating habits or perception biases, to choose a mode that is not the best one objectively, or being prevented to use the best mode by distance or accessibility constraints (see decision types above)

THINGS TO NOTICE

Without biases or habits, citizens will rationally update their scores and their mobility when the urban setting or their priorities change. If their rational score decreases, they might find a backup mode that has become better than the current one. On the contrary, with habits and/or bias activated, inertia appears in the modal distribution as users 'stick' to their usual mode. Either they re-use it without new evaluation (habit) or they filter their perception so that it keeps the best (subjective) score. This reduces their cognitive load and dissonance.

Regarding the deviation between users' scores and non-users' scores of a mode. These 2 marks can differ because users of different modes have different priorities, or because of the perception biases. - without biases: users are those who prefer this mode, but their score only slightly differs. Indeed, all citizens use the same evaluation (real values) and only differ in their priorities. - with biases but with habits: some users might use a mode out of habit despite not liking it, which decreases the users' score. The difference is low, sometimes negative. With time, biases can raise the evaluation of the mode (choice supportive bias). - with biases and no habits: the maximal difference is observed. Biases push users to widely over-estimate their mode, and others to under-estimate it, and no habit interferes with the choice. - remark: the less users of a mode there is, the more variable the mean score is, since each gained or lost user is more significative.

When you update the urban infrastructure to favour soft mobility, observe who switches first, depending on accessibility of car/bus, and on home-work distance. Visualise constrained decisions: are some citizens prevented from switching while they would want to?

THINGS TO TRY

Remark: if you start the simulation with habits and biases activated, and do no change in the urban planning, then the modal distribution stays stable. Visualise biased agents with a halo: if no modification is made, no agent is biased; the bias only modifies the perception of the changes made to the initial situation.

Scenario 1: start the simulation and progressively increase the priority of ecology in the population. Observe how the satisfaction and number of car drivers evolves over time. Scenario 2: start the simulation and progressively decrease practicality or comfort for cars (for instance less parking spots). How does the distribution of citizens on the different modes evolve? What about the average satisfaction of car drivers?

Compare the dynamics when enabling/disabling habits, and when enabling/disabling perception bias. Try resetting habits after a change in urban planning that did not have the expected effect, to see what happens.

Progressively improve the comfort and safety of bicycle and observe the geographical distribution of users: who switches to use the bicycle? Which mode did they use before? How far is their home-work distance? Visualise a halo around constrained decisions: what do you notice?

EXTENSIONS

Several extensions are possible from this basic model: - Add a budget for the player. Better infrastructures will be more costly to maintain, or will degrade with time. - Add concrete actions that connect to the values and/or priorities of criteria (build cycling lanes, communicate about road safety, speed controls by police, pedestrian zones, new parking taxes, etc) - Add other possibilities: create new bus lines that will make bus accessible to new citizens; move citizens closer/further to their work; forbid cars... Such actions will change the list of accessible modes for some citizens. - Add more information in the polls

RELATED MODELS

SWITCH simulators in French: https://nausikaa.net/index.php/switch-simuler-la-mobilite/

SWITCH simulators in English: https://nausikaa.net/index.php/switch-simulating-mobility/

CREDITS AND REFERENCES

ANR SWITCH: https://sites.google.com/site/caroleadamphd/projects/switch

Data used in the model: Adam, Carole, 2024, "Answers to a survey about perceptions of mobility", https://doi.org/10.57745/ELLXJF, Recherche Data Gouv, V1, UNF:6:bt0F6ogDcyk99+aUrD0GnQ==

(C) Carole ADAM - ANR SWITCH project - April-June 2024 - https://nausikaa.net/

Comments and Questions

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

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                                                                  ;;
;; SWITCH - BIASed MODAL CHOICE SIMULATOR                                                           ;;
;; Carole Adam - March 2023 + April-May-June 2024                                                   ;;
;; Population calibrated from survey results, including perception biases                           ;;
;; Goal: show impact of urban planning on modal distribution, with and without habits and biases    ;;
;; v2 - debug display                                                                               ;;
;;                                                                                                  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;
;;   SPECIES   ;;
;;;;;;;;;;;;;;;;;

;; global variables
globals [
  ; indexes for accessing each mobility mode
  index-car
  index-bike
  index-bus
  index-walk
  mobilities   ; list of modes names in order

  ;; indexes for accessing each criteria
  index-ecolo
  index-comfort
  index-safe
  index-time
  index-price
  index-easy
  criterias   ; list of criterias names in order

  ; list of numbers of users per mobility
  number-users
  ;; list of values of each mode on each criteria - in the current urban planning of the city
  notes-modes

  ; list of filters per mode
  filtres-modes

  ; managing habits
  nb-trips-stored    ; how many trips remembered by each agent
]

;; citizens agents making up the population of the town
breed [ citizens citizen ]

citizens-own [
  dist-hw             ; home work distance
  accessibles         ; vector of booleans

  ; choosen mobility and its note
  mobility            ; current mobility, reflected in shape and color
  note-mobilite       ; satisfaction with current mobility

  ; individual priorities and scores
  objective-scores    ; list: mode scores computed from objective perceptions
  subjective-scores   ; list: mode scores computed from biased perceptions
  priorities          ; list: priorities of all 6 criterias

  ; habits management
  trips-list       ; list of last X trips to compute habits
  habits-list      ; list of frequencies associated to each mode in trips-list

  ; tracking type of decision
  trigger-habits?     ; true if decision by habit, false if decision based on rational score
  trigger-bias?       ; did the bias modify the choosen mode?
  trigger-constraint? ; did constraints prevent from making best choice?

  ; list of lists:
  deviations      ; deviations factors of evaluations of modes on criterias
  evaluations     ; biased evaluations
]


;;;;;;;;;;;;;;;;;;;;;;;;;;
;;    INITIALISATION    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;

; SETUP button in the interface: initialises the simulator

to setup
  clear-all

  ; initialise indexes for modes and criterias
  setup-indexes
  set nb-trips-stored 100

  ;; initial values of criterias for each mode in the initial urban setting
  set-urban-survey

  ; initialise population with their individual priorities for criterias
  setup-population

  ; legend in the grid
  setup-patches

  ; visu switches
  set see-bikes? true
  set see-cars? true
  set see-bus? true
  set see-walk? true

  reset-ticks
  help
end 

to setup-patches
  ask patches [set pcolor black set plabel ""]
  ;ask patches with [pxcor = 0 or pycor = 0] [set pcolor (black + 2) ]
  ask patch (max-pxcor - 1) max-pycor [set plabel "car & bus"]
  ask patch (max-pxcor - 1) (min-pycor + 1) [set plabel "car & no bus"]
  ask patch (min-pxcor + 6) (min-pycor + 1) [set plabel "no car & no bus"]
  ask patch (min-pxcor + 5) max-pycor [set plabel "no car & bus"]
  ask patches [set plabel-color (black + 4)]

  draw-circles
  draw-cadrans
end 


; initialise indexes for modes and criterias
; used to access elements in lists

to setup-indexes
  set index-car 0
  set index-bike 1
  set index-bus 2
  set index-walk 3
  set mobilities (list "car" "bike" "bus" "walk")

  set index-ecolo 0
  set index-comfort 1
  set index-safe 2
  set index-time 3
  set index-price 4
  set index-easy 5
  set criterias (list "ecology" "comfort" "safety" "time" "price" "praticity")
end 




;;;;;;;;;;;;; CREATE ENVIRONMENT  ;;;;;;;;;;;;;;;;;;;

;; MODES EVALUATION in INITIAL URBAN SETTING

to set-urban-survey
  ;; car bike bus walk
  ; init population with French statistics on modal distribution
  set number-users (list 76 2 16 6)
  ; stats on our survey sample of 650: (list 134 204 228 84)

  ;; NOTES MEDIAN USERS OF THE MODE
  ;let notes-bus (list 80.0 70.0 80.0 70.0 75.0 70.0)
  ;let notes-walk (list 100.0 80.0 80.0 50.0 100.0 85.0)
  ;let notes-bike (list 100.0 70.0 50.0 80.0 90.0 80.0)
  ;let notes-car (list 20.0 90.0 80.0 90.0 40.0 90.0)

  ;; NOTES MEDIAN ALL
  ; (list "ecology" "comfort" "safety" "time" "price" "praticity")
  ;let notes-bike (list 100.0 60.0 50.0 70.0 80.0 70.0)
  ;let notes-car (list 20.0 80.0 80.0 70.0 20.0 70.0)
  ;let notes-bus (list 80.0 60.0 80.0 60.0 70.0 60.0)
  ;let notes-walk (list 100.0 70.0 70.0 30.0 100.0 60.0)
  ;set notes-modes (list notes-car notes-bike notes-bus notes-walk)

  ;; MEDIANS REDRESSEES sur STATS FRANCAISES
  set notes-modes (list (list 18.8 85.8 76.2 83.2 34.4 82.4 ) (list 97.4 52.2 34.2 50.9 78.6 52.4 ) (list 70.5 53.0 71.0 46.0 69.4 46.2 ) (list 98.0 61.8 69.4 23.0 98.0 52.9 ) )

  ;; FILTERS - mean values of deviation over users of each mode
  let filtre-bike (list (list 0.68 0.93 0.94 0.87 1.17 0.77) (list 0.96 1.23 1.08 1.14 1.07 1.18) (list 0.91 0.92 0.97 0.82 0.92 0.84) (list 0.99 1.0 1.03 0.88 0.99 0.97) )
  let filtre-car (list (list 1.26 1.06 0.96 1.17 1.92 1.19) (list 0.88 0.83 0.66 0.62 0.89 0.7) (list 0.88 0.86 0.89 0.67 0.98 0.67) (list 0.96 0.87 0.86 0.76 0.96 0.88) )
  let filtre-bus (list (list 0.93 0.95 0.87 0.94 1.22 0.89) (list 0.93 0.89 0.93 0.92 0.93 0.88) (list 0.97 1.08 0.92 1.13 1.04 1.2) (list 0.98 0.9 0.95 0.99 0.97 0.97) )
  let filtre-walk (list (list 0.84 0.91 0.89 0.92 1.15 0.82) (list 0.87 1.05 0.96 1.03 0.93 0.98) (list 0.93 1.0 0.93 1.06 0.98 1.08) (list 0.97 1.16 1.02 1.65 0.98 1.34) )
  set filtres-modes (list filtre-car filtre-bike filtre-bus filtre-walk)
end 


;;;;;;;;;;;;;;;; CREATE POPULATION ;;;;;;;;;;;;;;;;;;;;;;;;;

;; init population from survey results

to setup-population
  foreach mobilities [m ->
    let im (position m mobilities)
    create-citizens 2 * (item im number-users) [
      init-citizen
      init-mobility m
      init-position
    ]
  ]
end 

; initialise a citizen - general settings

to init-citizen
  move-to one-of patches with [ not any? turtles-here ]
  set mobility ""
  set size 1.5
  ; lists of notes and priorities: full of 0 for now
  set objective-scores n-values (length mobilities) [0]
  set subjective-scores n-values (length mobilities) [0]
  set priorities n-values (length criterias) [0]
  ; habits - empty history initially
  set trips-list []
  ; initial frequency 0 for all modes
  set habits-list n-values (length mobilities) [0]
  ; decision trackers
  set trigger-habits? false
  set trigger-bias? false
  set trigger-constraint? false
end 

to init-mobility [m]
  switch-to m
  set-random-distance m
  set-random-access m
  set trips-list n-values nb-trips-stored [m]
  set-mob-prios-survey m
  set evaluations notes-modes
  bias-evaluation
  ;; initialise evaluations of modes
  eval-mobility
end 

to init-position
  ; position
  move-to patch 0 0
  face patch max-pxcor 0
  ; angle based on available mobilities
  let has-bus? item index-mode "bus" accessibles
  let has-car? item index-mode "car" accessibles
  (ifelse
    (has-bus? and has-car?)  [lt (5 + random 80)]
    has-bus? and not has-car? [lt (95 + random 80)]
    not has-bus? and has-car? [rt (5 + random 80)]
    not has-bus? and not has-car? [rt (95 + random 80)]
  )
  ; distance to center reflects home-work distance
  fd visual-distance dist-hw
end 

; logarithmic visualisation of home-work distance in concentric circles

to-report visual-distance [d]
  report 7 * (log (d + 1) 5) + 0.3
end 

;; random home-work distance for this mode, from survey
;; obtained with statsDistMode(lir,kstats)

to set-random-distance [qm]
  (ifelse
    qm = "bike" [set dist-hw bounded-gaussian 6.43 6.67 1 50]
    qm = "car"  [set dist-hw bounded-gaussian 21.29 23.1 2 190]
    qm = "bus"  [set dist-hw bounded-gaussian 11.16 13.59 1 95]
    qm = "walk" [set dist-hw bounded-gaussian 1.8 1.44 0.2 9]
  )
end 

;; random accessibility of modes, from survey results

to set-random-access [qm]
  set accessibles n-values length mobilities [false]
  ; car and bus access: from statistics over the groups of users of this mode in survey
  (ifelse
    qm = "bike" [
      set-access "car" (random-float 100 > 29.9)
      set-access "bus" (random-float 100 > 10.29)
    ]
    qm = "car"  [
      set-access "car" true
      set-access "bus" (random-float 100 > 61.19)
    ]
    qm = "bus"  [
      set-access "car" (random-float 100 > 57.46)
      set-access "bus" true
    ]
    qm = "walk" [
      set-access "car" (random-float 100 > 50)
      set-access "bus" (random-float 100 > 8.33)
    ]
  )
  ; empirical max distance to walk / cycle
  ; current mob is accessible: some outliers will cycle / walk further than average
  set-access "bike" (qm = "bike" or dist-hw <= 15)
  set-access "walk" (qm = "walk" or dist-hw <= 5)
end 

; shortcut to replace a boolean qb as accessibility of mode qm

to set-access [qm qb]
  set accessibles replace-item (index-mode qm) accessibles qb
end 

; priority profile per mode, obtained from survey

to set-mob-prios-survey [mob]
  ;; priorities from survey - average over users of each mode
  ;; criterias: (list "ecology" "comfort" "safety" "time" "price" "praticity")
  (ifelse
    mob = "car" [set priorities (list 56.5 71.9 67.2 77.9 56.3 85.7)]
    mob = "bus" [set priorities (list 67.6 67.5 64.6 73.7 74.4 78.1)]
    mob = "bike" [set priorities (list 83.0 73.1 53.7 76.8 70.8 85.4)]
    mob = "walk" [set priorities (list 72.7 73.5 66.7 67.0 75.8 84.2)]
  )
  ; deviations for the current mode
  set deviations item (index-mode mob) filtres-modes
  ; random priority variation for some random heterogeneity
  foreach criterias [ crit -> factor-prio crit (1 - random-float 0.2 + random-float 0.2)]
end 




;;;;;;;;;;;;;;;;;;;;;;;;;
;;   SIMULATION LOOP   ;;
;;;;;;;;;;;;;;;;;;;;;;;;;

;; main loop

to go
  ; citizens decision
  ask citizens [
    ; compute habits strengths from trip list
    compute-habits
    ; several situations
    choose-mobility
    ; enact change and update mobility score
    switch-to mobility
  ]
  ; visualisation of citizens based on 4 switches - removes histograms
  update-map
  ; next step
  tick
end 

; visualisation of citizens based on 4 switches: each mode can be shown/hidden

to update-map
  ; background
  setup-patches
  ; citizens
  ask citizens with [mobility = "bike"][set hidden? not see-bikes?]
  ask citizens with [mobility = "car"][set hidden? not see-cars?]
  ask citizens with [mobility = "bus"][set hidden? not see-bus?]
  ask citizens with [mobility = "walk"][set hidden? not see-walk?]
end 



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MOBILITY EVALUATION and CHOICE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; ------- BIASES ------- ;;;

; 1) adapt filter according to habits
; compute individual filter as a weighed average between neutral (no habit: no deviation, factor = 1)
;   and full filter (strong habit: full deviation)

to compute-individual-filter
  let im index-mode mobility
  let mode-filter item im filtres-modes    ; list of lists of floats 0-1
  let coeff item im habits-list            ; between 0 and 100%
  foreach range length mobilities [qm ->
    foreach range length criterias [qc ->
      let val100 item qc (item qm mode-filter)
      ;; average weighed by habit
      let val (coeff * val100 + (100 - coeff) * 1) / 100
      set deviations (set-value deviations qm qc val)
    ]
  ]
end 

;; 2) biased evaluations: apply personal perception filter

to bias-evaluation
  ; individual filter depends on habit strength of usual mode
  compute-individual-filter
  ; perceive urban values in the environment
  set evaluations notes-modes
  ; then bias them: apply multiplying factors to real notes-modes observed
  foreach mobilities [mob ->
    let im index-mode mob
    ; list of 6 values of this mode on criterias
    let vals item im evaluations
    foreach criterias [crit ->
      let ic index-criteria crit
      ; objective value
      let obj item ic vals
      ; multiplying factor
      let fact item ic (item im deviations)
      ; subjective value
      let subj precision (min (list 100 (obj * fact))) 1
      set vals replace-item ic vals subj
    ]
    set evaluations replace-item im evaluations vals
  ]
end 

;; 3) compute rational mark as weighed average
;; a citizen recomputes the rational marks of the 4 modes
;; based on his priorities and his evaluation vector

to eval-mobility
  ; if objective switch is on subjective: bias perceptions, else keep environment values
  ifelse subjective? [bias-evaluation][set evaluations notes-modes]
  ; compute and store the objective and subjective scores of mobilities
  foreach mobilities [ mob ->
    ; objective scores are computed based on real environment values = notes-modes
    set objective-scores replace-item (index-mode mob) objective-scores (multicrit-eval priorities (item index-mode mob notes-modes))
    ; subjective scores are computed based on biased modes values = evaluations (set by bias-evaluation)
    ; subjective scores are actually objective if subjective? switch is off (since no filter biases the evaluations used to compute the score)
    set subjective-scores replace-item (index-mode mob) subjective-scores (multicrit-eval priorities (item index-mode mob evaluations))
  ]
  ;; constraints are static, determined at init
  ;; for inaccessible modes: replace subjective score with -1 so it is not considered in decision
  foreach (n-values length mobilities [i -> i]) [im ->
    if not (item im accessibles) [set subjective-scores replace-item im subjective-scores -1]
  ]
end 


;;; ------- MOBILITY CHOICE - HABITS or RATIONAL ------- ;;;

to choose-mobility
  (ifelse
    ; random context change from time to time (roadwork, strike...) to force some variation
    random 100 < 1 [
      set subjective-scores (replace-item (index-mode mobility) subjective-scores 0)
      set mobility random-max-mode subjective-scores
    ]
    random 1000 < 5 [
      ; reset habits
      set trips-list (list)
    ]
    ; if habits triggered
    trigger-habits? [
      ;; habits: choose most used mobility (with probability = frequency in the past)
      set mobility random-max-mode habits-list
    ]
    ; otherwise, choose rationally
    [
      ; mobility evaluation: computes objective and subjective scores based on biased/real values of modes on criteria
      eval-mobility                                     ; compute mode scores, obj and subj
      set mobility random-max-mode subjective-scores    ; choose subjectively
      ; check if the choice is constrained (by distance or access to car/bus)
      let best random-max-mode objective-scores         ; compare with objective best choice
      set trigger-constraint? (item (index-mode best) subjective-scores = -1)  ; subjective score set to -1 in eval-mobility if mode is inaccessible
      ; if the choice is not optimal, but not habitual nor constrained, then it is biased
      set trigger-bias? (mobility != best and not trigger-habits? and not trigger-constraint?)     ; if they differ: the choice is biased
    ]
  )
end 



;;; ------- MULTICRITERIA SCORING ALGORITHM ------- ;;;

;; compute note as product of list of (potentially biased) priorities * list of values

to-report multicrit-eval [list-prios list-values]
  let som sum (map [i -> (item i list-prios) * (item i list-values)] (n-values (length list-values) [i -> i]) )
  ;; divide by the sum of prios
  let nb sum list-prios
  report ifelse-value nb > 0 [som / nb] [0]
end 



;;; ------- HABITS ------- ;;;

;; 4) Manage habits of one citizen

to compute-habits
  ; store mobility in list of trips - max nb-trips-stored (remove oldest if needed)
  set trips-list lput mobility trips-list
  if length trips-list > nb-trips-stored [set trips-list remove-item 0 trips-list]

  ; enough trips stored: compute habits
  if length trips-list >= nb-trips-stored [
    foreach mobilities [mob ->
      ; count this mode in past window
      let nb-trips length filter [i -> i = mob] trips-list
      ; compute frequency and store it as habit strength
      let mode-freq 100 * nb-trips / length trips-list
      let im index-mode mob
      set habits-list replace-item im habits-list mode-freq
    ]
  ]
  ; the agent triggers habit-decision based on proba of its own habit strength (some agents have stronger habits)
  ; and on the frequency of the usual mode (higher frequency = more chance to repeat)
  set trigger-habits? (25 + random 75 < max habits-list)

  ; if GUI switch is off, 'untrigger' habits for the citizen
  if not habits? [set trigger-habits? false]
end 


;;; ------- MODE SWITCH ------- ;;;

; 5) enact change of mode
; actually change an agent's mobility mode
; and reflect it on its speed, + shape and color on map

to switch-to [qm]
  set mobility qm
  set note-mobilite (item (index-mode qm) subjective-scores)
  ; shape depends on mobility + halo based on which decision mode is selected for visu in GUI menu
  set shape shape-mode mobility
  ;ifelse shape = "bike" [set size 2] [set size 1]
  ; color just depends on mode (car:red, bus:blue, bike:green, walk:yellow)
  set color color-mode mobility
end 




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; INTERFACE BUTTONS         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; BUTTON - display help message in output panel. Called at init + Available anytime through the HELP button

to help
  clear-output
  output-print "Welcome to SWITCH mobility simulator"
  output-print "See INFO panel for quick start guide"
  output-print "INIT to create the population"
  output-print "Then run as LOOP or STEP by step"
  output-print "MAP shows citizens with mode as shape and color"
  output-print "LEGEND: yellow = pedestrians, green = cyclists,"
  output-print "        blue = bus, red = car"
  output-print "Modify urban planning and observe new modal distribution"
end 

;; BUTTON - reset habits of all agents

to reset-habits
  ;; effacer les habitudes de tout le monde
  ask citizens [
    set trips-list []
    set habits-list n-values (length mobilities) [0]
    set trigger-habits? false
  ]
end 

; BUTTON - to display a written report about selected mode and criterion

to poll
  clear-output
  output-print (word "Poll at time " ticks)
  output-print (word "Mean " which-criteria " of " which-mode " = " current-value " %")
  output-print (word "Mean priority of " which-criteria " = " (precision current-prio 1) " %")
  output-print (word "Mean score of " which-mode " = " mean-users-note which-mode " (users) vs " mean-notusers-note which-mode " (non-u)")

  ;; type of decision
  let tt count-decisions-mode which-mode "all"
  let tb count-decisions-mode which-mode "bias"
  let tc count-decisions-mode which-mode "constraint"
  let th count-decisions-mode which-mode "habit"
  output-print (word tt " citizens use " which-mode " : ")
  output-print (word "   " tb " are biased ; " tc " are constrained ; " th " by habit.")
end 



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;        URBAN PLANNING       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; INCREASE or DECREASE values of MODES on CRITERIAS
;; im index of a mode
;; ic index of a criteria
;; delta value to add to the current value

to change-value [im ic delta]
  ; get current value of this mode on this criteria
  let old item ic (item im notes-modes)
  ; compute and bound new value
  let new (old + delta)
  set new min (list 100 new)
  set new max (list 0 new)
  ; actually replace current value with new value in the list
  let notes-one-mode (item im notes-modes)
  set notes-one-mode (replace-item ic notes-one-mode new)
  set notes-modes (replace-item im notes-modes notes-one-mode)
end 

;; button "++" : increase value by 5
;; button "--" : decrease value by 5
;; REMARK: not all changes make sense, for instance no urban planning can make cars fully ecological, or walking super fast...


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; POPULATION PRIORITIES   ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; buttons in interface (communication campaigns to change priorities)
;; change priority of currently selected criteria for all the population

to change-prio [delta]
  ask citizens [
    ; index of the criteria (selected as text)
    let ic index-criteria which-criteria
    ; old value of priority of the criteria
    let ov (item ic priorities)
    ; new value: add delta and bound 0-100
    let nv round (ov + delta)
    set nv min (list 100 nv)
    set nv max (list 0 nv)
    ; change priority of the selected criteria, to the new value
    set priorities replace-item ic priorities nv
  ]
end 

;; button "++" : increase value by 5
;; button "--" : decrease value by 5
;; REMARK: no communication campaign is that efficient in reality



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;         ACCESSORS         ;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; set value of a mode on a criteria to a given value
; qm index of a mode, can be obtained from name, ex: index-mode "bus"
; qc index of a criteria, can be obtained from name, ex: index-criteria "ecology"
; qv new value of this mode on this criteria

to-report set-value [li qm qc qv]
  ;; bound value between 0 and 100
  set qv min (list 100 qv)
  set qv max (list 0 qv)
  ; replace value of that criteria in the global list of notes
  set li (replace-item qm li (replace-item qc (item qm li) qv))
  report li
end 

; modify score of one mode

to-report set-score [scores qm qv]
  set scores replace-item (index-mode qm) scores qv
  report scores
end 

; set priority for current citizen of a (text) criteria to
; its old value multiplied by a factor ; value will stay bounded 0-100

to factor-prio [qc qf]
  let ic index-criteria qc
  let ov item ic priorities
  let nv min (list 100 round (ov * qf))
  set priorities (replace-item ic priorities nv)
end 

; all positions of a value in a list

to-report positions [qv qli]
  let index-list range length qli
  let position-list (map [ [list-item index] -> ifelse-value qv = list-item [index][FALSE] ] qli index-list)
  report filter [index -> index != false] position-list
end 

;; one random mobility with max score in score list received (in case of equal scores of more than 1 mode)
;; called with list of scores or list of frequencies

to-report random-max-mode [liste]
  let maxi max liste
  let poslist positions maxi liste
  let rmm (one-of map [i -> (item i mobilities)] poslist)
  report rmm
end 

; index of a mode given as a string ("car", "bike", etc)

to-report index-mode [qm]
  (ifelse
    qm = "car" [report index-car]
    qm = "bike" [report index-bike]
    qm = "bus" [report index-bus]
    qm = "walk" [report index-walk]
    )
end 

to-report has-access? [qm]
  report item (index-mode qm) accessibles
end 

; index of a criteria, given as a string ("ecology, "price", etc)

to-report index-criteria [wc]
  (ifelse
    member? "ecolo" wc [report index-ecolo]
    member? "price" wc [report index-price]
    member? "safe" wc [report index-safe]
    member? "comfort" wc [report index-comfort]
    member? "pratic" wc [report index-easy]
    member? "time" wc [report index-time]
    [show wc show "error unknown criteria !!!"]
  )
end 

;; INITIALISE RANDOM GAUSSIAN
;; bounded gaussian for initialising attributes

to-report bounded-gaussian [avg dev bas haut]
  let v random-normal avg dev
  if v < bas [set v bas]
  if v > haut [set v haut]
  report v
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; HISTOGRAM VISUALISATION ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; visualise histogram of priorities

to visu-prio
  ask patches [set plabel ""]
  ask turtles [ht]
  show-legend "PRIORITIES"
  let i -15
  let j -15
  let c 0
  ; one histogram per mobility
  foreach mobilities [mob ->
    ; the list could be empty if nobody has this mobility
    ifelse any? citizens with [mobility = mob] [   ; cpt > 0 [
      let ql n-values (length criterias) [ic -> mean [(item ic priorities)] of citizens with [mobility = mob]]
      show-histog i j ql mob
    ]
    [
      ; bottom label with mobility and number of users
      ask patch (i + 3) j [set plabel (word mob " : 0")]
    ]
    (ifelse
      c = 0 [set c (c + 1) set j (j + 19)]
      c = 1 [set c (c + 1) set i (i + 21)]
      c = 2 [set c (c + 1) set j (j - 19)]
    )
  ]
end 

; visualise histogram of values of modes on criterias

to visu-values
  ask patches [set plabel ""]
  ask turtles [ht]
  show-legend "VALUES"
  let i -15
  let j -15
  let c 0
  ; one histogram per mobility
  foreach mobilities [mob ->
    let ql n-values (length criterias) [ic -> item ic (item (index-mode mob) notes-modes)]
    show-histog i j ql mob

    ; add a bar for the average value + associated legend
    show-bar (mean ql) (i + 6) j gray
    ask patch 0 -3 [set pcolor gray]
    ask patch -1 -3 [set plabel "average"]

    (ifelse
      c = 0 [set c (c + 1) set j (j + 19)]
      c = 1 [set c (c + 1) set i (i + 21)]
      c = 2 [set c (c + 1) set j (j - 19)]
    )
  ]
end 

;; central legend of histograms

to show-legend [title]
  ask patch 1 4 [set plabel title]
  foreach n-values (length criterias) [i -> i] [ic ->
    let crit item ic criterias
    ask patch 0 (3 - ic) [set pcolor color-criteria crit]
    ask patch -1 (3 - ic) [set plabel crit]
  ]
end 

;; histogram for one given mobility
;; qx and qy coordinates of starting patch
;; ql the list to visualise as histogram
;; qm the mobility (for legend)

to show-histog [qx qy ql qm]
  ; bottom label with mobility and number of users
  let cpt count citizens with [mobility = qm]
  ask patch (qx + 3) qy [set plabel (word qm " : " cpt)]
  ;; show values in list ql as vertical bars
  ;; the first bar starts in patch qx qy
  foreach n-values (length ql) [i -> i] [ic ->
     show-bar (item ic ql) (qx + ic) qy (color-criteria item ic criterias)
  ]
end 

; show one vertical bar
; qx * qy : starting position
; val : value defining height of bar
; qcol : color of bar

to show-bar [val qx qy qcol]
  ; number of patches that turn into the color associated with this criteria
  ask min-n-of round (val / 10) (patches with [pxcor = qx and pycor > qy]) [pycor - qy] [set pcolor qcol]
  ; the top patch also shows the numerical value, rounded
  ask patch (qx) (qy + round (val / 10) + 1) [set plabel round val]
end 

;; associate a color to each criteria (used for legend and histograms)

to-report color-criteria [qc]
  (ifelse
    qc = "ecology" [report green]
    qc = "price"   [report orange + 1]
    qc = "safety"  [report magenta]
    qc = "time"    [report yellow - 1]
    qc = "comfort" [report sky - 1]
    qc = "praticity" [report cyan - 1]
    [report grey]
    )
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; REPORTERS - REPORTERS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; MONITORS

; for monitor in GUI, based on selectors in GUI for mode and criteria
; current value in the urban setting of this mode on this criteria

to-report current-value
  let im index-mode which-mode
  let ic index-criteria which-criteria
  report (item ic (item im notes-modes))
end 

; for monitor in GUI, based on selectors (mode + criteria)
; current average priority of this criteria in population

to-report current-prio
  if count citizens = 0 [report 0]
  report mean [item (index-criteria which-criteria) priorities] of citizens
end 


;; AVERAGE MARKS - COMPARATIVE monitors

;; average mark of a mode, for the users of this mode

to-report mean-users-note [qm]
  if count citizens with [mobility = qm] = 0 [report 0]
  ;let moy mean [item (index-mode qm) subjective-scores] of citizens with [mobility = qm]
  let moy mean [note-mobilite] of citizens with [mobility = qm]
  report precision moy 2
end 

; average mark of non users of a mode

to-report mean-notusers-note [qm]
  if count citizens with [mobility != qm] = 0 [report 0]
  let moy mean [item (index-mode qm) subjective-scores] of citizens with [mobility != qm]
  report precision moy 2
end 

to-report mean-all-note [qm]
  if count citizens with [mobility != qm] = 0 [report 0]
  let moy mean [item (index-mode qm) subjective-scores] of citizens
  report precision moy 2
end 

; MONITOR - deviation = over-evaluation of self mode
; deviation between individual score (subjective/objective depending on GUI switch) and objective score of current mobility mode
; deviation is null if the individual is objective; positive if they over-evaluate their mode

to-report deviation-self-mode
  report note-mobilite - mean-all-note mobility
end 



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;       VISUALISATION       ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; color per mode, for visualisation on map

to-report color-mode [qm]
  (ifelse
    qm = "bike" [report green]
    qm = "bus" [report blue]
    qm = "car" [report red]
    qm = "walk" [report yellow]
    [report gray]
    )
end 

; shape per mode, also depends on selected visu (select in GUI menu visu-ppl)
; add a halo around the citizens that decided based on bias/habits/constraint

to-report shape-mode [qm]
  ifelse not mode2bool visu-ppl
  ; with halo
  [report qm]
  ; without halo
  [report (word qm "-halo")]
end 




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;     THREE PLOTS on the RIGHT      ;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; --------  HAPPINESS PLOT  -------- ;;;
;; for the happiness plot in GUI - wrt mobility
;; qm which mobility mode (string)

to-report happy [qm]
  let mobs citizens with [mobility = qm]
  ; if no user of this mode, report the score given by non-users (users of other modes)
  if count mobs = 0 [report mean-notusers-note qm]
  report mean [item (index-mode mobility) subjective-scores] of mobs
end 

;;;  -------  MOBILITY DISTRIBUTION PLOT  -------  ;;;

to-report mobility-percent [qm]
  if count citizens = 0 [report 0]
  report 100 * count citizens with [mobility = qm] / count citizens
end 

;;;  --------  DECISIONS TRACKING PLOT  ------- ;;;

;; POLL report - percentage of citizens users of mode qm, with decision type qdt

to-report count-decisions-mode [qm qdt]
  report count ((select-citizens qdt) with [mobility = qm])
end 

;; PLOT of decision types percentage in total population

to-report percent-decision-type [qdt]
  if count citizens = 0 [report 0]
  report (count select-citizens qdt) * 100 / count citizens
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; DECISION MODES - for visu and monitors ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; call on a citizen to deduce boolean to check before viz

to-report mode2bool [qvm]
  (ifelse
    qvm = "bias" [report trigger-bias? and not trigger-constraint?]
    qvm = "constraint" [report trigger-constraint?]
    qvm = "bad habits" [report trigger-habits? and cog-dissonance? and not trigger-constraint?]
    qvm = "habits" [report trigger-habits? and not trigger-constraint?]
    ; neutral: nobody shows halo
    qvm = "neutral" [report false]
    )
end 

; select citizens that activate the selected decision mode
; used in MONITOR that counts them next to menu

to-report select-citizens [qdt]
  report citizens with [mode2bool qdt]
end 

; cognitive dissonance if selected mode is not the best subjective

to-report cog-dissonance?
  report (item (index-mode mobility) subjective-scores) != max subjective-scores
end 


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; MAP SHOWING DISTANCES TO CYCLE / WALK  ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; a turtle draws a circle of given radius then dies

to circle [radius]
  ; drawing turtle
  create-turtles 1 [
    set color gray
    pen-up
    ; place on tangent
    setxy radius 0
    set heading 0
    ; circle approximation in 360 steps
    let step ( 2 * pi * radius ) / 360
    pen-down
    ; loop
    repeat 360 [fd step left 1]
    die
  ]
end 

; draw 2 circles illustrating the walking distance and cycling distance

to draw-circles
  ; radius must reflect the distance
  circle visual-distance 15  ;; bike
  circle visual-distance 5  ;; walk
  circle visual-distance 80
end 

; draw the lines for the 4 sectors

to draw-cadrans
  create-turtles 1 [
    set color gray
    pen-up
    setxy min-pxcor 0
    pen-down
    move-to patch max-pxcor 0
    pen-up
    setxy 0 min-pycor
    pen-down
    move-to patch 0 max-pycor
    die
  ]
end 


;; (C) Carole Adam, March 2023, April 2024 - https://nausikaa.net/

There is only one version of this model, created 9 days ago by Carole Adam.

Attached files

File Type Description Last updated
SWITCH mobility.png preview Interface preview 9 days ago, by Carole Adam Download

This model does not have any ancestors.

This model does not have any descendants.