Nicola Pensiero
Nicola Pensiero

Reputation: 31

Linking turtles to another turtle with highest value in NetLogo. Limit the number of links

I am a beginner with NetLogo and I am trying to ask some turtles (students from different social classes) to link to other turtles (schools). What I would like is for the working class students to look for the school with the highest achievement which is at the same not expensive and has not reached the max number of links allowed. If the desired school has reached the max number of links allowed I want the student to look for the next school with the highest achievement which has not reached the max number of links allowed and so on.

This is the code. I get the following message "ANY? expected input to be an agentset but got the turtle (school 1) instead."

breed [schools school] 
breed [upperclass upperclass-student]
breed [workingclass workingclass-student]

upperclass-own [achievement enrolled? target]
workingclass-own [achievement enrolled? target]
schools-own [schoolachievement  expensive? ]
 
to setup
   clear-all
   set-default-shape schools "house"
   set-default-shape upperclass "person"
   set-default-shape workingclass "person"
   ask patches [ set pcolor 8 ]
   create-schools num-of-schools [ setxy random-xcor random-ycor set schoolachievement random-normal 5 1 
   set expensive? one-of [ true false ] ]
   create-upperclass num-of-upperclass [ set color white setxy random-xcor random-ycor set achievement 
   random-normal 5 1  ] ;Students from upper class have higher achievement
   create-workingclass num-of-workingclass [ set color red setxy random-xcor random-ycor set achievement 
   random-normal 4 1  ]
end

to go
    ask workingclass [ 
    choose-school ]  
end

to choose-school
      if breed = workingclass [
      set target one-of schools with-max [ schoolachievement ]  with [ expensive? = false ] ]
      if any?  target  with [ count link-neighbors  < max-link-count ]   [
      create-link-with target ]
      set enrolled? TRUE
end

Upvotes: 1

Views: 199

Answers (1)

JenB
JenB

Reputation: 17678

Your problem is the difference between an agent and an agentset, which is a somewhat subtle problem. The with-max returns an agentset - a set of agents (in this case turtles). That agentset can have 0 members, 1 member, 2+ members but is a set even if it is empty. However, the one-of selects one agent from the agentset and returns it as an agent, not an agentset. That is, NetLogo knows anything that is returned by one-of must be exactly one agent. At this point, primitives that are for agentsets (like any?) will throw an error unless they can also be used on individual agents.

So, back to your code. I like the readability of checking whether there are viable schools and then selecting one, which is what I think you meant to do. That would be:

to choose-school
    if breed = workingclass
    [ set targets schools with-max [ schoolachievement ]  with [ expensive? = false ]
      set candidates targets with [ count link-neighbors  < max-link-count ]
      if any? candidates
      [ create-link-with one-of candidates
        set enrolled? TRUE
      ]
    ]
end

Note that I also changed to targets instead of target, which is one way to keep track of whether something is an agent or an agentset.

The other way you could do this and keep it as an agent is:

to choose-school
      if breed = workingclass [
      set target one-of schools with-max [ schoolachievement ]  with [ expensive? = false ] ]
      if target != nobody and [count link-neighbors] of target < max-link-count   [
      create-link-with target ]
      set enrolled? TRUE
end

So you can use nobody instead of any? but you can't also use with in that line because the with is really a filter on a set.

I also think you have a bracketing issue - I assume you want set enrolled? TRUE inside the brackets. I left it in the second fix, but changed in the first error (as well as changing bracket position convention to make the code block structure more visible)

Upvotes: 2

Related Questions