Search code examples
randomattributesnetlogoprobabilityagent-based-modeling

How to distribute agents' attributes randomly according to specific probabilities in Netlogo?


I am relatively new to Netlogo, having completed only a handful of models. Currently working on one for my dissertation where I need to distribute agents' attributes randomly according to specific probabilities, some at the onset of the simulation, other attributes to be distributed throughout. This is connected with an extension of the trust game, for those familiar with it. I completed the conceptual model with a colleague who doesn't use Netlogo, so I am a bit stuck at the moment.

I think the rnd extension might be useful, but I can't quite figure out how to use it. My apologies if this seems redundant to any of you, but I really hope to get some help here.

extensions [ rnd]

;; divides agents into two types
breed [ sexworkers sexworker ]
breed [ officers officer ]

;; determines attributes of agents
sexworkers-own
[ assault?       ;; is assaulted
  trust?         ;; probability to trust police to report assault
  protection?    ;; probability of good experience with police during report
  prob-trust ]   ;; probability to trust overall

officers-own
[ behavior   ] ;; probability of treating sex workers well/badly during report

This is the start of the model, and then I want to distribute the attributes according to specific probabilities. I honestly haven't found a way to do this that works as I intend it to. What I want is to start off, for every sex worker alike, a probability of 0.01 to be assaulted (prob-assault; assault?=true). Afterwards, with each tick, there is again the chance of 0.01 for sex workers to be assaulted.

Afterwards, in the subset of assault?=true, there is then a probability to report the assault (prob-report, 0.5. This is expressed by trust?=true/false. Within the subset of those who report, there is then a final probability of having a good/bad experience with police (prob-protection), here protection?=true/false.

These three attributes should be randomly distributed according to the probabilities, and also then result in a combined probability to trust police in the future, prob-trust. (prob-trust = prob-assault + prob-report + prob-protection).

What I have done (without rnd extension so far is this:

      ;; determines sex workers' behavior
      ask sexworkers [ move ]
      ask sexworkers [ victimize ]
      ask sexworkers [ file ]

    to victimize
 ask sexworkers [
    ifelse random-float 1 <= 0.0001 
    [ set assault? 1 ]
    [ set assault? 0 ]
  ]
end

to file 
  ask sexworkers with [ assault? = 1 ] [
   ifelse random-float 1 <= 0.5 
    [ cooperate ]
    [ avoid ] 
  ]
end

to cooperate
  ask sexworkers [ set trust? 1  ]
end

to avoid
  ask sexworkers [ set trust? 0 ]
end

What happens at the moment though is that there is no variation in attributes, all sex workers seem to have no assault and trust/not trust varying all simultaneously. I am not sure what is going on.


Solution

  • (1) You don't need the rnd extension for anything you are trying to do here. If you just want to take some action with some probability then your approach of if random-float 1 < <probablility value> is the correct approach. The rnd extension is when you want to get into weighted probability, for example choosing agents based on their income.

    (2) NetLogo recognises true and false (capitalisation does not matter) as specific truth values. You should not use 1 and 0 as proxies for true and false. There are several advantages to using the truth values directly. The most obvious is readability, you can have statements like set trust? true and if trust? = true [do something]. More compactly, you can simply say if trust? [do something]. Other advantages include access to logical operators such as not and and for your conditions.

    With regard to your actual problem of every agent having the same behaviour, you have nested your ask turtles type statements. For example, you have:

    to file 
      ask sexworkers with [ assault? = 1 ] [
       ifelse random-float 1 <= 0.5 
        [ cooperate ]
        [ avoid ] 
      ]
    end
    

    If you substitute the cooperate and avoid procedures into this code, you would get:

    to file 
      ask sexworkers with [ assault? = 1 ] [
       ifelse random-float 1 <= 0.5 
        [ ask sexworkers [ set trust? 1  ] ]
        [ ask sexworkers [ set trust? 0 ] ] 
      ]
    end
    

    So, if your random number is, say, 0.4 then ALL your sexworkers will have trust set to 1, not just the particular sexworker who 'rolled the die'.

    You either need:

    to file 
      ask sexworkers with [ assault? = 1 ] [
       ifelse random-float 1 <= 0.5 
        [ set trust? true ]
        [ set trust? false ] 
      ]
    end
    

    Or you need:

    to cooperate
      set trust? true
    end
    
    to avoid
      set trust? false
    end
    

    Use the first option if there's not really anything else that is being done. Use the second option if setting the trust? value is just one of many actions that the turtle should take when it is cooperating or avoiding.