User847462
User847462

Reputation: 81

NetLogo: ask turtle to perform calculations from patch-sets

I'm trying to get the hang of NetLogo and am in need of some assistance. I'm having turtles pick patches based on which is most "valuable." Value is determined by benefits versus costs of selecting patches, so I need turtles to do a bit of math. Basically, a turtle needs to:

  1. Identify a patch-set of available patches (patches not yet owned).
  2. Determine the benefit-to-me of each available patch. Each patch has a benefit of 0-1. To determine benefit-to-me, the turtle should calculate the mean benefit of the available patch plus that patch's neighboring patches in-radius 2 (to identify a cluster of high benefit patches in a moving windows fashion).
  3. Determine the cost-to-me of each available patch. For now, this is the distance of the patch from the turtle. (Cost-to-me will include additional considerations in future versions of this model.)
  4. Calculate which patch is most valuable as benefit-to-me / cost-to-me.

This works (or so I think--is this doing what I think it is?):

patches-own [
    benefit
    owner ]

to go 
    ask turtles [pick-patch]
end

to pick-patch
    move-to highest-value
end

to-report highest-value 
    let available-destinations patches with [owner = 0]  ;; I think this accomplishes step 1.
    report max-one-of available-destinations [(mean [benefit] of patches in-radius 2) / (distance myself + 1)]  ;; and I believe(?) this accomplishes step 2-4. (Note, "distance myself + 1" seems required since can't divide by 0.)        
end

But I'd like to separate out the benefit and cost portions:

to-report highest-value 
    let available-destinations patches with [owner = 0]  
    let benefit-to-me ...??  ;; code to assess "(mean [benefit] of patches in-radius 2)" for the patch-set of available-destinations?
    let cost-to-me ...??  ;; and code to assess "(distance myself + 1)" of available destinations?
    report max-one-of available-destinations (benefit-to-me / cost-to-me) ...??  ;; code to perform calculations based on benefit-to-me and cost-to-me?          
end

How do I complete this code to achieve the desired effect? And I'm guessing there could be multiple ways to approach this type of coding. Given that turtles will repeat finding "highest-value" thousands of times, what option is likely to be fastest to run? Thank you in advance!


Attempted revision to code: (Following up from Luke's answer, below.)

patches-own [
    benefit
    owner ]

to setup
    ask patches [ set owner nobody ]
end

to go 
    ask turtles [pick-patch]
    tick
end

to pick-patch                      ;;<-----noticing turtle will change _destination midway to traveling there...why?
    let _destination highest-value
    ifelse _destination != nobody [
    ask _destination [set pcolor red]  ;; added this as a check, and yes, red patch switches around before the turtle gets there sometimes.
    face _destination forward 1  
      if patch-here = _destination
        [ claim-patch _destination ]
    ]
    [stop] ;; if there is no _destination
end

to claim-patch [_patch]
     ask _patch [set owner myself]
     ;; and etc., turtle does several more things to claim patch, e.g., turn patch color of turtle
end

;;;; --reporters for calculations:-- 

to-report highest-value 
     let available-destinations patches with [owner = nobody]  
     report max-one-of available-destinations [benefit-to-me / cost-to-me]          
end

to-report benefit-to-me
     report mean [benefit] of patches in-radius 2
end

to-report cost-to-me
     report distance myself
end

Upvotes: 0

Views: 809

Answers (1)

Luke C
Luke C

Reputation: 10291

It seems like the use of distance myself in your "highest-value" reporter might be problematic- you should not get a divide-by-zero error unless the distance between the two agents referenced is actually 0, so it looks like your available patches are including the patch that the asking-turtle is currently on. If you are using a turtle's who to designate ownership, remember that there is almost always a turtle 0 around who will "own" all patches with "owner = 0". Avoid this by having patches set their "owner" variable to -1 or nobody, for example, in the initial setup.

If benefit of a patch is not based on the turtle itself, you could simplify a bit by having your reporter be just the "moving-window value" of that patch, by cutting the distance part of the reporter. That way, a turtle can just query the patch for its moving-window-value divided by distance. Quick example:

patches-own [
    benefit
    owner ]


to setup
  ca
  reset-ticks

  ask patches [ 
    set owner nobody 
    set benefit random-float 1 
    set pcolor benefit + 54
  ]

  crt 5 [ setxy (random 30 - 15)(random 30 - 15)
    ask patch-here [ 
      set owner [who] of myself
      set pcolor [color] of myself
    ]
  ]

end


to go 
    ask turtles [
      pick-patch
    ]
    tick
end


to-report moving-window-value 
  report mean [benefit] of patches in-radius 2  
end


to pick-patch

  let available-destinations patches with [ owner = nobody ]
  let best-patch max-one-of available-destinations [ moving-window-value / (distance myself) ]
  if best-patch != nobody [
    move-to best-patch 
    ask patch-here [ 
      set owner [who] of myself
      set pcolor [color] of myself
    ]
  ]
end

As far as separating out the cost and benefit- you could, but if cost is just distance, you don't need to calculate it as it's already a primitive. Unless you're using some other gradient like elevation, terrain type, etc, you can probably get away without storing your distance cost.

Upvotes: 1

Related Questions