Desire Paths

Desire Paths preview image

1 collaborator

Default-person Benjamin Duncan (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.0.2 • Viewed 359 times • Downloaded 17 times • Run 0 times
Download the 'Desire Paths' 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?

The purpose of the agent based model is to understand trail creation and patterns of turf destruction from foot traffic on a college campus. Given a spatial map corresponding to an existing or planned campus or park, results from this model could inform adjusted path layouts or revegetation efforts to mitigate erosion damage from foot traffic. By running the model with a map of the target area with paths removed, it could inform future path layouts to optimize foot traffic and minimize erosion damage.

HOW IT WORKS

People on the campus are all modeled as the same type agent. Agents are initialized with constant parameters for pavement preference and grass aversion. Agent location and destination are updated throughout the simulation after being initialized to one of the opening cells.

HOW TO USE IT

Global Settings

population - the number of students (turtles) on the map growth-rate - percent of turf health regeneration per tick turf-fragility - percent of damage traversing agents cause to turf per tick

Agent Settings

avg-pavement-preference - amount agents prefer pavement over dead turf avg-grass-aversion - amount agents dead turf over live turf relative-standard-deviation - standard deviation of agent preferences as percentage of mean

THINGS TO NOTICE

If you run the model for a long time (hint: turn off view updates for a while), turf destruction can build up after even thousands of ticks.

THINGS TO TRY

Drag stochasticity to 0% to simulate a population of agents with identical preferences.

The reset button also regenerates agent preferences. Using this, you can see different desire paths formed with different agent preferences by turning on go and hitting reset after the turf stabalizes. You can do this faster by turning off view updates and keeping an eye on the turf health plot.

EXTENDING THE MODEL

An interesting addition would be to model seasons, where maximum health of the grass oscillates gradually with time. For example, it could oscillate between a maximum of 0.5 for winter and 1 for spring. Making this model match reality would involve settings specific to the climate in question and the maintenance of the turf.

NETLOGO FEATURES

This uses a variation of Dijkstra's pathfinding algorithm with weights based on terrain type and agent preferences.

You can also use the path-drawing tools to draw your own map:

  1. turn on patch-draw
  2. choose your draw-patch-type
  3. draw on the canvas

If you want to resize the map canvas, set the custom-world-height and custom-world-width sliders and click new-canvas

CREDITS AND REFERENCES

This model was created by Benjamin Duncan for an undergraduate Agent-Based Modeling course at Portland State University.

The model was used using the Netlogo software:

Wilensky, U. (1999). NetLogo. http://ccl.northwestern.edu/netlogo/. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.

COPYRIGHT AND LICENSE

Copyright 2018 Benjamin Duncan.

CC BY-NC-SA 3.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Commercial licenses are also available. To inquire about commercial licenses, please contact Benjamin Duncan at benjamin.duncan@pdx.edu.

Comments and Questions

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

Click to Run Model

globals [
  map-canvas
  turf-colors
  map-valids
  map-openings
  turf-color
  path-color
  opening-color
  obstacle-color
  has-setup?
]
patches-own [
  turf-health
  patch-type
  visited?
  active?
  path-cost
  next-path-cell
]
turtles-own [
  destination
  pavement-preference
  grass-aversion
  upcoming-path
]

to setup-map
  clear-all
  set has-setup? true
  set-default-shape turtles "person"
  set turf-colors (list 37 56 56 54 53)

  let t 0
  let p 1
  let x 2
  let o 3

  ;; setup an initial map canvas
  set map-canvas (list
   ( list o p p p p p p p p p o )
   ( list p t t t t p t t t t t )
   ( list p t t t t p t t t t t )
   ( list p t t t t p t t t t t )
   ( list p t t t p p p t t t t )
   ( list p t t t p x p t t t t )
   ( list p t t t p p p t t t t )
   ( list p t t t t t t t t t t )
   ( list p t t t t t t t t t t )
   ( list p t t t t t t t t t t )
   ( list o p p p p p p p p p o )
  )

  resize-world 0 (length (item 1 map-canvas) - 1) 0 (length map-canvas - 1)
  ask patches [ set patch-type (item pxcor (item pycor map-canvas)) ]

  restart
end 

to new-canvas
  clear-patches
  let #width-ratio (world-width - 1) / custom-world-width
  let #height-ratio (world-height - 1) / custom-world-height
  set-patch-size floor (patch-size * min (list #width-ratio #height-ratio))
  resize-world 0 custom-world-width 0 custom-world-height
  ask patches [ set patch-type 0 ]
  update-map-data
end 

to-report patch-name-to-type [ #name ]
  if #name = "turf" [ report 0 ]
  if #name = "pavement" [ report 1 ]
  if #name = "obstacle" [ report 2 ]
  if #name = "opening" [ report 3 ]
end 

to patch-draw
  if mouse-down? [
    ask patch mouse-xcor mouse-ycor [
      set patch-type patch-name-to-type draw-patch-type
    ]
    update-map-data
    ask patch mouse-xcor mouse-ycor [ display ]
  ]
end 

to update-map-data
  ; Store a list of valid patches to traverse (non-obstacles)
  set map-valids ( patches with [ patch-type != 2 ] )
  set map-openings ( patches with [ patch-type = 3 ] )

  ask patches with [ patch-type = 0 ] [
    set pcolor last turf-colors
    set turf-health 1.0
  ]
  ask patches with [ patch-type = 1 ] [ set pcolor 8 ]
  ask patches with [ patch-type = 2 ] [ set pcolor black ]
  ask patches with [ patch-type = 3 ] [ set pcolor red ]
end 

to restart
  if (has-setup? != true) [
    setup-map
    stop
  ]

  ask patches [ set plabel "" ]
  clear-turtles
  reset-ticks
  clear-all-plots
  update-map-data
  create-turtles population [
    ;; randomly assign agent prefs using bounded normal distribution
    set pavement-preference max (list 0.1 (random-normal avg-pavement-preference (avg-pavement-preference * relative-standard-deviation / 100)))
    set grass-aversion max (list 0 (random-normal avg-grass-aversion (avg-grass-aversion * relative-standard-deviation / 100)))
    move-to one-of map-openings
    pick-destination
  ]
end 

to pick-destination
  ;; pick an opening that isn't the one here
  set destination ( one-of map-openings with [ self != [patch-here] of myself ] )
  set upcoming-path path-to-goal destination
end 

to go
  if has-setup? != true [ setup-map ]
  ask turtles [ turtle-go ]
  ask patches with [ patch-type = 0 ] [ turf-go ]
  tick
end 

to turtle-go
  ;; update destination if necessary
  if length upcoming-path = 0 [
    ;; set a new destination
    pick-destination
  ]
  ;; move one cell down path to destination
  move-to item 0 upcoming-path
  set upcoming-path remove-item 0 upcoming-path
end 

to turf-go
  set turf-health  min list (turf-health + (growth-rate / 100)) 1
  set turf-health max list 0 (turf-health - (turf-fragility / 100 * (count turtles-here)))
  set pcolor item (round (turf-health * 4)) turf-colors
end 

to-report cell-cost [ #traveler ]
  if (patch-type = 0) [ report 1 + ([grass-aversion] of #traveler * turf-health) ]
  if (patch-type = 1 or patch-type = 3) [ report 1 / [pavement-preference] of #traveler ]
  report 1
end 

to-report list-path [ #path-so-far ]
  let #next-patch ([next-path-cell] of (last #path-so-far))

  if ([path-cost] of (last #path-so-far)) = 0 [
    report #path-so-far
  ]

  report list-path lput #next-patch #path-so-far
end 

to-report path-to-goal [ #Goal ]
  let #Start patch-here
  let #traveler self

  ; clear all the information in the patches, and reset them
  ask map-valids [
    set next-path-cell nobody
    set path-cost (2 ^ 20)
    set visited? false
    set active? false
  ]

  ask #Start [
    set next-path-cell nobody
    set visited? false
  ]
  ask #Goal [
    set path-cost 0
    set visited? true
    set active? true
  ]

  while [not [visited?] of #Start] [
    let #options map-valids with [active?]

    ifelse any? #options [
      ask min-one-of #options [path-cost] [
        let #path-cost-father path-cost
        set active? false
        let #valid-neighbors neighbors with [member? self map-valids]
        ask #valid-neighbors [
          ;; get potential path cost, multiply cell cost by distance to account for diagonals
          let #new-path-cost #path-cost-father + (distance myself * cell-cost #traveler)
          if #new-path-cost < path-cost [
            set next-path-cell myself
            set visited? true
            set active? true
            set path-cost #new-path-cost
          ]
        ]
      ]
    ] [
      ;; We've run out of options before finding the Start
      show "No path available"
    ]
  ]

  let #future-path list-path (list #Start)

  report #future-path
end 

There is only one version of this model, created about 6 years ago by Benjamin Duncan.

Attached files

File Type Description Last updated
Desire Paths.png preview Preview for 'Desire Paths' about 6 years ago, by Benjamin Duncan Download

This model does not have any ancestors.

This model does not have any descendants.