sdaza
sdaza

Reputation: 1052

subsetting agentsets transforming a list of agents into an agentset

A toy example. There are two groups of people: A and B. Only A can say "hello" to people B. People walk around the world and meet each other. When people A meet people B, they say hello to them. Each person A record who was said hello to and the tick when that occurred. They cannot say hello to the same person until five new ticks happen. The procedures below only apply to people A.

Each time a person A say hello to a person B I define:

set tick-last-greeting lput ticks tick-last-greeting
set previous-person-b-greeted lput selected-person-b previous-person-b-greeted

Before the say-hello procedure happens again:

if (length  tick-last-greeting != [] and previous-person-b-greeted != []) [
  ; wait 5 ticks
  set temp (map [ticks - ? > 5] tick-last-greeting)
  ; filter the list, I don't know if there is a better way to do this
  set previous-person-b-greeted (map last filter [first ? = false] (map list temp previous-person-b-greeted)) 
  set tick-last-greeting (map last filter [first ? = false] (map list temp tick-last-greeting))
]

So, I get a list of people B that shouldn't be greeted by a person A but until five ticks happen. Here is my key problem: how to define an agentset that excludes the agents of the list previous-person-b-greeted.

set potential-persons-b targets-on (patch-set neighbors patch-here)
if (previous-person-b-greeted > 0) [

; Here, I get an error as expected
let who-previous-person-b [who] of previous-person-b-greeted 
set potential-persons potential-persons with [who != who-previous-person-b]
]

A possible solution: transform the list previous-person-b-greeted into an agentset (I don't know if there is simple way to do this).

Any ideas?

Upvotes: 4

Views: 1332

Answers (3)

sdaza
sdaza

Reputation: 1052

Finally, following your suggestions, I ended up with this solution:

set potential-persons-b sort (targets-on (patch-set neighbors patch-here))

if (previous-person-b-greeted != []) 
[

foreach previous-victimized-target
[ set potential-persons-b remove ? potential-persons-b]

set potential-persons-b turtle-set potential-persons-b
]

Here a more general solution using to-report:

to-report subsetting-agents [agent-set1 agent-set2]
  set agent-set1 sort agent-set1
  set agent-set2 sort agent-set2
  foreach agent-set2
  [ set agent-set1 remove ? agent-set1]
  set agent-set1 turtle-set agent-set1
  report agent-set1
end

Upvotes: 0

Seth Tisue
Seth Tisue

Reputation: 30453

To transform a list of agents into an agentset, use turtle-set or patch-set or link-set. So e.g.:

observer> create-turtles 5
observer> let mylist (list turtle 0 turtle 2 turtle 4)  print turtle-set mylist
(agentset, 3 turtles)

Upvotes: 3

David Merinos
David Merinos

Reputation: 1295

I will assume that you're not using specific breeds for people A or people B.

Perhaps you could try using breeds, for example:

breed [personA peopleA]
breed [personB peopleB]

Will define 2 different agentsets and then you can use the <breeds>-own statement to define a list of recently greeted people.

peopleA-own [recently-greeted-people recently-greeted-people-time]

And then everytime that a personA has to greet someone your procedure could look like this:

to greet [personB-who]
    if (not (and (member? personB-who recently-greeted-people)
                  (procedure-that-checks-ticks-less-than-5))
       ...ADD HERE OTHER LOGICAL CHECKS DEPENDING ON YOUR PROBLEM
       )
       [ 
         fput personB-who recently-greeted-people
         fput current-tick recently-greeted-people-time
       ]
end

Observe that for every personB greeted, the who and the id are added to different lists and then they must be removed at the same time to keep consistence.

You can read more about breeds in the NLogo dictionary.

Upvotes: 1

Related Questions