jova95
jova95

Reputation: 33

how to make turtles who satisfy a condition move with NetLogo

I'm currently working on a project with NetLogo. Long story short: I have a certain number of turtles spread across the first half of my world. The objective is to make the turtles move on the other half of the world if they satisfy a certain condition (a mathematical one). The problem that i'm ecountering is that I want just the turtles who satisfy the condition to move to the other half (so I assume it will be a subgroup of turtles whom dimension will depend on which value of "free income" I select through the slider), but in reality what happens is that if at least one of them satisfy the condition then ALL the turtles move. That's not what I want. I was thinking to use the function "breed" but I am not sure how to implent it. Here is the code :

globals
[
  lazyness-coefficient 
  fatigue-of-work     ; cost associated with looking for work and the activity of working
  free-income
  working-income
]


turtles-own
[
  condition                       ; condition = 1 if the subject works, 0 if the subject is unemployed
  utility-value-working-income    ; utility associated with working or being unemployed while receiving a subsidy
  utility-value-free-income
]



;;;
;;;
;;;

to setup
  clear-all
  set free-income free-income-slider       ; mettere slider
  set working-income working-income-slider ; mettere slider
  setup-turtles
  setup-patches
  reset-ticks
end

to setup-patches
  ask patches [ set pcolor black]
end

to setup-turtles
 create-turtles 500
  [
    set shape "person"
    set color green
    set size 1.5
    set condition 0
    setxy random 64 random 32
    set utility-value-free-income free-income ^ 2 + free-income + random-float 1000
    set utility-value-working-income 0
  ] 
end

to go
  let target any? turtles with [utility-value-free-income > 14000]
  if utility-value-free-income > 14000
  [move-target]
end

to move-target
    setxy random 64 random 64
    set color blue 
end

The condition in this case is the following: If the turtle has an utility value (which is of the type: x^2 + x + r, where r is a random factor) higher than 14000 then set color blue and move to the other half. This condition is just a try, in the final project the condition will be: if the ration of the free income utility and the working income utility is higher than 1 then move to the other half and set the colour of that particular turtle blue.

I hope I have explained it clearly, thanks everybody.

Upvotes: 2

Views: 774

Answers (3)

Matteo
Matteo

Reputation: 2926

The answer by Jumboman addressed the most practical aspect and told you what to do, but I want to include some further perspective to let you understand what is going on, given that it is something which is easy to struggle with at the beginning.

The heart of the problem is your to go but, as you can see, NetLogo is not warning you with any syntax error - because actually there is none! This is very much linked to the nature of your problem, i.e. all of the turtles performing the action (instead of just those that satisfy the condition).

To understand why, we should take a step back: you should always pay particular attention to the context from which procedures are executed (i.e. which type of agents is performing the action).

In NetLogo, there are four types of agents: turtles, patches, links, and the observer. The code is always written from the perspective of the observer (i.e. you). This is why, if you want other agents to do things, there is the need for you to ask those agents to do those things. You can ask turtles to ask patches to ask links to ask some turtles to do things but, ultimately, every chain of ask starts from the observer.

NetLogo, however, also tries to guess who you want to perform your procedures. In this case, given that to go uses turtles-own variables (i.e. utility-value-free-income and color, the latter from within move-target) and calls a primitive that can be used only by turtles (i.e. setxy from within move-target), NetLogo is assuming that to go belongs to the turtle context.

This means that, when performing to go, every single turtle will do what to go says. More specifically, this means that every single turtle will evaluate the let target statement, and then every single turtle will perform to move-target.

However this also means that, although to go does not give any syntax error as it is, you should have probably noticed something else weird going on in the first place. Being to go a turtle-only procedure as of now, you should see that if you add a go button in the Interface (which is standard practice) you'll get an error. The Interface, in fact, is observer-only context (so buttons are observer-context by default, i.e. unless you don't change their context manually). You would get an error typing go in the Command Center too (observer-only context by default too) as well as trying to insert go in setup.

This will be solved by making to go observer context, i.e. by calling it from anywhere which is observer context + using ask turtles as Jumboman showed.

Another thing that is implicit in Jumboman's answer but which you need to explicitely understand, is what's wrong with the actual lines of code inside to go. The issue with any? was hinted at by JenB:

You clearly had the intention of creating an agentset called target; however, any? only ever reports true/false. This means that, as JenB said, target will not store any agentset but just a true/false value.

Regardless of this, however, it remains the fact that your code creates this target variable but never really uses it. In fact, the fact that you included the word "target" in the name of a procedure (move-target), doesn't make this procedure automatically use the variable named target. So, even if target was an agentset, move-target would not automatically refer to target (for that matter, you could have given these two elements totally random names and it would have been the same).

To do so, you would have to do

to move-target
 ask target ...
end

However, as you've already been suggested, with is the tidiest way to do the job. Overall, the sum of all these things above is why you should just do:

to go
 ask turtles with [utility-value-free-income > 14000] [
   setxy random 64 random 64
   set color blue
 ]
end

PS: As for the context thing, I developed the habit of always writing a comment, next to the declaration of each procedure, specifying the context that such procedure belongs to. This becomes particularly useful for speeding up the readability of your code and for some debugging, as your model builds up with lots and lots of procedures.

Upvotes: 1

Jumboman
Jumboman

Reputation: 551

You're making it too complicated. The Ask keyword allows you to specify a filter.

to go   
  ask turtles with [utility-value-free-income > 14000]
  [
    setxy random 64 random 64
    set color blue   
  ] 
end

should do the trick.

Upvotes: 2

JenB
JenB

Reputation: 17678

This is the key procedure:

to go
  let target any? turtles with [utility-value-free-income > 14000]
  if utility-value-free-income > 14000
  [move-target]
end

Working through each line:

  1. creates a variable called 'target' and assigns it the value true or false` depending on whether there are any turtles with high enough income
  2. this should generate a syntax error - assuming that 'utility-value-free-income' is a turtle attribute (which is must be because otherwise line 1 doesn't make sense), then this line is an error because you haven't told NetLogo which turtle to look at to run the test.
  3. runs the code at 'move-target' if the line 2 condition is true

I usually recommend that novice NetLogo modellers avoid breaking things across too many procedures. Think about this conceptually, what you want is to move the turtles that meet some condition. It's one concept, make it one procedure. Something like this:

to go
  move-rich-turtles
end

to move-rich-turtles
  let movers turtles with [utility-value-free-income > 14000] 
  ask movers
  [ setxy random 64 random 64
    set color blue
  ]
end

Upvotes: 0

Related Questions