The applet requires Java 1.4.1 or higher. It will not run on Windows 95 or Mac OS 8 or 9. Mac users must have OS X 10.2.6 or higher and use a browser that supports Java 1.4. (Safari works, IE does not. Mac OS X comes with Safari. Open Safari and set it as your default web browser under Safari/Preferences/General.) On other operating systems, you may obtain the latest Java plugin from Sun's Java site.
powered by NetLogo
view/download model file: How_to_build_the_perfect_museum.nlogo
In this model we perform an agent-based simulation of people visiting a museum. The environment has not a fixed geometry, but is easily modifiable using the mouse. Also a set of model parameters is changeable by interface. Our purpose is to evaluate the average degree of satisfaction of all the agents visiting the museum by varying environment and model parameters. It is also possible to implement an alarm dynamics via a switch you can find on the interface.
Each patch colour indicates a different property of the environmental object (walls are grey, the entrance is red, the exit is blue, artworks are yellow, doors are green, free spaces are black) which agents recognize and with which they interact.
Visitors access the museum by the red entrance in groups of randomly selected sizes separated by variable intervals of time.
The motion of the visitors is constrained by the colour of the patches and follows a few intuitive rules. Each agent possesses a tunable radius of vision and is attracted by doors and artworks he can see. At each time step, in absence of obstacles, each agent move one step (i.e. a patch) towards his target, either a door or an artwork; people that saw an artwork are dynamically stored in an individual list of that artwork, roughly simulating human memory, so that one visitor will not attend twice the same artwork. In presence of obstacles, walls or other people, agents try to avoid them going around, until they reach the following door or fruition area near to an artwork. A given agent has a random interest for each artwork, i.e. the time that he is willing to spend enjoying that artwork. The degree of interest is randomly selected within a fixed range. Once the visit is over, visitors exit through the blue door.
Starting to use this model you have two choices: if you click on the button 'Setup standard environment' you will achieve a simple configuration in which there are four rooms and an artwork in each of them; otherwise, if you click on the button 'Setup empty environment' you will get an empty closed environment. You can also click on 'Setup model X', where X goes from A to E, achieving different configurations,more complicated than the previous ones.
Anyway you can modify the environment simply using the mouse: you will be able to draw environmental objects just clicking on 'draw' and then selecting on a chooser what you wish to insert (namely a door, an artwork, an entrance, an exit or a wall). Moreover, if you want to delete an object you are allowed to do it. You can also export your world writing it on a .csv file using the 'export world' button; then you will be able to reimport it opening the NetLogo file and using the 'import world' button.
Before starting the simulation you can establish the values of the five model parameters by using the sliders present in the interface:
1) interval: set the time elapsed between the admission of two different visiting groups
2) num_max: set the maximum size of the visiting groups
3) visual_radius: set the agents' radius of vision
4) max_looking_time: set the maximum time each agent will spend enjoying an artwork
5) stray_time: set the maximum time with no object in a room necessary to let an agent escape from that room
Finally you can check the degree of satisfaction of the turtles already exited, number of turtles involved in the simulation and touring time of the turtles by looking the following plots:
1) 'satisfaction'
2) 'turtles'
3) 'life'
Then clicking on 'go' button, the simulation will run indefinitely until you re-click 'go'. Otherwise, a click on 'go once' give you the possibility to run the model only for one tick.
We notice that modifying the structure of the environment and/or the parameters of the simulation it is possible to increase the average degree of satisfaction of the agentset.
It could be interesting to introduce some genetic algorithms in order to better select the optimal model parameters.
We used a lot of NetLogo features in order to build this model but some of them were especially significant :
1) the possibility of defining turtles and patches-own variables.
2) the possibility of using dynamical lists to store some important tags.
3) the possibility of drawing environments just using the mouse and to export them.
We started from the work 'Multi agent simulation of pedestrian behaviour in closed spatial environments' developed by Francesca Camillen, Salvatore Capr�, Cesare Garofalo, Matteo Ignaccolo, Giuseppe Inturri, Alessandro Pluchino, Andrea Rapisarda and Salvatore Tudisco from the University of Catania ( Italy).
patches-own [ tag escape_time ] globals [ num_of_obj coord visual list_turtles_in p satisfaction alarm_time p1 get ] turtles-own [ time_with_no_object looking_time control? direction dist see? stay? life time object? a b ] to setup_standard_environment ca set alarm false set visual visual_radius ask patches [set tag [] set escape_time []] set list_turtles_in [] set satisfaction [] set-default-shape turtles "person" ask patches with [pxcor = max-pxcor or pxcor = min-pxcor or pycor = max-pycor or pycor = min-pycor or pycor = 0 or pxcor = 0] [ set pcolor grey ] ask patches with [(pxcor = round(max-pxcor / 2) or pxcor = round(min-pxcor / 2) and pycor = 0) or (pycor = round(max-pycor / 2) and pxcor = 0) ] [ set pcolor green ] ask patches with [pycor = min-pycor and pxcor = round(min-pxcor * 0.75)] [ set pcolor red ] ask patches with [pycor = min-pycor and pxcor = round(max-pxcor * 0.75)] [ set pcolor blue ] ask patches with [(pxcor = round(max-pxcor / 2) and pycor = round(max-pycor / 2)) or (pxcor = round(max-pxcor / 2) and pycor = round(min-pycor / 2)) or (pxcor = round(min-pxcor / 2) and pycor = round(max-pycor / 2)) or (pxcor = round(min-pxcor / 2) and pycor = round(min-pycor / 2)) ] [ set pcolor yellow ] end to setup ca set alarm false set visual visual_radius set list_turtles_in [] set satisfaction [] ask patches [set tag [] set escape_time []] set-default-shape turtles "person" ask patches with [pxcor = max-pxcor or pxcor = min-pxcor or pycor = max-pycor or pycor = min-pycor] [ set pcolor grey ] end to draw if mouse-down? [ ask patch mouse-xcor mouse-ycor [ if drawing = "Door" [ set pcolor green ] if drawing = "Artwork" [ set pcolor yellow ] if drawing = "Wall" [ set pcolor grey ] if drawing = "Entrance" [ set pcolor red ] if drawing = "Exit" [ set pcolor blue ] if drawing = "Delete" [ set pcolor black ] ] ] end to generate if remainder ticks interval = 0 [ ifelse any? patches with [ pcolor = red ] [ crt random (Num_Max + 0.5) [ move-to one-of patches with [ pcolor = red ] set time random (max_looking_time) set stay? false set see? true set control? false set object? false set looking_time 0 set time_with_no_object 0 ] ] [ user-message ( "NO ENTRANCE IN THE MUSEUM !!!" ) ] ] ask turtles [ if [ pcolor ] of patch-here = red [if [ pycor ] of patch-here = min-pycor [ set heading 0 fd (1 + random-float 1) ] if [ pycor ] of patch-here = max-pycor [ set heading 180 fd (1 + random-float 1) ] if [ pxcor ] of patch-here = min-pxcor [ set heading 90 fd (1 + random-float 1) ] if [ pxcor ] of patch-here = max-pxcor [ set heading 270 fd (1 + random-float 1) ] ] ] end to update_door_lists ask patches with [ pcolor = green ] [ ask turtles-here [ ifelse not member? who [ tag ] of patch-here [ set tag fput who tag set tag remove-duplicates tag set object? false ] [ set tag remove who tag ] ] ] end to update_artwork_lists ask patches with [ pcolor = yellow ] [ let a1 ( [ who ] of turtles in-radius 3 with [ stay? = false ] ) if not empty? a1 [ let b1 item 0 a1 set tag fput b1 tag set tag remove-duplicates tag ] ] end to look_and_move if not stay? [ ifelse not object? [ set direction heading set p 0 while [ p < num_of_obj and control? = false ] [ if item 2 item p coord = "angle" or item 2 item p coord = "end_wall" or item 2 item p coord = "exit" [ set dist (distance patch (item 0 item p coord) (item 1 item p coord) - 2) ] if item 2 item p coord = "artwork" or item 2 item p coord = "door" [ set dist distance patch (item 0 item p coord) (item 1 item p coord) ] ifelse dist < visual_radius [ set see? true facexy (item 0 item p coord) (item 1 item p coord) check_walls if see? [ if not member? who [ tag ] of patch (item 0 item p coord) (item 1 item p coord) [ set a (item 0 item p coord) set b (item 1 item p coord) move_to_object set control? true set object? true ] ] ] [ set see? false ] set p (p + 1) ] if p = num_of_obj [ set heading direction ifelse [ pcolor ] of patch a b = grey [ let a1 a let b1 b ifelse any? patches with [ pcolor = black and count turtles-here = 0 and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ] [ let a2 [pxcor ] of one-of patches with [ pcolor = black and count turtles-here = 0 and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ] let b2 [pycor ] of one-of patches with [ pcolor = black and count turtles-here = 0 and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ] ifelse not member? who [ tag ] of patch a2 b2 [face patch a2 b2 move_to_object ] [ move ] ] [ move ] ] [move] set time_with_no_object (time_with_no_object + 1) ] set control? false ] [ ifelse [ pcolor ] of patch a b = grey [ let a1 a let b1 b ifelse any? patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ] [ face one-of patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ] ] [ facexy a b ] ] [ facexy a b ] move_to_object ] ] end to follow_walls let name who let a1 a let b1 b if object? = true and [pcolor] of patch a b = grey [ if distance patch a b <= 2 [ set object? false look_and_move ask patches with [pxcor = a1 and pycor = b1] [ set tag fput name tag set tag remove-duplicates tag ] ] ] end to contemplate if [ pcolor ] of patch a b = yellow and distance patch a b <= 3 and time > 0 and not member? who [ tag ] of patch a b [ set stay? true set time (time - 1) set heading heading + (random 10 - 5) ] if time = 0 [ set stay? false look_and_move update_artwork_lists set object? false set time random max_looking_time ] end to create_lists_of_objects let num_turt count turtles with [ life = 1 ] set list_turtles_in fput num_turt list_turtles_in set list_turtles_in remove 0 list_turtles_in ask patches [ set coord (list (list 0 0 0 0) (list 0 0 0 0)) ] set num_of_obj 0 ifelse alarm = false [ ask patches with [ pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor) ] [ if patch-at 1 0 != nobody and patch-at 0 1 != nobody [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] if patch-at 1 0 != nobody and patch-at 0 -1 != nobody [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor] of patch-at 0 -1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] if patch-at -1 0 != nobody and patch-at 0 1 != nobody [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] if patch-at -1 0 != nobody and patch-at 0 -1 != nobody [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 -1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] ] ask patches with [pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor)] [ if count neighbors4 with [pcolor = grey] = 1 and count (neighbors4 with [pcolor = blue or pcolor = red or pcolor = green]) = 0 [ let a1 (list pxcor pycor "end_wall" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] ask patches with [pcolor = blue] [let a1 (list pxcor pycor "exit" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ask patches with [pcolor = green] [ let a1 (list pxcor pycor "door" num_of_obj) set num_of_obj (num_of_obj + 1) set coord fput a1 coord ] ask patches with [pcolor = yellow] [ let a1 (list pxcor pycor "artwork" num_of_obj) set num_of_obj (num_of_obj + 1) set coord fput a1 coord ] ] [ ask patches with [ pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor) ] [ if patch-at 1 0 != nobody and patch-at 0 1 != nobody [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] if patch-at 1 0 != nobody and patch-at 0 -1 != nobody [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor] of patch-at 0 -1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] if patch-at -1 0 != nobody and patch-at 0 1 != nobody [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] if patch-at -1 0 != nobody and patch-at 0 -1 != nobody [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 -1 = grey and count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0 [ let a1 (list pxcor pycor "angle" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] ] ask patches with [pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor)] [ if count neighbors4 with [pcolor = grey] = 1 and count (neighbors4 with [pcolor = blue or pcolor = red or pcolor = green]) = 0 [ let a1 (list pxcor pycor "end_wall" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] ask patches with [pcolor = green] [ let a1 (list pxcor pycor "door" num_of_obj) set num_of_obj (num_of_obj + 1) set coord fput a1 coord ] ask patches with [pcolor = blue] [let a1 (list pxcor pycor "exit" num_of_obj) set num_of_obj (num_of_obj + 1) set coord remove (list 0 0 0 0) coord set coord fput a1 coord ] ] end to escape_room let name who set p1 0 while [ p1 < num_of_obj ] [ if (item 2 item p1 coord) = "door" [ set direction heading set dist distance patch (item 0 item p1 coord) (item 1 item p1 coord) facexy (item 0 item p1 coord) (item 1 item p1 coord) set see? true check_walls if see? = true [ ask patch (item 0 item p1 coord) (item 1 item p1 coord) [ set tag remove name tag ] ] ] set p1 (p1 + 1) set heading direction ] set time_with_no_object 0 look_and_move end to check_alarm if alarm [ ask turtles [ set num_max 0 set stay? false] if alarm_time = 0 [ ask turtles [ clear_doors ] ] set alarm_time (alarm_time + 1) ] end to clear_doors let ausiliaria who ask patches with [ pcolor = green ] [ set tag remove ausiliaria tag ] set time_with_no_object 0 end to go random-seed new-seed generate tick ask turtles [ set life (life + 1) ] create_lists_of_objects ask patches with [ pcolor = green ] [ ask turtles-here [ ifelse not member? who [ tag ] of patch-here [ set tag fput who tag set tag remove-duplicates tag set object? false ] [ set tag remove who tag ] ] ] check_alarm ask turtles [ let a1 a let b1 b if any? patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0] [ ask patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1) and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0] [ ask turtles-here [if not member? who [tag] of patch-here [ set tag fput who tag set tag remove-duplicates tag ] ] ] ] ] ask turtles [ look_and_move ] ask turtles with [ time_with_no_object >= stray_time ] [ ifelse alarm [ clear_doors ] [ escape_room ] ] ask turtles [ contemplate ] ask patches with [ pcolor = blue ] [ ask turtles-here [ set escape_time fput life escape_time ] ] ask turtles [ if stay? = true [ set looking_time looking_time + 1 ] ] ask patches with [ pcolor = blue ] [ ask turtles-here [ set satisfaction fput ( looking_time / life ) satisfaction ] ] ask turtles [ if [ pcolor ] of patch-here = blue [ die ] ] ask turtles [ if [ pcolor ] of patch-here = green [ update_door_lists set object? false look_and_move ] ] ask patches with [ pcolor = blue ] [ do-plots ] ask turtles [ follow_walls ] end to move ifelse patch-ahead 1 != nobody [ ifelse not any? turtles-on patch-ahead 1 [ ifelse [ pcolor ] of patch-ahead 1 != grey and [ pcolor ] of patch-ahead 1 != yellow [ fd random-float 1 ] [ ifelse (random 2) - 0.5 > 0 [ set heading heading + (100 + random-float 10) move ] [ set heading heading - (100 + random-float 10) move ] ] ] [turn_and_go] ] [ set heading heading + 90 ] end to check_walls if dist > 0 [ ifelse patch-ahead dist != nobody [ ifelse [ pcolor ] of patch-ahead dist = grey [ set see? false ] [ set dist (dist - 1) check_walls ] ] [ set see? false ] ] end to move_to_object ifelse [ pcolor ] of patch a b = green [ set direction heading set p 0 while [ p < num_of_obj and control? = false ] [ if item 2 item p coord = "artwork" [ set dist distance patch (item 0 item p coord) (item 1 item p coord) ifelse dist < visual_radius [ set see? true facexy (item 0 item p coord) (item 1 item p coord) check_walls if see? [ if not member? who [ tag ] of patch (item 0 item p coord) (item 1 item p coord) [ set a (item 0 item p coord) set b (item 1 item p coord) if [ pcolor ] of patch-here = blue [ die ] move_to_object set control? true set object? true ] ] ] [ set see? false ] ] set p (p + 1) ] if p = num_of_obj [ set heading direction if patch-ahead 1 != nobody [ ifelse not any? other turtles-on patch-ahead 1 and ([pcolor] of patch-ahead 1 != yellow and [pcolor] of patch-ahead 1 != grey) [ fd 1 ] [ turn_and_go ] ] set control? false ] ] [ if patch-ahead 1 != nobody [ ifelse not any? other turtles-on patch-ahead 1 and ([pcolor] of patch-ahead 1 != yellow and [pcolor] of patch-ahead 1 != grey) [ fd 1 ] [ turn_and_go ] ] ] end to turn_and_go set heading heading + (random 60 - 30) ifelse patch-ahead 1 != nobody [ ifelse not any? other turtles-on patch-ahead 1 and ([ pcolor ] of patch-ahead 1 != grey and [ pcolor ] of patch-ahead 1 != yellow) [ fd 1 ] [ set object? false ifelse (random 2) - 0.5 > 0 [ let h random-float 10 if patch-at-heading-and-distance (heading + 100 + h) 1 != nobody [if not any? other turtles-on patch-at-heading-and-distance (heading + 100 + h) 1 and [ pcolor ] of patch-at-heading-and-distance (heading + 100 + h) 1 != grey and [ pcolor ] of patch-at-heading-and-distance (heading + 100 + h) 1 != yellow [set heading (heading + 100 + h) fd 1]] ] [ let h random-float 10 if patch-at-heading-and-distance (heading - 100 + h) 1 != nobody [if not any? other turtles-on patch-at-heading-and-distance (heading - 100 + h) 1 and [ pcolor ] of patch-at-heading-and-distance (heading - 100 + h) 1 != grey and [ pcolor ] of patch-at-heading-and-distance (heading - 100 + h) 1 != yellow [set heading (heading - 100 + h) fd 1]] ] ] ] [ ifelse (random 2) - 0.5 > 0 [ set heading heading + (100 + random-float 10) ] [ set heading heading - (100 + random-float 10) ] ] end to do-plots set-current-plot "Turtles" set-current-plot-pen "inside" plot count turtles set-current-plot-pen "escaped" plot sum [length escape_time] of patches set-current-plot-pen "entered" plot sum list_turtles_in set-current-plot "Satisfaction" set-current-plot-pen "time_view_artwork" set-plot-y-range 0 (sum [length escape_time] of patches + 1) set-histogram-num-bars number_of_bars histogram satisfaction set-current-plot "Life" set-current-plot-pen "lifetime" set-plot-y-range 0 (sum [length escape_time] of patches + 1) if escape_time != [] [set-plot-x-range 0 max escape_time + 1 set-histogram-num-bars (max escape_time + 1) / interval_width ] histogram escape_time set get escape_time end