How to select up to a maximum number of turtles using roulette wheel selection

China☆狼群 提交于 2019-12-11 02:07:56

问题


In my model the turtles have two sexes where the males have two potential tactics. The females count the number of males in a set radius.

I want the females to weight their probability of selecting from the group of males (without replacement) depending on the relative frequency of the two male tactics.

I already have the code for the probability of selecting from the males (matingPoolProbAnad and matingPoolProbRes) but I don't know how to implement it, though the rnd extension seems the way to go, specifically rnd:weighted-n-of size agentset [ reporter ].

It's complicated by three things (1) the males can mate with more than one female but (2) only once with a given female and (3) females can only mate with a maximum of five males.

to count-mates ; ask the females to count the number of males in a 10 patch radius & then 
                ; determine the frequency of the resident males in their patch

  ask turtles with [sex = "female"]
  [
    if any? turtles with [sex = "male"] in-radius 10
    [ set potentialMates turtles with [sex = "male"] in-radius 10
       ifelse any? potentialMates with [anadromousM = 1]
    [ set FA count potentialMates with [anadromousM = 1] / count potentialMates ]
    [ set FA 0]
      ifelse any? potentialMates with [anadromousM = 0]
    [ set FR count potentialMates with [anadromousM = 0] / count potentialMates ]
    [ set FR 0]
    ]
    ]
end

to mating-pool-prob ; negative frequency dependency which is based on the number of male 
                    ; resident turtles 

  ask turtles with [sex = "female"]
  [
  ifelse (FA = 1) and (FR = 0)[
      set matingPoolProbAnad 1
      set matingPoolProbRes 0
  ]
  [ifelse (FA > 0) and (FR < 1)
    [
        set matingPoolProbRes exp(a - b * (FR - c ))/(1 + exp(a - b * (FR - c)))
        set matingPoolProbAnad 1 - matingPoolProbRes 

    ]
    [
        set matingPoolProbAnad 0
        set matingPoolProbRes  1
        ]
  ]
  ]
end

回答1:


This example may approach what you're getting at, but obviously would need to be adapted from this toy version. This setup sprouts 75% of males with strategy A and the rest with strategy B, and gives all turtles an empty agentset of mates to start off:

breed [ males male ]
breed [ females female ]
turtles-own [ mates ]
males-own [ strategy ]
females-own [ max-mate-count mate-count ]

to setup
  ca
  ask n-of 200 patches [
    sprout-males 1 [
      ifelse random-float 1 < 0.75 [
        set strategy "A"
        set color orange
      ] [
        set strategy "B"
        set color violet
      ]
    ]
  ]
  ask n-of 50 patches with [ not any? turtles-here ] [
    sprout-females 1 [
      set color green
    ]
  ]
  ask turtles [
    set mates ( turtle-set )
  ]
  reset-ticks
end

Use a while loop to have each female iteratively assess the strategy proportions of the males available to her, then add them to her 'mates' list. More detail in comments:

to choose-mates
  ask females [
    ; set a cap on possible mates for females; 5, or the number
    ; available within the radius if less than 5
    let availa-males males in-radius 10
    let n-max count availa-males
    set max-mate-count ifelse-value ( n-max < 5 ) [ n-max ] [ 5 ]

    ; Until a female has chosen up to her maximum number of mates:
    while [ mate-count < max-mate-count ] [
      ; determine which available males are not already in her 'mates' agentset
      set availa-males availa-males with [ not member? self [mates] of myself ]  

      ; assess the proportion of B strategy in remaining available males
      let prop_B ( count availa-males with [ strategy = "B" ] ) / n-max

      ; example probability choice, just meant to choose B males 
      ; with a frequency disproportionate to availability
      let proba_B ifelse-value ( prop_b * 2 < 0.6 ) [ prop_b * 2 ] [ 0.6 ]

      ; use a random float to determine which strategy type is chosen
      set mates ( turtle-set mates ifelse-value ( random-float 1 < proba_B ) 
      [ one-of availa-males with [ strategy = "B" ] ] 
        [ one-of availa-males with [ strategy = "A" ] ]  )

      ; count the current mates to break the while loop once
      ; the maximum number of mates is reached
      set mate-count count mates
    ]
    ; have the female's males add her to their own mates agentset
    ask mates [ 
      set mates ( turtle-set mates myself )
    ]
  ]
end

To check that 'B' males are being chosen disproportionately to their availability:

to check-values
  let all-mates  map [ i -> [strategy] of i ] [mates] of females
  print word "Average proportion of 'B' mates chosen: " mean map b-proportion all-mates
  print word "Actual proportion of 'B' males: " ( ( count males with [ strategy = "B" ] ) / count males )
end

to-report b-proportion [ input_list ]
  let tot length input_list
  let nb length filter [ i -> i = "B" ] input_list
  report nb / tot  
end

I'm not 100% sure that that's what you're after- maybe you can use the rnd package to clean up the loop.

Edit in response to comment

If you modify the end of the `choose-mates like so:

    ...
    ...
    ; have the female's males add her to their own mates agentset
    ask mates [
      set mates ( turtle-set mates myself )
    ]
    if n-max < count mates [
      print "Fewer available males than mates"
    ]
  ]
end

And your go looks like:

to go
  choose-mates  
end

You can run setup and go as many times as you like and you should never see the printout "Fewer available males than mates":

to repeat-1000
  repeat 1000 [ 
    setup
    go
  ]
end

I ran that a few times and never had count availa-males be less than the count of mates. However, if you add in movement without allowing the females to reset their mates agentset, you do start to see it- for example, try running this a few times:

to go
  choose-mates  
  ask turtles [ fd 1 ]
end

Now, because the turtles are moving around, you have some cases where females held on to their mates from the previous function call and then moved into a space where there were fewer availa-males. The quick and easy fix is to have females clear their mates each time. Where you do that depends on your model goals (how often do females choose mates? Do they only forget some of their previous ones? etc), but here's a very simple way:

to go
  ask turtles [ set mates ( turtle-set ) ]
  choose-mates  
  ask turtles [ fd 1 ]
end

Now you can run that as many times as you like and shouldn't see the "Fewer available males than mates" printout.



来源:https://stackoverflow.com/questions/50699599/how-to-select-up-to-a-maximum-number-of-turtles-using-roulette-wheel-selection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!