Calculating & reporting land-rent of patches in a certain radius around the agent's movement-radius

Viewed 96

Summary

I'm developing a land-use model with a forested World and turtles that have the ability to convert the forest into crop land. Turtles (in this specific case companies) have the ability to move to a destination-patch within their range of mobility and clear the forest in a radius around them (to turn it into cropland). The goal is to have the companies choose their destination-patches based on the predicted profit from converting the patches around it, i.e., making economical decisions as to where to move in the landscape. Profit (or land-rent in my model) is a function of cost of conversion, maintenance cost, and potential penalties, subtracted from the patch-yield. Thus, the ideal destination-patch is a patch whose cluster of patches around it has the highest sum of predicted profits. I made a little figure to help visualizing the concept: concept of cluster profit in radius

What I did so far So far, I have the following procedures relevant to seeking the maximum land-rent patch: 1) moving the companies to the patch with the maximum predicted land rent 2)reporting the maximum predicted land rent, using a to-report function. I've also tried a ask-patches function instead, but to no avail. Patches have a penalty associated to them, depending on whether they are part of a protected area, and can be owned-by a certain actor (depending on where they are located and who converts them).

Problem/Goal What I need is a structure that asks each patch within a given radius of the turtle (company) to calculate the land-rent for each patch in another given radius. In other words, I want the turtle to be able to say: if I go to this patch xy which is in my radius of movement, I get the maximum land-rent out of converting all the patches around that patch xy. The code below does not produce any error messages, but from the turtles behavior, it doesn't seem it's running correctly either. Turtles move across the World randomly, and directly run into areas that are protected (incurring heavy fines for encroaching), causing them to go bankrupt.

patches-own
owned-by                  ;; "R" indicated it's unoccupied forest
protected-area            ;; whether the patch is part of a protected area 
encroachment-fine         ;; the $-amount a turtle is fined for converting this patch of forest

GUI inputs
company-conversion-radius ;in what radius around themselves companies can convert land


to move-to-max-rent-C
    ifelse any? patches in-radius (company-conversion-radius * 2 - 1) with [owned-by = "R"] [ ;here, companies 'scan' their environment for any patches that have forest (expressed through owned-by = "R"), if there are forested patches, companies move to the destination-patch that promises the highest profit (land-rent)   
      let destination-C max-rent-C
      move-to destination-C
    ]
  
;; if no forest patch within their scanning-radius, they face the nearest forest patch anywhere and move towards it
  [
    face min-one-of patches with [owned-by = "R"] [distance myself]
    move-to patch-ahead company-conversion-radius                                      
     ]                                                                                  
end

to-report max-rent-C
  ask patches in-radius (company-conversion-radius * 2 - 1) [
    let available-conversion-patches count patches in-radius company-conversion-radius with [owned-by = "R"]                  
    report max-one-of patches in-radius company-conversion-radius with [owned-by = "R"] [;;formula for calculating land rent] 
  ]
end

I found this thread ask turtle to perform calculations from patch set, but it seemed not to quite answer my problem as it only ask for calculations around the turtle, not around the patches the turtle can reach.

2 Answers

assuming that the radius is the same for all companies, I would probably have each patch own its value as a variable. then you can just choose the one with the highest in a seperate function. also it seems like the movemtent range for companies is now equal to the conversion range. I would expect these to be different things, so I would use different names even if they have the same value. I split it up in my code to make it clearer. you should also be aware that what you are asking can be computationally expensive. if N companies are asking M patches what the combined value of P surrounding patches is, you are doing N * M * P calculations. if your program is running slow, this is probably causing it.

generaly I would think that your code would look something like:

patches-own 
rent-value ;the value of this specific tile
HQ-value ;the value of making this a destination patch

to update-value
  ask patches [ ; ask every patch to update its HQ value
    set HQ-value 0
    ask patches in-radius company-conversion-radius [ ; by summing over the rent-value of its radius
      set HQ-value of [myself] HQ-value of [myself] + rent-value
      ;you could incorporate your protections and penalties here too.
    ]
  ]

this should cause ALL patches to update their HQ-value. if you have few companies and many patches, it will be faster to ask turtles to do the following:

to update-value
  ask turtles [ 
    ask patches in-radius company-movement-range [ 
      set HQ-value 0
      ask patches in-radius company-conversion-radius [ 
      ;...

You're almost there (I think). I can't run your code, but from reading it, the max-rent-C procedure will correctly identify the patch in a given radius that returns the best profit. Your problem is that you aren't calling that procedure the right way. Imagine a turtle is at patch A, and has the opportunity to move to patch B but wants to select the B that gives the most profit. What that turtle has to do is to imagine itself at all the possible patch Bs and calculate the profit from all the patches around it while at that location. This is what you said in your question, but restating it for clarity.

So instead of asking from A for the maximum, it has to find the maximum that gives the maximum.

Instead of:

let destination-C max-rent-C

try:

let potential-destinations patches in-radius (company-conversion-radius * 2 - 1) with [owned-by = "R"]
let destination-C max-one-of potential-destinations [max-rent-C]
Related