Question - how to assign breed types using sprout for 4 types of breeds that follow a probability assigned by a user?

243 views
Skip to first unread message

Fan Li

unread,
Jul 26, 2022, 1:59:16 PM7/26/22
to netlogo-users
Hi All,
I am new in NetLogo.

I wonder if you could help with one part of my NETLOGO code.
Right now, I have two types of turtle breeds in my system, and I assign the breed type randomly in the grid according to some pre-established frequency defined by the user (initial_type1_fr):

breed [ type1_s type1 ]
breed [ type2_s type2 ]

to assignTypes
  sprout 1 [
    let ptype random-float 1.0
    ifelse (ptype < initial_type1_fr)
    [set breed type1_s ]
    [set breed type2_s ]
  ]
end

I want to generalize this code by initializing the population with 4 types of breeds with a pre-established frequency defined by the user (that is not necessarily having all breeds types being equally frequent).
breed [ type1_s type1 ]
breed [ type2_s type2 ]
breed [ type3_s type3 ]
breed [ type4_s type4 ]

Would you be able to provide me guidance in generalizing this code? (I have been looking into the NetLogo library and community forums, but I have had no success.)

Thank you ^^

question_generalizing_initialization.png

Michael Tamillow

unread,
Jul 26, 2022, 2:20:55 PM7/26/22
to Fan Li, netlogo-users
Hey Fan,

I could be mistaken but I don't think breed is a property owned by individual agents. From my understanding it is more like a "type" which means it is deeply set and not something that can be set willy-nilly. Otherwise we could change turtles to wolves!

when you use "sprout" you are creating a turtle - the built in breed. If you want other breeds, you need "sprout-other_breed". So your specific problem, you should probably do your "if-else" before you try to sprout anything.

--
You received this message because you are subscribed to the Google Groups "netlogo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netlogo-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/netlogo-users/c5d8c6ae-8bb8-47e8-8eb5-165c3b31ee10n%40googlegroups.com.

Jim Lyons

unread,
Jul 26, 2022, 2:29:03 PM7/26/22
to netlogo-users, Fan Li, Michael Tamillow

On Jul 26, 2022, at 2:20 PM, Michael Tamillow <mikaelta...@gmail.com> wrote:

I could be mistaken but I don't think breed is a property owned by individual agents. From my understanding it is more like a "type" which means it is deeply set and not something that can be set willy-nilly. Otherwise we could change turtles to wolves!

Michael,
You are mistaken. It is perfectly alright to set an individual agent’s breed to one of the defined breeds in your model. You can change turtles to wolves, and you can change wolves to turtles.

Best,
Jim

Michael Tamillow

unread,
Jul 26, 2022, 4:09:40 PM7/26/22
to Jim Lyons, netlogo-users, Fan Li
Thank you for the clarification. 

Stephen Guerin

unread,
Jul 26, 2022, 8:31:08 PM7/26/22
to Fan Li, netlogo-users
Here's an approach assigning breeds to patches using the "run" command (which I normally try to avoid). 

to setup
  ca
  set-default-shape people "person"
  set-default-shape wolves "wolf"
  set-default-shape ants "bug"
  assignBreedsToPatches
end

to assignBreedsToPatches
  let breedList      ["wolves" "ants" "people"]
  let breedFrequency [  0.1      0.3    0.6   ]   ; list sums to 1.0
  (foreach breedList breedFrequency [ [aBreed aFrequency] ->
    (run (word "ask up-to-n-of " round (aFrequency * count patches)  " patches with [not any? turtles-here] [sprout-" aBreed " 1]" )) ] )
end


You might see artifacts based on the rounding, the ordering of the lists and there's a chance a patch won't get assigned. For a more robust approach take a look at the "Lottery Example"  in the models library of how to do "weighted draws" and having a patch set a breed that way.

The main method in the Lottery Example that you could adapt:

