Home > other >  In NetLogo, how to cycle through an agentset and check conditions before performing an action if tru
In NetLogo, how to cycle through an agentset and check conditions before performing an action if tru

Time:01-04

I'm building a model loosely based on the Sugarscape model to look at corporate takeovers. I need to check the attributes of a neighbouring turtle, perform a calculation on it's attributes and then choose if the acting turtle wishes to eat the neighbouring turtle. I'm having some trouble extracting the relevant information as I'm unfamiliar with the data structures and how to cycle through each individual agent in the agentset.

I want to extract the breed, vision, metabolism and current sugar balance from each agent in the agentset, perform a calculation using both this information and information about the acting turtle and then eat the 'best' one if they meet certain conditions.

to financials-kill ;; turtle proceedure
  ;; buy another company
  let candidates []
  ask neighbors4 [
    ask turtles-here [set candidates fput self candidates]
  ]
  foreach candidates[
    let best-candidate max-one-of candidates with 

;; checking some conditions etc here and performing the calculations but unsure how to proceed

    if breed of candidates = financials[
      ; 
    ]
    if breed = healthcare [ ]
  if breed = industrials [ ] 
  print candidates 
end

In python, I would cycle through each of the individual agents in the agentset using a counter and have an array storing the 'fitness' of the agent and some identifying number but having looked at the documentation, I can't see how to do this.

Any pointers would be great thanks!

CodePudding user response:

So, the main structure to use when dealing with groups of turtles in the "agentset". Many NetLogo primitives take or report agentsets. An agentset can contain zero, one, or many agents.

The TURTLES-ON reporter takes a turtle or patch or set of either, as input, and reports an agentset containing the turtles standing on those patches, or standing on the same patches as those turtles.

The WITH operator reports an agentset containing those members of the agentset on the left side that report TRUE as the result of the expression on the right side. Example: turtles with [ color = blue ]

The OF operator reports the value of the expression on the left, as evaluated by the agent or agentset on the right. If an agentset, the result is a list of the values. Note that the expression is actually evaluated by the agent--if the expression has 'side effects' they will apply to that agent.

So, usually, we just use the agentset, we don't bother converting it to a list.

If we need a list of agents, there a a handful of primitives do to that:

let t (turtles-on neighbors4) ;; the set of turtles standing on this
                              ;; turtle's 4 neighboring patches
[ self ] of t      ;; list of turtles in random order
sort t             ;; list of turtles sorted by WHO
sort-on [ xcor ] t ;; list sorted by value of that expression
                   ;; as evaluated by the individual turtles
sort-by ...        ;; sort using more complex criteria

So, a general pattern might be:

ask <agentset>
[
  let candidates <another agentset> with [ <critiera> ]
  if any? candidates 
  [ let selected <some expression that selects one agent>
    ;; this agent can access the selected agent's properties using OF
    set energy energy   [ energy ] of selected
    ;; this agent can command the selected agent to do things:
    ask selected
    [ set energy 0
      ;; this agent can access the "calling" agent using MYSELF
      show (word myself " ate me.")
      die ;;
    ]
    ;; "selected" now refers to a dead turtle. Don't use it again.
 ] 

So your example might look like this:

to financials-kill ;; turtle procedure
  ;; buy another company
  let candidates turtles-on neighbors4
  ;; make sure there are actually some candidates
  if any? candidates
  [ let best max-one-of candidates [ cash ]
    ;; take their cash
    ;; add their cash to my cash
    set cash cash   [ cash ] of best
    ;; set their cash to 0
    ask best [ set cash 0 ]
    ;; they have no cash, they are defunct, and vanish
    ask best [ die ]
   ]
end

Your question, though, doesn't just want to use cash-- you want to perform some evaluation, and pick the one that gets the best result. For that, I'd make a reporter that does the valuation, and reports the result. You can refer to the calling agent using MYSELF. You may need two reporters: one that reports true/false to select possible candidates, and another that reports a value to select the best of those candidates.

to potential-takeover
  if breed = financials and income > [ income ] of myself
  [ report true ]
  if cash > [ debt ] of myself [ report true ]
  ;; otherwise
  report false
 end

 to-report max-value
    report (cash - debt) - [ debt ] of myself        
 end

now you can do something like

let candidates turtles-on neighbors4 with [ potential-takeover ]
if any? candidates
[ let target max-one-of candidates [ takeover-value ]
 ...
 ]

Last, I see you are trying to use breeds. Breeds should be treated like agentsets. So you can do things like:

ask financials [ .... do things ]

or

if any? industrials-here [ .... ]

and so on.

CodePudding user response:

Your example is very vague and also quite unclear: given that we don't know how you want to use turtles' values, I will simply include a generic case (you should aim at providing a minimal and reproducible example. This also includes providing working code - except from the part for which you are seeking help, of course).

First, some notes:

  • Using turtles-on is a much more efficient and clearer choice than the way you build your candidates list.
  • Check more closely what foreach does: it takes a list as input, and it runs some commands for each item of the list. Based on what I can guess from your example, you are not taking into account that every turtle in the candidates list will be executing let best-candidate max-one-of candidates with ... etc.
  • The part where you check breeds is very unclear and contains errors, which means that it is also hard to guess what you want to achieve there. Again, providing a working example of your problem helps others help you, and helps you isolate what you need to fix.

That said, see below a fully-working, although generic, example of how to achieve something like what you said (e.g. performing some selection based on both the acting-turtle's variables and its targets' variables etc). Please also see comments in there:

turtles-own [
  the-value
  targets
  chosen-one
]

to setup
  clear-all
  create-turtles 100 [
    setxy random-xcor random-ycor
    set the-value random 70
  ]
end


to go
  ask turtles [
    evaluate-targets
  ]
end


to evaluate-targets
  ; Just clearing 'targets' and 'chosen-one' here, to make sure there is no weird behaviour across iterations if you try this
  ; multiple times.
  set targets (list)
  set chosen-one NOBODY
  
  ; Using 'turtles-on' is much more convenient than doing the same thing by asking patches to ask turtles to deal with lists.
  let potential-targets turtles-on neighbors4
  
  ; The 'foreach' primitive takes a list as input (this is why I use 'sort': not because I really want to sort the agents, but
  ; because it turns the 'potential-targets' agentset into a list of agents) and runs the command block for each item of the
  ; list. In this case, each agent in 'potential-targets' in turn is identified by 'pt', and the if-statement is executed taking
  ; into account that current 'pt'.
  foreach (sort potential-targets) [
    pt ->
    if ([the-value] of pt > the-value) [
      set targets (lput pt targets)
    ]
  ]
  
  ; Note that, referring to the code above, if we wanted to be brief we could simply do:
  ;   foreach (sort turtles-on neigbors4) [...]
  
  ; Now you can just do whatever you want with 'targets', including choosing one of those agents based on some criterion...
  set chosen-one max-one-of (turtle-set targets) [color]
  
  ; ...and doing something with it:
  if (is-turtle? chosen-one) [
    ask chosen-one [
      set shape "star"
    ]
  ]
end
  •  Tags:  
  • Related