Rhino Poaching
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This model explores the dynamic interaction between three agents involved in rhino poaching: rhinos, poachers, and rangers. The agents make decisions based on their environment and are also influenced by other agents. A population of rhino agents live inside a protected area and are moving around. Poachers try to find these rhino’s in order to kill them. Rangers try to find the poachers in order to capture them and ultimately prevent the rhino population from going extinct. The model can be used to identify optimal ranger strategies under varying environmental conditions, but also for studying various strategies that poachers may use to avoid detection or for successfully finding rhinos.
HOW IT WORKS
The world The world is created by the "SETUP-PARK" button. The patches at the border of the world are colored black and represent the area outside the reserve. All other patches represent the protected area where a population of rhinos live. These patches contain a varying amount of resources (ranged from 0-1), roughness (ranged from 1-5), home range information (to which rhino does this patch belongs to) and finally signs of recent rhino, poacher and ranger activity. Resources can represent food, water or other features that are relevant to your species of interest. These resources are diffused to create more natural and realistic gradients. All patches have a resource regrowth rate. Some patches do not contain any resources, here called 'sandy areas'. The slider "SANDY-AREAS" gives you control over the percentage of patches with no resources. Roughness is also an umbrella term for features that may make an area less desirable or more difficult to move through (for example, mountains or dense vegetation). Agents moving through rough areas results the agent waiting an extra tick (slowing them down).By default all patches are equally “easy” to traverse with a roughness value of 1. Adding rough areas with the "ROUGH-AREAS" slider creates the specified amount of rough patches with the maximum value of 5 and a radius around it to smooth out the effect. All this information was combined into one variable named "patch attractiveness". This value is used to direct each agent's movement and described in more detail for each agent.
There are several visualization options available from the "VISUALIZATION" drop-menu. The option RESOURCECOLOURS visualizes the amount of resources available in each patch, colored by a shade of green. The higher the amount of resources, the more darker the shade of green. The patches with a resources value of 0 (the sandy patches) are colored brown. The option ROUGHNESSCOLORS visualizes all patches with a roughness value larger than 1 along a shade of red. Patches with a roughness value equal to 1 are visualized based on their resources. The option RHINO_HOME-RANGES shows how the rhino territories are distributed. The color of the patch is the same as the color of the rhino it belongs to. Please note that the rhino colors are randomly distributed so it may occur that two rhinos have the same color. The next section describes how home ranges are formed.
Rhinos The rhino agents are created and put in place by the "SETUP-RHINOS" button. The number of rhino agents is determined by the NUM-RHINOS slider. Rhinos are randomly placed in the world. If another agent is within a radius of 10 patches, the rhino is moved to a random different patch without any agents within that radius. If none of the patches can for-fill that condition, the rhino will be placed on a random patch that is has not been taken yet. Each 1.5 patch in the rhino’s radius is added to its home range, and it expands when the rhino is moving. If a rhino was killed by poachers, all of its home range patches become unoccupied. The rhinos move by making a weighted decisions by based on the variables of its neighboring patches. The variables involved are the amount of resources, the roughness, and the distance to other rhinos. Each of these variables were scaled from 0 to 1 with 1 indicating the high preference. The variables are then summed and the divided by the sum of weights. The weights for the rhinos are "RESOURCE-WEIGHT", "ROUGHNESS-WEIGHT", "RHINO-AVOID-WEIGHT", and "GOAL-WEIGHT", and are adjustable in the interface. This information was stored in the variable ‘patch attractiveness’ that describes the overall attractiveness and hence the likelihood that the rhino will go to that patch. This was done by using the rnd:weighted-one-of function. To reduce the likelihood that rhinos will enter territories of other rhinos, the patch attractiveness of neighbors that belong to one of the other rhinos, are divided by 10. Once the rhino moved to one of the neighboring cells, it will consume 1% of the available resources. After moving to a new patch, the rhino will consume 1% of the resources (specified by the FORAGE-AMOUNT slider), add the patch to its territory and a 50% chance of leaving signs in that patch. The rhino will also remember and avoid the last 3 visited patches.
Poachers Poachers are added by the SETUP-HUMANS procedure and placed at a random patch on one of the black border patches. The number of poachers in the world can be changed by using the "NUM-POACHERS" slider. The time available for hunting is specified by the "POACHER-TIME" slider. When time has run out, they will leave the park. The variables involved in poacher movement are signs of recent rhino activity, signs of ranger activity, roughness, resources, and distance to goal. The weights for poacher decision-making are "RANGER-AVOID-WEIGHT", "HUNT-RHINO-WEIGHT", "ROUGHNESS-WEIGHT", "RESOURCE-WEIGHT", and "GOAL-WEIGHT". Poachers check if there are rhinos within the "POACHER-VISION" radius. If so, the poacher will kill it, remove it from the world and move towards the nearest border patch. Poachers will lay low after successfully escaping the reserve (regardless if a rhino was killed or not). The lay low time was defined as twice the "POACHER-TIME" plus random 100. Poachers also have a 50% chance of leaving signs, whereas killing a rhino will leave permanent signs. Poachers remember patches where they killed rhinos as success sites, patches with recent-rhino-activity as good-sites, and patches with ranger activity as failure sites. The success and failure sites are used to plan new poaching trips and to determine where the poacher will enter the park next.
Rangers The SETUP-HUMANS procedure also builds ranger camps and create rangers. The number of camps and rangers can be specified with the "NUM-CAMPS" and "NUM-RANGERS" slider respectively. Camps are put either randomly, at fixed locations or manually. This can be set from the "CAMP-PLACEMENT" drop-down menu (where "WE-DECIDE" is the manual option). Rangers sprout from camps and start their first patrol there. Rangers use movement rules similar to poachers, only their aim is to find poachers. Their movement is directed by goal distance and weight, rhino signs, poacher signs and roughness. This again accumulates into a patch attractiveness, allowing rangers to pick the highest relative attractiveness with a degree of randomness. The duration of each patrol is specified by the "PATROL-LENGTH" slider. When a ranger detects a poacher within the "RANGER-RADIUS" slider, the poacher was caught and removed from the world. Patches with poacher signs are remembered as risky areas whereas non-poaching sites are remembered as safe-areas. This information is used in the planning of the next patrols. Rangers also have a 50% chance of leaving signs. When the patrol-time ends, rangers move to the nearest camp or border patch and wait a number of ticks before going out again. Ranger agents have two strategies that can be specified from the "PATROL-TYPE" drop-down-menu. The "STANDARD-PATROL" is the weighted decision-making as described above. The "FENCE-PATROL" lets the ranger team moves along the border of the reserve and do not make weighted decisions. If the ranger enters a patch with poacher signs, the PATROL-LENGTH will be reset to 0, and from here makes weighted decisions similar to the STANDARD-PATROL strategy. This represents a so-called 'response time' that will take over when an illegal entry was detected.
The signs of rhinos, poachers, and rangers will decrease in value over time. When it reaches 0, the signs are not visible for the agents.
HOW TO USE IT
(1) SETUP-PARK creates the world with all the environmental variables and creates a population of rhinos. (1b) If you want to manually decide the camp placement, first click the "CREATE-CAMPS" button, and then anywhere in the world to create camp. Make sure that the number of camps in the "MUN-CAMPS" slider is equal to the number of camps that you manually create. (2a) "SETUP-RHINOS" allows you to run the world with only rhinos before adding the poacher and ranger agents. This will only call the rhino movement procedures in which the rhinos can establish their home-ranges. (2b) "SETUP-HUMANS" adds the poacher and ranger agents.
On the right-hand side of the screen, you can specify the weights for each variable. The weights are used in the decision-making as described above. The graph below it shows the number of rhino agents that are still alive.
THINGS TO NOTICE
This is an abstract representation of a protected area. The units (patches and ticks) are an arbitrary measurement and don't map directly to real world time or space. This can only be done when this model is applied to a specific context or setting where one can define what one tick or patch means in the real world.
THINGS TO TRY
The aim is to find ranger strategies that match the existing or realistic anti-poaching strategies, in order to keep as many rhinos alive as possible. It is important to make these ranger strategies realistic and practically feasible. How does adding more teams, longer patrols, influence the number of surviving rhinos? Is one strategy more effective than the other? What will happen if the rangers or poachers know better the whereabouts of the rhinos?
EXTENDING THE MODEL
The strength of this general model and the behavioral rules is that they can be applied to any park or reserve and that one can make additional assumptions to better fit their specific setting. The model should be regarded as a first step to understand the wildlife crime and would only benefit from further improvements and extensions. Additional ranger strategies can be developed, added and tested in this model. This model focuses on active poaching (searching and shooting an animal), but passive poaching such as traps and snares can also be implemented and subsequently test which anti-poaching strategies work best for this poaching activity. Also rangers and poachers may start learning more from one another (communication can lead to success and failure sites being shared), or the effect of corruption. One may also try to change the environment to better represent a real-life national park or reserve by, for example, creating rivers or different types of habits.
NETLOGO FEATURES
To allow for the random weighted decision rules for agent movement use: extensions [rnd] Allowing the use of: rnd:weighted-one-of
RELATED MODELS
The wolf-sheep predation model and the mammoths model are similar as they look the dynamic interactions between two types of agents. Tuskless elephants is another model related to poaching.
CREDITS AND REFERENCES
We would like to thank Michael Mäs and Andrew Lemieux for their support and help in building the model.
Comments and Questions
; ctrl f: JJJJ & ???? extensions [rnd] globals [ max-roughness ; highest rough terrain value sprout-delay-time ; number of ticks until resources wil grow back rhino-activity-decay ; how fast will signs of rhino activity disappear? human-signs-decay ; how fast will signs of poachers disappear? carcass-decay ; how long it takes for a carcass to dissappear rhino-weight ; sum of weights for the rhino-decision poacher-weight ; sum of weight for the poacher-decision ranger-weight ; sum of weight for the ranger-decision ;population-size ; sum of herd-size of all rhinos (i.e. rhinos * herd-size, which starts at 70 w/ herds off and 350 w/ herds on) JJJJ [OFF, see report] ] breed [ camps camp] ; create breed of camps breed [ poachers poacher ] ; create breed of poachers breed [ rhinos rhino] ; create breed of rhinos breed [ rangers ranger] ; create breed of rangers rangers-own [ patrol-memory ; remember previous visited patches patrol-time ; how long has the ranger been on patrol risky-areas ; remember areas where the ranger found signs of poaching activity safe-areas ; remember areas with no poaching activity off-duty-time ; how long to wait in between patrols rhino-sightings ; remember where rangers saw a rhino ranger-goal ; everyone needs a goal in life state ; describes if the ranger is patrolling, or heading back to camp and preparing for next patrol direction ; describes the direction of ranger during fence patrol ticks-wait ] poachers-own [ time ; How much time has the poacher spent inside the reserve? laylow ; How long to wait between hunts? success-sites ; remember all patches where the poacher killed a rhino good-sites ; remember all patches with rhino signs and no rangers failure-sites ; remember all patches where the poacher did not find anything or too many rangers rhinos-killed ; total number of rhinos killed poacher-memory ; remember previous visited patches poacher-goal ; everyone needs a goal in life state ; describes if the poacher is on the journey to, from crime or waiting and planning new trip ticks-wait ] rhinos-own [ rhino-memory ; remember previous visited patches rhino-goal ; even rhinos have a goal in life ticks-wait herd-size ; counter for group size JJJJ ] patches-own [ inside? ; represents inside / outside reserve resources ; how many resources in the patch? roughness ; high roughness takes more time to move through countdown ; number of ticks until resources wil grow back recent-rhino-activity ; was there any rhino here recently? rhino-territory ; to which rhino does this patch belong to? poacher-signs ; signs of poaching patch-attractiveness ; which patch is the most sexy? ranger-signs ; signs of ranger patrols ] ;to test ; ask ranger (1 + num-rhinos) [set color yellow set size 20] ;end to setup-park clear-all set sprout-delay-time 100 ; resources will increase after a certain time set max-roughness 5 ; highest rough terrain value set rhino-activity-decay 500 ; set rhino-weight (rhino-avoid-weight + roughness-weight + resources-weight) ;set population-size (sum [herd-size] of rhinos * count rhinos) ; JJJJ create-park create-rough-areas release-rhinos setup-home-range reset-ticks end to-report population-size ; JJJJ report sum [herd-size] of rhinos end to setup-humans set carcass-decay 10000 ; carcass signs will always be visible throughout the simulation set human-signs-decay 200 set poacher-weight (ranger-avoid-weight * 2) + hunt-rhino-weight + roughness-weight + resources-weight set ranger-weight 1 + search-rhino-weight + roughness-weight + catch-poacher-weight ; the '+1' represents avoidance of other patrols build-camps distribute-camps release-rangers release-poachers reset-ticks end to create-park ; next create resources patches inside the reserve ask patches with [count neighbors = 8][ ; inside the reserve set rhino-territory nobody ; no patches have been taking by rhinos yet set roughness 1 ; all patches are easy to move through set inside? TRUE ; resources can increase only inside the reserve set resources random-float 1.1 ; amount of resources is a random number between 0 to 1 set countdown random (sprout-delay-time + random 100) ; generate a random countdown for each patch ] diffuse resources 0.4 ; first create the reserve's border ask patches with [count neighbors < 8][ ; select world's border set roughness 1 ; easy to move through set resources 0 ; no resources means unattractive for rhinos set inside? FALSE ; no resources can grow here set countdown 0 ; no resources can grow back set pcolor black ; colour the border black ] ; some patches will be sand/dirt areas. No resources is growing on these patches let percentage-sand ((count patches with [inside? = TRUE]) / 100 ) * sandy-areas ask n-of percentage-sand patches with [inside? = TRUE] [ set resources 0 ] ; colour the world ask patches [color-resources] end to setup-rhino if ticks = 1000 [ stop ] ask rhinos [ rhino-goal-check ; check for their rhino movement goal update-rhino-memory ; short-term memory of rhino rhino-foraging-and-home-range ; rhinos are territorial and search for food ] ask patches [ update-resources update-home-range update-visualization update-activity-signs ] tick end to go ; when all rhinos die and last poacher escaped the reserve, it's game over. if (not any? rhinos) [ stop ] ; when all poachers are caught, the rhinos live happily ever after if (not any? poachers) [ stop ] ; when "a year" has passed, stop the simulation if ticks = 10000 [ stop ] ask rhinos [ rhino-goal-check ; check for their rhino movement goal update-rhino-memory ; short-term memory of rhino rhino-foraging-and-home-range ; rhinos are territorial and search for food ] ask poachers [ poacher-laylow ; if outside reserve, poacher will will prepare for their next hunt poacher-goal-check ; poachers avoid rangers and search for rhinos ] ask rangers [ ranger-end-patrol ; check if rangers have still time to patrol more. ranger-goal-check ; rangers search for poachers ] ask patches [ update-resources update-home-range update-visualization update-activity-signs ] tick end to update-visualization if visualization = "resources_colors" [ color-resources ] if visualization = "rhino_home-ranges" [ color-home-range ] if (visualization = "rough_areas") [ color-rough-areas ] end to color-home-range ; the colour of the patch corresponds to the same colour as the rhino it belongs to. ; when the patch belongs to nobody, it corresponds to the number of resources. ; IF - patches are inside ifelse inside? [ if rhino-territory != nobody [ set pcolor [color] of rhino-territory + 2] if rhino-territory = nobody and resources > 0 [ set pcolor (scale-color green resources 1.5 0)] if rhino-territory = nobody and resources = 0 [ set pcolor brown * 1.02 ] ] ; ELSE - patches outside the reserve [set pcolor black] end to update-resources set countdown (countdown - 1) ; reduces the countdown by 1 if inside? and countdown = 0 [ ; for every fertile patch that reached 0.. set resources (resources * 1.01) ; ...increase resources with 1% set countdown sprout-delay-time + random 100 ; resources won't increase again until sprout-delay-time has passed if resources > 1 [set resources 1] ; 1 indicates maximum value, this cannot be exceeded ] if not inside? [ ; select the patches outside the reserve... set resources 0] ; ... and keep them unattractive for rhinos if resources < 0 [ set resources 0 ; resources cannot have negative values ] if (visualization = "resources_colours") [ color-resources] ; colour patches based on amount of resources available end to color-resources ; scale color of patch from whitish green (for low resources) to green (for high resources) ; IF - patches are inside the reserve ifelse inside? [ ; IF - and have some resources ifelse resources > 0 [ set pcolor (scale-color green resources 1.5 0)] ; ELSE - fertile but no resources [set pcolor brown * 1.02]] ; colour for patches inside the reserve but with no resources ; ELSE - not fertile [set pcolor black] ; colour for outside the reserve end to create-rough-areas ask n-of rough-areas patches with [inside? = TRUE] [ ; select an x number of patches inside the reserve... set roughness max-roughness ; and assign the maximum value of roughness to it (the peak if you like). ask patches in-radius ( max-roughness - 1 ) [ ; select the patches surrounding it... set roughness round (max-roughness - distance myself + roughness) ; ...and increase their roughness based on how close the patch is to the "peak". if roughness < 1 [ ; minimum roughness = 1 set roughness 1] if roughness > max-roughness [ set roughness max-roughness]] ; maximum roughness ] if visualization = "rough_areas" [ ask patches [ color-rough-areas ] ] end to color-rough-areas ; colour the patches based on their roughness. The non-rough patches will be coloured based on their resources-values. ; IF - patches are fertile if roughness > 1 [ set pcolor (scale-color red roughness 1 10) ] if roughness = 1 and resources > 0 [ set pcolor (scale-color green resources 1.5 0) ] if roughness = 1 and resources = 0 and inside? = TRUE [ set pcolor brown * 1.02 ] if roughness = 1 and resources = 0 and inside? = FALSE [ set pcolor black ] end to release-rhinos set-default-shape rhinos "mammoth" ; slightly modified mammoth symbol represents rhinos ask n-of num-rhinos patches with [inside? = TRUE and not any? turtles in-radius 5 ] [ ; sprout rhinos only inside the reserve sprout-rhinos 1 [ ; create the rhinos, then initialize their variables set size 2] ] spread-rhinos ; make sure rhinos won't be too close to each other ask rhinos [ set rhino-memory (list patch-here) ; At the start, rhinos only remember their current location set rhino-goal patch-here ; Rhinos will start by creating a new goal ifelse herd = true [set herd-size 5] [set herd-size 1] ] end to setup-home-range ask rhinos [ ask patches in-radius 1.5 with [inside? = TRUE] [ ; select patches that are around the rhino and inside the reserve set rhino-territory myself ; those patches now belong to that rhino's territory if visualization = "rhino_home-ranges" [ ; home ranges will be visualised if the user strongly desires so. set pcolor [color] of myself + 2] ; colour of the patches is similar to the color of the rhino ] if random-float 1 < 0.5 [ ; 50% chance of.. ask patch-here [ ; leaving rhino activity signs on the current patch set recent-rhino-activity rhino-activity-decay + random 500] ] ] end to spread-rhinos let spreading-rhinos rhinos with [any? other turtles in-radius 10] if any? spreading-rhinos [ ask one-of spreading-rhinos [ let available-patches patches with [inside? = TRUE and not any? other turtles in-radius 10] ; IF - there are any patches without a rhino nearby, move rhino to that patch. ifelse any? available-patches [ move-to one-of available-patches spread-rhinos ] ; ELSE - if no patches are available anymore, pick a random spot [ move-to one-of patches with [inside? = TRUE and not any? other turtles-here ] ] ] ] end to release-poachers set-default-shape poachers "person" ; person symbol represents poachers ask n-of num-poachers patches with [inside? = FALSE] [ ; sprout poachers only on the borders sprout-poachers 1 [ ; create the poachers, then initialize their variables set color blue set size 2 set time 0 ; poachers have not spend time in the reserve yet set laylow ( poacher-time * 2 ) + random 100 ; how long to wait in between hunts set good-sites no-patches ; memories of good hunting grounds set success-sites no-patches ; memories of successful rhino kill sites set failure-sites no-patches ; memories of unsuccessful hunts set poacher-memory no-patches ; memories of previous patches set poacher-goal patch-here ; poacher will start by creating a new goal set state "journey-to-crime" ; poacher will go hunting ] ] end to build-camps set-default-shape camps "house" ; house symbol represents the base camps if camp-placement = "random" [ ; distribute the camps randomly across the reserve ask n-of num-camps patches with [inside? = TRUE and roughness = 1] [ ; but only inside, and for easily accessible areas sprout-camps 1 ] ] if camp-placement = "fixed" [ ; when running model 500 times sets camp at fixed coordinates ) let camp-coordinates (patch-set patch 0 0 patch (min-pxcor + 1 + random 10) (min-pycor + 1 + random 10) patch (min-pxcor + 1 + random 10) (max-pycor - 1 - random 10) patch (max-pxcor - 1 - random 10) (max-pycor - 1 - random 10) patch (max-pxcor - 1 - random 10) (min-pycor + 1 + random 10)) ask n-of num-camps camp-coordinates [ sprout-camps 1] ] end to distribute-camps let camps-too-close camps with [any? other camps in-radius 10] if any? camps-too-close [ ask one-of camps-too-close [ let available-patches patches with [inside? = TRUE and not any? other camps in-radius 10] ifelse any? available-patches [ move-to one-of available-patches distribute-camps ] [ move-to one-of patches with [inside? = TRUE and not any? other turtles-here] ] ] ] ask camps [ ask patches in-radius 4.5 [ set resources 0 color-resources] set size 2 set color red] end to click-camps if mouse-down? [ ask patch mouse-xcor mouse-ycor [ sprout-camps 1 ] stop] end to release-rangers set-default-shape rangers "person soldier" ; soldier symbol represents rangers repeat num-rangers [ ; for N rangers, repeat the following ask one-of camps [ ; hatch-rangers 1 [ ; create a ranger at a random camp set color red set size 2 set patrol-memory no-patches ; memories of previous patches set patrol-time 0 ; represents how long the poacher has been on patrol today set risky-areas no-patches ; remember areas where the ranger has found evidence of poaching set safe-areas no-patches set rhino-sightings no-patches ; remember areas where the ranger has seen a rhino ifelse coordinated = false [set off-duty-time (patrol-length * 2) + random 100] [set off-duty-time patrol-length * 2] ; JJJJ ;set off-duty-time ( patrol-length * 2 ) + random 100 ; how long to wait in between patrols set ranger-goal patch-here set state "patrolling" ifelse random 2 = 0 [ ; for fence patrols... set direction 1 ] ; ... 1 follows right-hand fence [ set direction -1 ] ; ... -1 follows left-hand fence face one-of neighbors4 ] ] ] end to-report ticks-to-stay-on-patch [p] report roughness - 1 end to rhino-goal-check ifelse ticks-wait > 0 [ set ticks-wait ticks-wait - 1 ] ; IF - rhino has completed his goal in life [ ifelse rhino-goal = patch-here [ rhino-decision-making] ; do rhino stuff ; ELSE - if rhino is still moving towards goal ; IF - rhino is within reach of his goal [ifelse member? rhino-goal neighbors [ move-to rhino-goal ] [ rhino-movement ] ] if ( roughness > 1) [ set ticks-wait ticks-to-stay-on-patch patch-here ] ] end to rhino-movement let surroundings neighbors with [inside? = TRUE] let max-goal-dist distance rhino-goal ask surroundings [ let goal-dist (max-goal-dist - distance [rhino-goal] of myself) * goal-weight let estimated-roughness ((max-roughness - roughness) / max-roughness) * roughness-weight let estimated-resources resources * resources-weight set patch-attractiveness (goal-dist + estimated-resources + estimated-roughness + rhino-dist) / (rhino-weight + goal-weight) if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] ask surroundings with [rhino-territory != myself and rhino-territory != nobody] [ set patch-attractiveness patch-attractiveness / 2 ] move-to rnd:weighted-one-of surroundings [patch-attractiveness] end to rhino-decision-making let surroundings patches in-radius 2.5 with [inside? = TRUE and not member? self [rhino-memory] of myself] ask surroundings [ let estimated-roughness ((max-roughness - roughness) / max-roughness) * roughness-weight let estimated-resources resources * resources-weight set patch-attractiveness (estimated-resources + estimated-roughness + rhino-dist) / rhino-weight ] ask surroundings with [rhino-territory != myself and rhino-territory != nobody] [ set patch-attractiveness patch-attractiveness / 10] set rhino-goal rnd:weighted-one-of surroundings [patch-attractiveness] ifelse member? rhino-goal neighbors [ ; if the goal is a neighbouring patch... ???? add intervals here? move-to rhino-goal] ; move to that patch [ rhino-movement ] ; otherwise get closer to the goal patch end to-report rhino-dist ifelse any? other rhinos [ let max-rhino-dist distance min-one-of other rhinos [distance myself] ifelse max-rhino-dist = 0 [ report 0 ] [ report (distance min-one-of other rhinos [distance myself] / max-rhino-dist) * rhino-avoid-weight ] ] [ report 0 ] end to update-rhino-memory set rhino-memory lput patch-here rhino-memory ; remember the current patch set rhino-memory remove-duplicates rhino-memory ; clean up the valuable memory space if length rhino-memory > 3 [ ; if the rhino has more than three patches in its memory set rhino-memory but-first rhino-memory] ; forget the oldest (first) one end to rhino-foraging-and-home-range ask patch-here [ set resources (resources * ((100 - forage-amount) / 100)) ; eat some proportion of available resources set countdown sprout-delay-time ; resources will grow back after sprout delay time. set rhino-territory myself ; include current patch to home range if visualization = "rhino_home-ranges"[ ; home ranges will be visualised if the user strongly desires so. set pcolor [color] of myself + 2] ; home range colours are similar to the rhinos colour if random-float 1 < 0.5 [ ; 50% chance of... set recent-rhino-activity rhino-activity-decay + random 500] ; ...dropping rhino activity signs ] end to update-home-range if visualization = "rhino_home-ranges"[ set pcolor [pcolor] of one-of neighbors with [inside? = TRUE] ] end to poacher-goal-check pen-down ; IF - poacher is moving through rough terrain ifelse ticks-wait > 0 [ set ticks-wait ticks-wait - 1 ] [ ; ELSE - poacher will move and make decisions ; IF - poacher has no horn and still time left to hunt ifelse state = "journey-to-crime" [ poacher-journey-to-crime ] ; searching for rhinos and avoid rangers ; ELSE - no time is left or the poacher obtained a rhino horn, he will move to the nearest patch outside the reserve [ poacher-journey-after-crime ] if time >= poacher-time [ ; if no time is left to continue the hunt? set state "journey-after-crime" ] if roughness > 1 [ set ticks-wait ticks-to-stay-on-patch patch-here] ] ask patch-here [ if random-float 1 < 0.5 [ ; 50% chance of... set poacher-signs human-signs-decay ] ; ...dropping poacher activity signs ] set time time + 1 end to poacher-journey-after-crime let closest-exit min-one-of patches with [ inside? = FALSE ] [ distance myself ] set poacher-goal closest-exit ; IF - poacher is within reach of his goal ifelse distance poacher-goal <= 1 [ move-to poacher-goal] ; if so, move to goal ; ELSE - move closer to goal [face poacher-goal forward 1] end to poacher-journey-to-crime let target one-of rhinos in-radius poacher-vision ; are there any rhinos around? ; IF - a rhino is nearby, the poacher will go there and kill it ifelse target != nobody [ poacher-kills-rhino ] ; IF - poacher has completed his goal in life [ ifelse poacher-goal = patch-here [ poacher-decision-making ] ; do sneaky poacher things ; ELSE - if poacher is still moving towards goal ; IF - poacher is within reach of his goal [ifelse member? poacher-goal neighbors [ move-to poacher-goal ] [ poacher-movement ] ] ] set poacher-memory (patch-set poacher-memory patch-here) ; remember the patches on the journey to crime if recent-rhino-activity > 0 and ranger-signs = 0 [ ; remember good hunting areas set good-sites (patch-set good-sites patch-here) ; IF - the good hunting site was in the failure-memory, remove that patch from failure-memory if (member? patch-here [good-sites] of self) and (member? patch-here [failure-sites] of self) [ set failure-sites failure-sites with [[patch-here] of myself != self]] ] if ranger-signs > 0 [ ; remember areas with high ranger activity set failure-sites (patch-set failure-sites patch-here) ; IF - the high ranger activity site was in the good hunting site memory, remove that patch from hunting-memory if (member? patch-here [failure-sites] of self) and (member? patch-here [good-sites] of self) [ set good-sites good-sites with [[patch-here] of myself != self]] ] end to poacher-movement let nearby-rangers (turtle-set rangers camps) if any? nearby-rangers in-radius poacher-vision [ ; look around and see if any rangers are nearby set failure-sites (patch-set failure-sites patches in-radius poacher-vision) ] ; remember this patch as failure-sites let max-goal-dist distance poacher-goal ask neighbors with [inside? = TRUE] [ let goal-dist (max-goal-dist - distance [poacher-goal] of myself) * goal-weight let rhino-signs (recent-rhino-activity / (rhino-activity-decay * 2)) * hunt-rhino-weight let nearby-ranger-signs ((human-signs-decay - ranger-signs) / human-signs-decay) * ranger-avoid-weight let estimated-roughness ((max-roughness - roughness) / max-roughness) * roughness-weight let estimated-resources resources * resources-weight set patch-attractiveness (goal-dist + estimated-resources + estimated-roughness + ranger-dist + rhino-signs + nearby-ranger-signs) / (poacher-weight + goal-weight) if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] let surroundings neighbors with [inside? = TRUE and not member? self [poacher-memory] of myself] ifelse any? surroundings [ move-to rnd:weighted-one-of surroundings [patch-attractiveness] ] [ move-to rnd:weighted-one-of neighbors with [inside? = TRUE] [patch-attractiveness] ] end to poacher-decision-making let nearby-rangers (turtle-set rangers camps) if any? nearby-rangers in-radius poacher-vision [ ; look around and see if any rangers are nearby set failure-sites (patch-set failure-sites poacher-memory) ; remember this patch as failure-sites set state "journey-after-crime" ] ; when poacher spots a ranger or camp he will get out of reserve let surroundings patches in-radius poacher-vision with [inside? = TRUE] ask surroundings [ let rhino-signs (recent-rhino-activity / (rhino-activity-decay * 2)) * hunt-rhino-weight let nearby-ranger-signs ((human-signs-decay - ranger-signs) / human-signs-decay) * ranger-avoid-weight let estimated-roughness ((max-roughness - roughness) / max-roughness) * roughness-weight let estimated-resources resources * resources-weight set patch-attractiveness (ranger-dist + rhino-signs + nearby-ranger-signs + estimated-resources + estimated-roughness) / poacher-weight if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] ask surroundings with [member? self [poacher-memory] of myself] [ set patch-attractiveness patch-attractiveness / 10 ] set poacher-goal rnd:weighted-one-of surroundings [patch-attractiveness] ; the higher patch attractiveness, the more likely the poacher will go there ifelse member? poacher-goal neighbors [ ; if the goal is a neighbouring patch... move-to poacher-goal] ; move to that patch [ poacher-movement ] ; otherwise get closer to the goal patch end to-report ranger-dist let nearby-rangers (turtle-set rangers camps) ifelse any? nearby-rangers [ let max-ranger-dist distance min-one-of nearby-rangers [distance myself] ifelse max-ranger-dist != 0 [ report (distance min-one-of nearby-rangers [distance myself] / max-ranger-dist) * ranger-avoid-weight ] [ report 0 ] ] [ report 0 ] end to-report other-patrol-dist let nearby-rangers (turtle-set other rangers camps) ifelse any? nearby-rangers [ let max-ranger-dist distance min-one-of nearby-rangers [distance myself] ifelse max-ranger-dist != 0 [ report (distance min-one-of nearby-rangers [distance myself] / max-ranger-dist) * ranger-avoid-weight ] [ report 0 ] ] [ report 0 ] end to poacher-kills-rhino let target one-of rhinos in-radius 1.5 move-to target ; go to where the rhino is ask target [if herd-size >= 1 [set herd-size herd-size - 1] ; JJJJ if herd-size = 0 [die]] set poacher-goal patch-here ; update poacher goal set success-sites (patch-set success-sites patch-here) ; remember these patches as successful kill sites set poacher-memory no-patches ; no need to remember the route, only the success site matters now set state "journey-after-crime" ask patch-here [ set poacher-signs poacher-signs + carcass-decay ; rhino carcass is an important sign of poaching ] end to poacher-laylow pen-up if poacher-goal = patch-here and state = "journey-after-crime" [ ; if the poacher has escaped the reserve and obtained a horn set laylow laylow - 1] ; lay low and wait until it's time again if (laylow = 0) [ ; when the waiting is done or when the poacher was unsuccessful... poacher-plan-new-trip ; try again. ] end to poacher-plan-new-trip let good-options (patch-set success-sites good-sites) ; IF - no signs of rangers or rhinos, then pick a random spot along the border ifelse good-options = nobody or count good-options = 0 [ move-to one-of patches with [inside? = FALSE and not member? self [failure-sites] of myself] ] ; ELSE - make a weighted decision on where to enter next [ let new-trip-weight success-weight + hunt-rhino-weight + ranger-avoid-weight ask good-options [ let recent-rhino-kill (poacher-signs / carcass-decay) * success-weight let detected-rhino-signs (recent-rhino-activity / (rhino-activity-decay * 2)) * hunt-rhino-weight let detected-ranger-signs ((human-signs-decay - ranger-signs) / human-signs-decay) * ranger-avoid-weight set patch-attractiveness (recent-rhino-kill + detected-rhino-signs + detected-ranger-signs) / new-trip-weight if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] let best-option max-one-of good-options [patch-attractiveness] ; this compares the best option with a random number. ; IF - random number is smaller than the patch-attractiveness of the best option, he will choose among the available options ifelse random-float 1 < [patch-attractiveness] of best-option [ move-to rnd:weighted-one-of good-options [patch-attractiveness] move-to one-of patches in-radius 1.5 move-to min-one-of patches with [inside? = FALSE] [distance myself]] ; ELSE - random number is higher than highest patch-attractiveness, and poacher will pick a random location [ move-to one-of patches with [inside? = FALSE] ] ] set state "journey-to-crime" set laylow (poacher-time * 2 ) + random 100 ; reset the poacher-own parameters set time 0 ; set poacher-memory no-patches set poacher-goal patch-here end to ranger-goal-check pen-down ; IF - ranger is moving through rough terrain ifelse ticks-wait > 0 [ set ticks-wait ticks-wait - 1 ] [ ; ELSE - rangers will move and make decisions let target one-of poachers in-radius ranger-vision with [inside? = TRUE] ; are there any poachers around? ifelse target != nobody [ rangers-catch-poachers ] ; IF - ranger has time to patrol [ if state = "patrolling" [ ; select the type of patrol we specified in the patrol-type menu ifelse patrol-type = "standard-patrol" [ ranger-patrol ] [ ranger-fence-patrol ] ] if state = "follow-up" [ ranger-follow-up ] ; ELSE - no time is left he will move to the nearest patch outside the reserve or camp if state = "back-to-camp" [ ranger-to-camp ] if patrol-time >= patrol-length [ set state "back-to-camp" ] if roughness > 1 [ set ticks-wait ticks-to-stay-on-patch patch-here ] ] ] ask patch-here [ if random-float 1 < 0.5 [ ; 50% chance of... set ranger-signs human-signs-decay ; ...dropping poacher activity signs ] ] if any? poachers in-radius ranger-vision with [inside? = TRUE] [ rangers-catch-poachers ] set patrol-time patrol-time + 1 ; time is passing by set patrol-memory (patch-set patrol-memory patch-here) ; remember the current patch if poacher-signs > 0 [ set risky-areas (patch-set risky-areas patch-here) if (member? patch-here [risky-areas] of self) and (member? patch-here [safe-areas] of self) [ set safe-areas safe-areas with [[patch-here] of myself != self]] ] let new-rhino-sighting any? rhinos-on neighbors if new-rhino-sighting = TRUE [ set rhino-sightings (patch-set rhino-sightings neighbors) ] if poacher-signs = 0 [ set safe-areas (patch-set safe-areas patch-here) if (member? patch-here [safe-areas] of self) and (member? patch-here [risky-areas] of self) [ set risky-areas risky-areas with [[patch-here] of myself != self]] ] end to ranger-to-camp let closest-border min-one-of patches with [ inside? = FALSE ] [ distance myself ] ; calculate distance to nearest border let closest-camp min-one-of camps [ distance myself ] ; calculate distance to nearest camp ifelse distance closest-border < distance closest-camp ; compare the two and set goal to the nearest [ set ranger-goal closest-border ] [ set ranger-goal closest-camp ] ifelse distance ranger-goal <= 1 [ ; if the goal is a neighbouring patch... move-to ranger-goal] ; move to that patch [face ranger-goal ; otherwise get closer to the patch forward 1] end to ranger-patrol ; IF - ranger completed his goal in life ifelse ranger-goal = patch-here [ ranger-decision-making] ; do brave ranger things ; ELSE - if ranger is still moving towards goal ; IF - ranger is within reach of his goal [ifelse member? ranger-goal neighbors [ move-to ranger-goal ] [ ranger-movement ] ] end to rangers-catch-poachers let suspect one-of poachers in-radius ranger-vision with [inside? = TRUE] move-to suspect ; go to where the poacher is ask suspect [ die ] ; catch him set risky-areas (patch-set risky-areas patch-here) ; remember these patches as risky areas set ranger-goal patch-here set state "back-to-camp" ask patch-here [ set ranger-signs ranger-signs + 500 ] pen-up move-to min-one-of camps [distance myself] end to ranger-movement if any? poachers in-radius ranger-vision with [inside? = TRUE] [ ; look around and see if any poachers are nearby set risky-areas (patch-set risky-areas patrol-memory) ; remember this patch as risky-sites ] let max-goal-dist distance ranger-goal ask neighbors with [inside? = TRUE] [ let goal-dist (max-goal-dist - distance [ranger-goal] of myself) * goal-weight let rhino-signs (recent-rhino-activity / (rhino-activity-decay * 2)) * search-rhino-weight let nearby-poacher-signs catch-poacher-weight - ((human-signs-decay - poacher-signs) / human-signs-decay) * catch-poacher-weight ;;FIX 2-12-2017 added catch-poacher-weight - ... (3-) let estimated-roughness ((max-roughness - roughness) / max-roughness) * roughness-weight set patch-attractiveness (goal-dist + estimated-roughness + other-patrol-dist + rhino-signs + nearby-poacher-signs) / (ranger-weight + goal-weight) if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] let surroundings neighbors with [not member? self [patrol-memory] of myself] ifelse any? surroundings [ move-to rnd:weighted-one-of surroundings [patch-attractiveness] ] [ move-to rnd:weighted-one-of neighbors [patch-attractiveness] ] end to ranger-decision-making if any? poachers in-radius ranger-vision [ ; look around and see if any poachers are nearby set risky-areas (patch-set risky-areas patrol-memory) ; remember this patch as risky-sites ] let surroundings patches in-radius ranger-vision with [not any? camps-here and inside? = TRUE] ask surroundings [ let rhino-signs (recent-rhino-activity / (rhino-activity-decay * 2)) * search-rhino-weight let nearby-poacher-signs catch-poacher-weight - ((human-signs-decay - poacher-signs) / human-signs-decay) * catch-poacher-weight ;;FIX 2-12-2017 added catch-poacher-weight - ... (3-) let estimated-roughness ((max-roughness - roughness) / max-roughness) * roughness-weight set patch-attractiveness (other-patrol-dist + rhino-signs + nearby-poacher-signs + estimated-roughness) / ranger-weight if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] ask surroundings with [member? self [patrol-memory] of myself] [ set patch-attractiveness patch-attractiveness / 10 ] set ranger-goal rnd:weighted-one-of surroundings [patch-attractiveness] ; the higher patch attractiveness, the more likely the poacher will go there ifelse member? ranger-goal neighbors [ ; if the goal is a neighbouring patch... move-to ranger-goal] ; move to that patch [ ranger-movement ] ; otherwise get closer to the goal patch end to-report fence? [angle] ;; turtle procedure ;; note that angle may be positive or negative. if angle is ;; positive, the turtle looks right. if angle is negative, ;; the turtle looks left. report black = [pcolor] of patch-right-and-ahead angle 1 end to ranger-fence-patrol ;; turn right if necessary if not fence? (90 * direction) and fence? (135 * direction) [ rt 90 * direction ] ;; turn left if necessary (sometimes more than once) while [fence? 0] [ lt 90 * direction ] ;; move forward fd 1 if poacher-signs > 0 [ ranger-follow-up set patrol-time 0 set state "follow-up"] end to ranger-follow-up ; follow poacher spoor, otherwise look around for spoor let poacher-spoor neighbors with [poacher-signs >= 1 and inside? = TRUE] ifelse any? poacher-spoor with [not member? self [patrol-memory] of myself] [ move-to max-one-of poacher-spoor [poacher-signs]] [ ranger-movement ] end to ranger-end-patrol ; rangers will rest for a certain amount of time before starting a new patrol ???? add intervals at ranger-time. Give each a varying wait buffer? pen-up if state = "back-to-camp" and ranger-goal = patch-here or ranger-goal = one-of camps in-radius 1 [ set off-duty-time off-duty-time - 1 ] if off-duty-time = 0 [ ;;???? add intervals by letting some of them start with off-duty time >1!!! (how to do this for each turtle specifically though, and does it work at 1st patrol? Also have to change state of some at start ctrl f in desctription) ranger-new-patrol ] end to ranger-new-patrol let options rhino-sightings with [not member? self [safe-areas] of myself] let good-options (patch-set options risky-areas) ; IF - no signs of poachers or rhinos, then pick a random spot along the border ifelse good-options = nobody or count good-options = 0 [ move-to one-of patches with [not member? self [safe-areas] of myself] ranger-start-location ] ; ELSE - make a weighted decision on where to enter next [ let new-patrol-weight search-rhino-weight + catch-poacher-weight ask good-options [ let detected-rhino-signs (recent-rhino-activity / (rhino-activity-decay * 2)) * search-rhino-weight let detected-poacher-signs ((human-signs-decay - poacher-signs) / human-signs-decay) * catch-poacher-weight set patch-attractiveness (detected-rhino-signs + detected-poacher-signs) / new-patrol-weight if patch-attractiveness < 0 [ set patch-attractiveness 0 ] ] let best-option max-one-of good-options [patch-attractiveness] ; this compares the best option with a random number. ; IF - random number is smaller than the patch-attractiveness of the best option, he will choose among the available options ifelse random-float 1 < [patch-attractiveness] of best-option [ move-to rnd:weighted-one-of good-options [patch-attractiveness] move-to one-of patches in-radius 1.5 ranger-start-location] ; ELSE - random number is higher than highest patch-attractiveness, and poacher will pick a random location [ move-to one-of patches with [not member? self [safe-areas] of myself] ranger-start-location] ] end to ranger-start-location ; IF - the nearest border is closer than the nearest camp let closest-border min-one-of patches with [ inside? = FALSE ] [ distance myself ] let closest-camp min-one-of camps [ distance myself ] ifelse patrol-type = "fence-patrol" [ move-to closest-border move-to one-of neighbors with [inside? = TRUE] ] [ ifelse distance closest-border < distance closest-camp [ move-to closest-border ] ; ELSE - move to the nearest camp when nearest border is too far [ move-to closest-camp] ] set patrol-time 0 set patrol-memory no-patches ifelse coordinated = false [set off-duty-time (patrol-length * 2) + random 100] [set off-duty-time patrol-length * 2] ; JJJJ ;set off-duty-time ( patrol-length * 2 ) + random 100 set ranger-goal patch-here set state "patrolling" ifelse random 2 = 0 [ set direction 1 ] [ set direction -1 ] face one-of neighbors4 end to update-activity-signs ; after every 12 ticks, remove decrease signs of rhinos, poachers, and rangers if recent-rhino-activity > 0 [set recent-rhino-activity recent-rhino-activity - 1] if ranger-signs > 0 [set ranger-signs ranger-signs - 1 ] if poacher-signs > 0 [set poacher-signs poacher-signs - 1 ] end ;****CHECKLIST**** ;["poacher-vision" 1.5] ;["rough-areas" 2] ;["success-weight" 2] ;["forage-amount" 1] ;["num-rhinos" 70] ;["num-poachers" 1] ;["goal-weight" 2] ;["hunt-rhino-weight" 2] ;["ranger-avoid-weight" 3] ;["catch-poacher-weight" 3] ;["roughness-weight" 2] ;["num-camps" 1] ;["resources-weight" 3] ;["patrol-length" 50] ;["rhino-avoid-weight" 2] ;["sandy-areas" 5] ;["num-rangers" 2 4] ;["visualization" "resources_colors"] ;["search-rhino-weight" 2] ;["ranger-vision" 1.5] ;["camp-placement" "random"] ;["poacher-time" 50] ;["patrol-type" "standard-patrol"] ;repetitions: 100 ;Run combinations in sequential order: checked ;Measure: ;count rhinos ???? [No herds this starts out with 70, so x/70 killed. With herds this starts out at 350, so x/350 killed. Or compare 70 indivs with 70/5=14 herds? Many more locations for indivs in that case] ;count poachers ;Measure runs at each step: checked ;Setup commands: ;setup-park ;setup-rhino ;setup-humans ;Go commands: ;go ;Stop condition: ;count rhinos = 0 or ;count poachers = 0 ;Time limit: 10000 ; ASK NICK BURN IN ????
There are 3 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Exploring Anti-poaching Strategies for Wildlife Crime with a Simple and General Agent-Based Model _ SpringerLink.html | html | Published Article using this Model | almost 8 years ago, by Nick van Doormaal | Download |
Indepth Model Guide and Explanation - Rhino Poaching.pdf | In-depth Model Guide and Explanation for Rhino Poaching | about 8 years ago, by Nick van Doormaal | Download | |
Rhino Poaching.png | preview | Preview for 'Rhino Poaching' | over 8 years ago, by Nick van Doormaal | Download |
This model does not have any ancestors.
This model does not have any descendants.