;; The idea behind this procedure is a bit tricky to understand.
;; Basically we take the sum of the sizes of the turtles, and
;; that's how many "tickets" we have in our lottery.  Then we pick
;; a random "ticket" (a random number).  Then we step through the
;; turtles to figure out which turtle holds that ticket.
to-report lottery-winner
  let pick random-float sum [size] of turtles
  let winner nobody
  ask turtles
    [ ;; if there's no winner yet...
      if winner = nobody
        [ ifelse size > pick
            [ set winner self ]
            [ set pick pick - size ] ] ]
  report winner
end


--- -. .   ..-. .. ... ....   - .-- ---   ..-. .. ... ....
Stephen...@Redfish.com
1600 Lena St #D1, Santa Fe, NM 87505
office: (505) 995-0206  mobile: (505) 577-5828   
tw: @redfishgroup  skype: redfishgroup
zoom.redfish.com


--

James Steiner

unread,
Jul 26, 2022, 11:11:53 PM7/26/22
to Fan Li, netlogo-users
You are in luck!

This is a more or less common task with several well-known solutions!

What you are looking for is a "roulette wheel" (aka lottery or raffle) selection.

This can be accomplished with standard NetLogo commands, or with the "Rnd" extension. If that extension is not pre-installed, it can be acquired easily from the Extension Manager in NetLogo. 

Description and Documentation for Rnd:


If you're needs are simple, and you value the experience of learning and coding it yourself, it can be done.

What nice about this method is the selection bias weights can have any basis, that is, the frequencies don't have to sum to 1 or 100, but can be any arbitrary values. The odds of selection are based on the sum of the  selection weights given for each item. 

It will help you immensely to understand that breeds are a single value (a breed), but they appear to act differently in code depending on how they are used. 
 
Once they are defined as you have done, with the BREED [ ] statement, they 
can be assigned to a variable, placed in lists, passed into reporters, and be used in comparisons.  (a breed is only ever equal to itself (or, naturally, any stored reference to the breed, such as in a variable) or a reference to itself in a variable, or whatever).  

But, when used as input to a procedure that accepts agentset, the breed is the set of all agents with their breed variable set to that breed.

Unlike an agentset set, whose membership does not change unless refreshed, and can contain "dead" agents, a breed always refers to the current population of agents of that breed, and never contains dead agents.

So you can make a list of the breeds in question, and a list of their relative frequencies, and use that with Rnd. 

E.g.

Let breed-list (list typea typeb typec)

Let us know if you need more guidance. 

-James
Aka ja...@Turtlezero.com


--

Stephen Guerin

unread,
Jul 27, 2022, 2:22:48 AM7/27/22
to James Steiner, Fan Li, netlogo-users
I didn't realize breeds could be referenced. I wrongly assumed (list people ants wolves) would be a list of turtle-sets instead of breed references.

Thanks, James :-)

Fan, that means we can get rid of that ugly "run" command where we constructed a string. Instead we can change the code to look like this:

breed [wolves wolf]
breed [ants ant]
breed [people person]

to setup
  ca
  set-default-shape people "person"
  set-default-shape wolves "wolf"
  set-default-shape ants "bug"
  assignBreedsToPatches
end

to assignBreedsToPatches
  let breedList (list wolves ants people)
  let breedFrequency [  0.01    0.01    0.98  ]

  (foreach breedList breedFrequency [ [aBreed aFrequency] ->
    ask up-to-n-of round (aFrequency * count patches) patches with [not any? turtles-here]
      [sprout 1 [set breed aBreed]]])
end


------------------------------------------------------------------------

An alternative using James's Rnd extension suggestion might look like this;

extensions [rnd]

breed [wolves wolf]
breed [ants ant]
breed [people person]


to setup
  ca
  set-default-shape people "person"
  set-default-shape wolves "wolf"
  set-default-shape ants "bug"
  setBreedUsingRnd
end

to setBreedUsingRnd
  let breedList (list wolves ants people)
  let frequencyLIst [  0.1    0.3  0.6  ]
  let breedFrequencyList (map list breedList frequencyList)  ; map creates a list of lists
  ask patches [sprout 1 [set breed first rnd:weighted-one-of-list breedFrequencyList [ aList -> last aList]]]
end

  






--- -. .   ..-. .. ... ....   - .-- ---   ..-. .. ... ....
Stephen...@Redfish.com
1600 Lena St #D1, Santa Fe, NM 87505
office: (505) 995-0206  mobile: (505) 577-5828   
tw: @redfishgroup  skype: redfishgroup
zoom.redfish.com

Fan Li

unread,
Aug 3, 2022, 12:19:54 PM8/3/22
to netlogo-users

Michael and Jim, thank you for all the help. 


Stephen, thanks for the code; without it would have been much hard to find the solution to my problem. Just one question, why is "round" necessary? (I tried with and without it, and the outcome appears to be the same.) 


James, thanks for the recommendation of the rnd extension. 

Is there any way to find the code operating behind the extension? 

I wanted to see the details of how the code rdn works behind the scenes, but I am unsure if this information is in https://github.com/NetLogo/Rnd-Extension . I looked at all files but could not quite find anything resembling NetLogo. 

In case the authors of this extension decide to change the code, is there any way to keep using the version of the rnd extension I am using now (2022.07.29)?


Cheers ^^

Fan

Stephen Guerin

unread,
Aug 3, 2022, 2:45:14 PM8/3/22
to Fan Li, netlogo-users


Fan,

On Wed, Aug 3, 2022 at 10:08 AM Fan Li <wangerl...@gmail.com> wrote:

Stephen, thanks for the code; without it would have been much hard to find the solution to my problem. Just one question, why is "round" necessary? (I tried with and without it, and the outcome appears to be the same.) 

Cool exploration. Did you try it with different frequencies for breeds? To compare the impact of the round statement you might check the patches at the end of the assignment with:
   count patches with [not any? turtles-here]

 Also note my statement on the first post:
You might see artifacts based on the rounding, the ordering of the lists and there's a chance a patch won't get assigned. For a more robust approach take a look at the "Lottery Example"  in the models library of how to do "weighted draws" and having a patch set a breed that way.

Jeremy Baker

unread,
Aug 3, 2022, 3:39:13 PM8/3/22
to Fan Li, netlogo-users
Is there any way to find the code operating behind the extension? 

I wanted to see the details of how the code rdn works behind the scenes, but I am unsure if this information is in https://github.com/NetLogo/Rnd-Extension . I looked at all files but could not quite find anything resembling NetLogo. 

You're looking in the right place.  NetLogo extensions are all written in Java or Scala code, and not in NetLogo code.  The code for RND is mostly in the files Picker.scala and Primitives.scala here:  https://github.com/NetLogo/Rnd-Extension/tree/hexy/src/main/scala/org/nlogo/extensions/rnd with a little other Java code here.

In case the authors of this extension decide to change the code, is there any way to keep using the version of the rnd extension I am using now (2022.07.29)?

The version of RND that comes bundled with a particular NetLogo version won't change, so as long as you install that same NetLogo version will get you the same version of RND too.  Old versions of NetLogo are always kept available, partly for this reason.  There is no way from your model code to "lock in" a particular extension version, unfortunately.


That said, as far as I can see there hasn't been a functional update for RND in many years; it seems like a pretty stable extension.


-Jeremy


Michael Tamillow

unread,
Aug 3, 2022, 4:14:32 PM8/3/22
to Jeremy Baker, Fan Li, netlogo-users
There is a way to build and install the extensions independently. If you develop an extension, you will have to go through that process.

The built-in extensions are nice and should be taken advantage of like they are a part of Netlogo. This way you don’t have to think about the hard work that goes into creating a new one.

Sent from my iPhone

On Aug 3, 2022, at 2:39 PM, Jeremy Baker <jeremy...@northwestern.edu> wrote:


--
You received this message because you are subscribed to the Google Groups "netlogo-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to netlogo-user...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages