Reciprocal Altruism in Vampire Bats

No preview image

1 collaborator

Sinemoraavvie Collin Lysford (Author)

Tags

altruism 

Tagged by Collin Lysford over 6 years ago

bats 

Tagged by Collin Lysford over 6 years ago

evolution 

Tagged by Collin Lysford over 6 years ago

Visible to everyone | Changeable by everyone
Model was written in NetLogo 6.0.1 • Viewed 643 times • Downloaded 33 times • Run 0 times
Download the 'Reciprocal Altruism in Vampire Bats' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


WHAT IS IT?

This model examines the phenomena of blood sharing in bats. It has been observed that female vampire bats will share blood with non-kin in order to increase the chance of donations when they themselves are having hard times. In essence, the diminishing marginal utility of food creates opportunity for nominally "equal" trades of food over time to benefit both parties. Testing this in vivo is logistically limited to small populations of captive bats, and it cannot examine the genetic drift over time. As such, this model will do what is experimentally difficult in real life and look at a small roost of bats over a large number of generations. By modeling genetic inheritance, we can see what level of altruism is optimal given various configurations of population size, food abundance, and rate of immigration from non-related bats.

HOW IT WORKS

The bat population goes through seven distinct phases each tick.

1. Hunting Phase

Each bat that is at least age-until-independence old gets a normally distributed value of food. The mean and standard deviation of this normal distribution are set by food-average and food-standard-deviation, respectively. However, the mean is also modified in two other ways:

  • For each bat that has hunted before this bat this phase, the mean is lowered by order-penalty. This represents overcrowding of the environment. Note that the order in which bats hunt is randomized each night.
  • A sine function with period year-length is evaluated for the value of the tick modulo year-length, divided by the year length and multiplied by 360 to turn to degrees. The output of this function (which ranges from -1 to 1) is multiplied by season-difference and added to the mean. We term the ticks where this is positive the "high season", and the ticks where this is negative the "low season".

2. Pregnancy Phase

Each bat who:

  • Is not pregnant
  • Has at least consumption-cost + reproduction-cost of food
  • Is at least age-until-sexual-maturity old
  • Had their last child, if any, at least time-between-pregnancies ago

Has a pregnancy-chance percent chance to become pregnant. When a bat becomes pregnant, their consumption is increased by reproduction-cost. Since their sharing threshold is "How much more food than consumption do I want before I start sharing?", their sharing threshold increases by the same amount.

3. Sharing Phase

The sharing phase is divided into four sub-phases:

Family sub-phase

If a daughter bat would starve tonight, her mother will give her food until she runs out or her daughter will no longer starve tonight.

If a mother would starve tonight, her daughter will give her food until either the mother will no longer starve tonight or the daughter would starve if she gave away any more food.

Cooperation sub-phase

If a bat who has donated to another bat before would starve tonight, they ask each bat they've donated to (in descending order of how much they've given that bat over time) for food. The potential donor decides whether to help them based on this criteria:

  • Start with your personal threshold (your current consumption cost plus your sharing-threshold)
  • For each unit of food this bat has ever shared with you, lower the threshold by your trust coefficient
  • For each unit of food this bat currently OWES you (ie, for each unit your value to them is greater than their value to you), raise the threshold by your annoyance coefficient
  • If the bat asking for food has a child who can't feed themselves, decrease your threshold by your charity-to-mothers

The potential donor shares food until they have this modified threshold worth of food, or until they and the bat asking for food have the same amount of food.

Mother begging sub-phase

As the cooperation sub-phase, but instead, bats with children who can't feed themselves and who will starve tonight ask bats they have NEVER interacted with for food. To make the code run faster, we pre-cache whether any bat would bother sharing with a strange mother (since trust and annoyance don't factor in to this, this is static per bat.)

Non-mother begging sub-phase

As the mother begging sub-phase, but with non-mothers.

4. Consumption Phase

Mothers that will die tonight first reabsorb their fetus. This lowers their personal consumption back to baseline, and refunds food equal to the invested food (reproduction cost times days of pregnancy) times the absorption efficiency.

Then, each bat pays their personal consumption worth of food and dies if they can't.

5. Reproduction Phase

Each bat that has been pregnant for reproduction-time has a daughter. If psuedo-recombination is turned off, daughters start as exact clones of their mother. If psuedo-recombination is turned on, their genetic traits are averaged with another living bat. In either case, the daughters genetic traits are then further mutated. The sharing threshold and charity to mothers has a 20% chance to decrease by 2, decrease by 1, stay the same, increase by 1, or increase by 2. The trust and annoyance coefficients are increased or decreased randomly by up to .05.

6. Aging phase

Each living bat has their age increased by 1. If they reach their death-age, they die. The death-age was randomly chosen for each bat when they were created by a normal distribution with mean lifespan-average and standard deviation lifespan-standard-deviation.

7. Immigration phase

There is an immigration-chance percent chance that one new bat is randomly added to the roost. This bat is generated with the same code that generated bats on setup, instead of being based on any existing living bat.

HOW TO USE IT

To setup

Each slider controls a certain aspect of the model. Refer to the Sliders Section for more information on the function of each variable.

Once all the sliders are set to the desired levels, click SETUP to start the model.

To run

To observe the tick-by-tick interactions of the bat colony, set "messages-to-display" to "All Messages", hit "Go", and read along in the output box.

If you want to observe the long term trending of the genetic traits (sharing threshold, charity to mothers, trust coefficient, and annoyance coefficient), "All Messages" slows the model down too much. Set it to "Major Events Only" or "No Messages", then run the model on the fastest setting to develop the bat colony through many generations.

If you want to read messages corresponding to a developed bat colony, you can always let the model run for a while on "No Messages", then turn on "All Messages" later.

Buttons

The SETUP button initializes the model.

The GO button runs the simulation until the cell dies.

Switches

psuedo-recombination? - If this is on, daughters will average their genetic traits with one other living adult before mutating. This will significantly reduce variation in the gene pool.

Choosers

messages-to-display? - Has three options:

  • No Messages: Writes nothing to the output window.
  • Major Events Only: Writes tick changes with seasonal updates, births, deaths, pregnancies, fetal absorptions, and immigrations to the output window.
  • All Messages: Writes everything Major Events does to the output window, but also shows how much food each bat gets during the hunting phase, and every request and response during the sharing phase. This slows the model down significantly.

Sliders

starting-roost-count: Sets the number of starting bats. Since the food related parameters dictate the population that can be maintained, this doesn't have too much impact on the models output. However, the Count of Bats plot has a line relating to the starting roost count, so picking one that's about the median value of what the environment can maintain will make it easier to read the Count of Bats plot.

stomach-size: How much food a bat can have at once.

consumption-cost: How much food a bat needs each tick to survive.

reproduction-cost: How much MORE food a bat needs if she's pregnant.

absorption-efficiency: How much of the invested food a bat gets back if she's forced to reabsorb her fetus because she would otherwise starve to death.

time-between-pregnancies: How long after having a daughter a bat can get pregnant again.

pregnancy-chance: The chance a bat will get pregnant each night she isn't pregnant, has enough food to pay the additional reproduction cost, is sexually mature, and has waited sufficiently long since her last pregnancy.

lifespan-average: The mean of the normal function that dictates how long a bat will live if they don't starve to death.

lifespan-standard-deviation: The standard deviation of the normal function that dictates how long a bat will live if they don't starve to death.

age-until-independence: How long after being born a bat is able to hunt.

age-until-sexual-maturity: How long after being born a bat can become pregnant.

food-average: The mean of the normal function that dictates how much food a bat will get each night.

food-standard-deviation: The standard deviation of the normal function that dictates how much food a bat will get each night.

order-penalty: How much less food a bat will get each night for each bat that has hunted already this night.

season-difference: How much seasonal change impacts the availability of food. The seasons are modeled by a sine function. This corresponds to how much food is added or subtracted from the average when the sine function returns 1 or -1, respectively.

year-length: The period of the seasonal sine function.

immigration-chance: The percentage chance each tick for a new bat to immigrate to the roost.

Plots

Count of Bats - Shows the number of living bats each tick. Also includes the starting roost count (in blue) as a reference.

Mean Sharing Threshold - Shows the mean sharing threshold of all living bats each tick.

Mean Charity to Mothers - Shows the mean charity to mothers of all living bats each tick.

Mean Trust Coefficient - Shows the mean trust coefficient of all living bats each tick.

Mean Annoyance Coefficient - Shows the mean annoyance coefficient of all living bats each tick.

THINGS TO NOTICE

Notice the sinusoidal pattern of the bat count that comes as a result of the seasonal difference and the order penalty. This is the ideal for natural selection, since it creates variation and then limits the survivors to the best adapted ones.

Notice the proportion of mother-daughter links to general sharing links as the model evolves.

THINGS TO TRY

Increase the stomach size and watch what happens to the mean sharing threshold. Vampire bat altruism is heavily incentived by their small stomachs meaning that "it could be me in two days" - with large stomachs, greed is a much more successful strategy, because it's actually possible to hoard a significant amount of blood.

Other than that, you can try to do what I failed to do and find a parameter set where the "best" bats tend to die natural deaths. No matter what parameter set I explored, very few bats tend to die of natural causes in this model - this means that random chance is having a lot of impact and a large chunk of the fluctuation of the traits is just noise. Ideally, there's a parameter set where the "best adapted" bats live out their full lives. This model would have been much more interesting if I could have the defaults produce that result. (This could be a consequence of my food function - unfortunately, I couldn't find much research on how bat feedings scale with population, so I took a best guess.)

EXTENDING THE MODEL

Since vampire bats tend to live in female-only roosts and thus only share blood with females, I made all children daughters and didn't model male bats. It might be interesting to try to make this a truly genetic model by researching how the male interacts with the roost. It's a harder problem than it sounds because the males exploits are "off-screen" with regards to the model, so the male rate of genetic change needs to be kept in sync somehow.

There's also the interesting possibility that this model is "doomed to fail" because kin-only altruism would be the ideal if you could get away with it, and vampire bat altruism is simply because bats don't have the memories to remember their trading history and who is and isn't kin. In essence, my model may be pre-supposing a level of sophistication bats don't actually possess, which explains why it diverges from what's observed in nature. It would be a relatively easy mutation to change this model to have no historical memory and no special handling of kin relations, and see what level of altruism the population stabilizes on.

NETLOGO FEATURES

The season related code in start-tick shows how to model sinusoidal changes in the environment when the length of the period is determined by a user parameter.

The "cooperation phase" of share has a useful design pattern to "ask in order". It involves caching the value you want to sort on, then, while any one of those values is greater than zero, asking an agent with a maximal value for that cached variable and setting the cached value to 0 during the ask.

HOW TO CITE

If you mention this model or the NetLogo software in a publication, we ask that you include the citation below.

Please cite the NetLogo software as:

COPYRIGHT AND LICENSE

model developed by Collin Lysford in 2017

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

globals [
  setting-up?                         ; Used to suppress new-bat messages when setting up
  cached-largest-value                ; Cached value of the largest sharing this tick, for performance
  parent-who                          ; identity of the parent cached to use during reproduciton
  child-who                           ; identity of the child cached to use during reproduction
  daughter-age                        ; age of the daughter cached to use when determining if her mother is "feeding for two"
  hunting-order                       ; serial order of how many bats have hunted before you, used to represent food pressures for overcrowding
  seasonal-average                    ; the average food per season (set by a slider) modified by the seasonal offset
  season-day                          ; which day within the "season" (half a year) you're in
  season-word                         ; whether it's the low or high season
  plural                              ; when the message log mentions some quantity of something, this is "s" if that quantity is more than 1 and otherwise null
  share-value                         ; value of a trade of food that was made
  potential-donor                     ; agent that the potential recipient is asking for a trade
  donor-who                           ; who number of the (potential) donor when evaluating a trade
  recipient-who                       ; who number of the (potential) recipient when evaluating a trade
  donor-food                          ; food in the (potential) donors stomach when evaluating a trade
  donor-threshold                     ; the (potential) donors sharing threshold when evaluating a trade
  incoming-sharing                    ; the all-time contributions from the potential recipient to the potential donor when evaluating a trade
  outgoing-sharing                    ; the all-time contributions from the potential recipient to the potential donor when evaluating a trade
  modifier                            ; how much individual circumstances (motherhood, trust, annoyance) change the potential donors mind about this trade
  recombination-sharing-threshold     ; when reproducing, sharing threshold of one adult who's not your mother
  recombination-charity-to-mothers    ; when reproducing, charity to mothers of one adult who's not your mother
  recombination-trust-coefficient     ; when reproducing, trust coefficient of one adult who's not your mother
  recombination-annoyance-coefficient ; when reproducing, annoyance coefficient of one adult who's not your mother
  birth-count                         ; Number of births
  immigration-count                   ; Number of immigrations
  natural-death-count                 ; Number of natural deaths
  starvation-count                    ; Number of starvations
]

bats-own [
  food                                ; How much food is in the bats stomach currently
  pregnant?                           ; Whether the bat is currently pregnant
  pregnancy-days                      ; How many days the bat has been pregnant
  next-potential-pregnancy            ; How old you can be before your next pregnancy
  has-dependant?                      ; Whether this bat has a living daughter who can't feed themselves
  age                                 ; How old (in ticks) the bat is
  death-age                           ; How old (in ticks) the bat will be when they die naturally if they haven't already starved
  sharing-threshold                   ; How much more food than consumption this bat wants to have before it will share with strangers.
  charity-to-mothers                  ; How much a bat will lower it's sharing threshold for a bat with a non-hunting child.
  trust-coefficient                   ; How much this bats sharing threshold will be lowered for each unit of food is currently owes the other bat in a trade
  annoyance-coefficient               ; How much this bats sharing threshold will be raised for each unit of food the other bat in a trade currently owes it
  personal-consumption                ; How much this bat consumes each night (always either consumption-value or consumption-value + reproduction-cost)
  personal-threshold                  ; This bats threshold for a stranger bat (always personal-consumption + sharing-threshold)
  begging-tonight?                    ; Whether a bat is begging for food tonight because it's starving
  willing-to-give-tonight?            ; Whether a bat would be willing to give food to a stranger tonight
  willing-to-give-to-mothers-tonight? ; Whether a bat would be willing to give food to a stranger mother tonight
]

breed [ bats bat ]
directed-link-breed [ sharings sharing ]
sharings-own [ value cooperation-value ]
directed-link-breed [ mothers mother ]

to setup
  clear-all
  set setting-up? true ;; suppress message for bats joining roost during inital setup
  repeat starting-roost-count [ spawn-new-bat ]
  set setting-up? false
  ;; Reset counts
  set cached-largest-value 0
  set birth-count 0
  set immigration-count 0
  set starvation-count 0
  set natural-death-count 0
  reset-ticks
end 

to go
  start-tick
  hunt
  become-pregnant
  share
  consume
  reproduce
  grow-older
  immigrate
  tick
end 

to start-tick ;; clear out per-tick variables, update season, and post start-of-tick message if messages are enabled
  set hunting-order 0 ;; order changes each hunt, so clear previous queue
  ask sharings with [ value = 0 ] [ die ] ;; Any value-0 sharings were just created to protect from inifite loops, and aren't real sharings
  if any? sharings
  [
    set cached-largest-value max [ value ] of sharings ;; cache once a tick, for performance
    ask sharings [ set color scale-color blue value 0 cached-largest-value ] ;; scale so bluer = higher value, to make the viz more useful
  ]

  ask bats [ set has-dependant? false ] ;; we have to recheck this each tick

  if any? mothers
  [
    ask mothers
    [
      ask end2 [ set daughter-age age ] ;; end2 of mother links are daughters
      if daughter-age > age-until-independence  [ ask end1 [ set has-dependant? true ] ]
    ]
  ]

  ;; Season is a sine function with a period of year-length. At the peak, it raises the average food for each bat by season-length; at the trough, lowers it by the same.
  let season-int ticks mod year-length  ;; first, get an integer representation of where in the season we are...
  let season-proportion season-int / year-length ;; then, divide it by year length to bound it between 0 and 1...
  let season-degree season-proportion * 360 ;; next, multiply it by 360 to make it a value in degrees...
  set seasonal-average food-average + season-difference * sin ( season-degree ) ;; finally, take the sine of it and add that term to the food-average
  if messages-to-display != "No Messages" ;; write the tick and indicate where we are in the season
    [
    let season-length year-length / 2 ;; We divide a year into "high" and low" seasons depending on whether the sine output is positive or negative.
    ifelse season-int < season-length [ set season-word "high" set season-day season-int + 1] [ set season-word "low" set season-day ( season-int - ( season-length - 1 ) ) ]
    let season-change season-length - season-day + 1
    ifelse season-change = 1 [ set plural "" ] [ set plural "s" ]
    output-print ("") ;; pad with spaces for new tick announcements
    output-print ( word "--Tick " ticks " begins.--" )
    output-print ( word "It is day " season-day " of the " season-word " season." )
    output-print ( word "Season will change in " season-change " day" plural "." )
    output-print ("")]
end 

to hunt ;; Bats get more food
 ask bats with [ age >= age-until-independence ] ;; all bats old enough to hunt
 [
    let ordered-average seasonal-average + ( hunting-order * order-penalty ) ;; The seasonal average is lowered by one order penalty for each bat in front of you
    let meal floor min list ( random-normal ordered-average food-standard-deviation ) ( stomach-size - food )  ;; each bat gets food according to food distrubtion, or just enough to be full
    if messages-to-display = "All Messages"
    [
      ifelse meal = 1 [ set plural "" ] [ set plural "s" ]
      output-print ( word "Bat " who " (" food " food) got " meal " more unit" plural " of food." ) ]
    set food food + meal
    set hunting-order hunting-order + 1
  ]
end 

to become-pregnant ;; Bats who can pay the reproduction cost have a chance to get pregnant
  ask bats with [ pregnant? = false and food >= ( consumption-cost + reproduction-cost ) and age >= next-potential-pregnancy ] ;; If you can feed a child, don't have one, are sexually mature, and it's been long enough since last baby...
    [
      if random-float 1 < ( pregnancy-chance / 100 ) ;; you have a pregnancy-chance% chance to become pregnant
      [
        set pregnant? true
        set pregnancy-days 0
        if messages-to-display != "No Messages" [ output-print ( word "Bat " who " is now pregnant. " ) ]
        set personal-consumption consumption-cost + reproduction-cost
        set personal-threshold personal-threshold + reproduction-cost
    ]
  ]
end 

to share ;; Bats may share food with each other
  ask bats [ check-sharing-status ] ;; find out who will starve tonight and who is willing to share

  ;; family subphase - first, mothers and daughters look out for each other
  ask mothers [ feed-family ]

  ;; cooperation subphase - check all existing links first, in decending order of priority
  ask sharings [ set cooperation-value value ] ;; clone off the value for just this sharing value
  while [ any? sharings with [ cooperation-value > 0 ] ] ;; loop over all sharings...
  [
    ask max-one-of sharings [ cooperation-value ]  ;; in decending order of value...
    [
      set cooperation-value 0 ;; delete cloned value, so we don't evaluate this link again
      if [begging-tonight?] of end1 = true ;; if the donor bat of this link wants to call in the debt tonight...
      [
        set potential-donor end2
        ask end1 [ beg-for-food ] ;; See if they'll go for it
      ]
    ]
  ]

  ;; mother begging subphase - hungry bats ask bats who are willing to donate to stranger mothers
  while [ any? bats with [ willing-to-give-to-mothers-tonight? = true ] and any? bats with [ begging-tonight? = true and has-dependant? = true ] ] ;; while some bats are hungry and others are willing to share with strangers...
  [
    ask one-of bats with [ begging-tonight? = true and has-dependant? = true ] ;; one bat who will die tonight without food...
    [
      set potential-donor one-of other bats with [ willing-to-give-to-mothers-tonight? = true and sharing-neighbor? myself = false and mother-neighbor? myself = false ] ;; asks a bat it has no relation with
      ifelse potential-donor != nobody [ beg-for-food ] [ set begging-tonight? false ] ;; go for a trade if anyone is willing; otherwise, don't bother trying to beg again
    ]
  ]

  ;; non-mother begging phase - hungry bats ask bats who are willing to donate to strangers in general
  while [ any? bats with [ willing-to-give-tonight? = true ] and any? bats with [ begging-tonight? = true ] ] ;; while some bats are hungry and others are willing to share with strangers...
  [
    ask one-of bats with [ begging-tonight? = true ] ;; one bat who will die tonight without food...
    [
      set potential-donor one-of other bats with [ willing-to-give-tonight? = true and sharing-neighbor? myself = false and mother-neighbor? myself = false ] ;; asks a bat it has no relation with
      ifelse potential-donor != nobody [ beg-for-food ] [ set begging-tonight? false ] ;; go for a trade if anyone is willing; otherwise, don't bother trying to beg again
    ]
 ]
end 

to consume ;; Bats need to spend food or die
  ask bats
  [
    if pregnant? = true and food < personal-consumption ;; if you will starve keeping the fetus...
    [
      set pregnant? false ;; lose fetus
      set pregnancy-days 0
      set food food + ( pregnancy-days * reproduction-cost * absorption-efficiency ) ;; gain some of the invested energy back
      set food max list food stomach-size ;; but no more than you can hold in your stomach
      set personal-consumption personal-consumption - reproduction-cost
      set personal-threshold personal-threshold - reproduction-cost
      if messages-to-display != "No Messages" [ output-print ( word "Bat " who " was forced to absorb her fetus." ) ]
    ]
    ifelse food < personal-consumption ;; starve if you don't have enough food
    [ set starvation-count starvation-count + 1
        if messages-to-display != "No Messages" [ output-print ( word "Bat " who " starved to death." ) ]
        ask my-sharings [ die ]
        ask my-mothers [ die ]
        die
    ]
    [ set food food - personal-consumption ] ;; otherwise, just eat
  ]
end 

to reproduce ;; Bats who have been pregnant for long enough have babies
  ask bats with [ pregnant? = true ]
  [
    set pregnancy-days pregnancy-days + 1
    if pregnancy-days >= reproduction-time ;; If you've been pregnant long enough...
    [  set pregnant? false
       set pregnancy-days 0
       set parent-who who
       set next-potential-pregnancy age + time-between-pregnancies
       set personal-consumption personal-consumption - reproduction-cost ;; reset consumption BEFORE you have the baby, so it gets the correct, non-pregnant ones
       set personal-threshold personal-threshold - reproduction-cost
       set birth-count birth-count + 1
       hatch-bats 1
       [
        setxy random-xcor random-ycor
        set color one-of base-colors
        set child-who who
        set food 0
        set age 0
        set next-potential-pregnancy age-until-sexual-maturity
        set death-age floor random-normal lifespan-average lifespan-standard-deviation
        if messages-to-display != "No Messages" [ output-print ( word "Bat " parent-who " gave birth to bat " who "." ) ]
        if psuedo-recombination? = true [ psuedo-recombinate ] ;; If optional psuedo recombination is turned on, run it
        mutate ;; Baby may differ slightly from mom
        set personal-threshold sharing-threshold + consumption-cost ;; sharing threshold may have changed, so update personal threshold
       ]
       create-mother-to bat child-who [ set color yellow ] ;; create a mother-daughter link - these bats will preferentially share
    ]
  ]
end 

to grow-older ;; Bats grow older and maybe die of old age
  ask bats
  [
    set age age + 1
    if age >= death-age ;; Death function gave each bat a pre-determined lifespan on creation
    [ set natural-death-count natural-death-count + 1
      if messages-to-display != "No Messages" [ output-print ( word "Bat " who " died naturally." ) ]
      ask my-sharings [ die ]
      ask my-mothers [ die ]
      die ]
  ]
end 

to immigrate ;; Stranger bats with no relation to the roost might join in
  if random-float 1 < ( immigration-chance / 100 ) [ spawn-new-bat set immigration-count immigration-count + 1 ]
end 

to check-sharing-status ;; Determine whether a bat needs food tonight to live, and whether a bat is willing to donate to strangers.
  ifelse food < personal-consumption [ set begging-tonight? true ] [ set begging-tonight? false ] ;; figure out who will starve to death tonight and who won't
  ifelse food > personal-threshold [ set willing-to-give-tonight? true ] [ set willing-to-give-tonight? false ] ;; figure out who might be willing to give to strangers and who won't
  ifelse food > max list personal-consumption ( personal-threshold - charity-to-mothers ) [ set willing-to-give-to-mothers-tonight? true ] [ set willing-to-give-to-mothers-tonight? false ] ;; figure out who might be willing to give to stranger mothers and who won't
end 

to feed-family ;; Special sharing function only for mothers and daughters
  if [ begging-tonight? ] of end2 = true ;; if the child is going to starve...
  [
    ask end2 [ set share-value personal-consumption - food ] ;; share-value has the hunger of the daughter
    ask end1 [ set share-value min list share-value food ] ;; mom makes sure her daughter is fed, even if she has to starve
    if share-value > 0 [ ask end1 [ set food food - share-value ] ask end2 [ set food food + share-value ] ]
  ]

  if [ begging-tonight? ] of end1 = true ;; if mom is going to starve...
  [
    ask end1 [ set share-value personal-consumption - food ] ;; share-value has the hunger of the mother
    ask end2 [ set share-value min list share-value food - personal-consumption ] ;; daughter won't go hungry for mom, but she'll share everything extra, ignoring threshold
    if share-value > 0 [ ask end2 [ set food food - share-value ] ask end1 [ set food food + share-value ] ]
  ]
    ask both-ends [ check-sharing-status ] ;; re-validate if either one is begging and/or willing to share tonight
end 

to beg-for-food ;; This function is called by the potential recipient when potential-donor has another bat stored in it.
  set recipient-who who
  ask potential-donor
  [
    set donor-food food
    set donor-who who
    calculate-donor-modifier ;; donor figures out how much they'd change your personal threshold for this bat
    set donor-threshold max list ( personal-threshold + modifier ) ( personal-consumption ) ;; but their personal threshold is always at least as much as they need to live
  ]
  set share-value floor min list ( donor-food - donor-threshold ) ( ( donor-food - food ) / 2 ) ;; share until donor is unwilling to share more, or unitl sharing would make them equal
  set share-value max list share-value 0 ;; turn negative share values to 0 so function below can be simplier
  if messages-to-display = "All Messages" [ output-print ( word "Bat " who " (" food " food) asks bat " donor-who " (" donor-food " food) for food. " ) ]
  ifelse share-value > 0
  [
    if messages-to-display = "All Messages"
    [
      ifelse share-value = 1 [ set plural "" ] [ set plural "s" ]
      output-print ( word "She shares " share-value " unit" plural " of food. " ) ]
    ]
  [
    if messages-to-display = "All Messages" [ output-print ( word "She refuses.") ]
  ]
ask potential-donor [ update-sharing-link ] ;; update link even if no sharing happened to protect from infinite loops. This value-0 sharings are deleted each start-tick
end 

to calculate-donor-modifier ;; Called by a bat being asked to donate blood, with the potential recipient's who number stored in recipient-who
  set outgoing-sharing 0 ;; baseline if the donor has never given to the recipient before
  set incoming-sharing 0 ;; baseline if the recipient has never given to the donor before
  if sharing who recipient-who != nobody [ ask sharing who recipient-who [ set outgoing-sharing value ] ]
  if sharing recipient-who who != nobody [ ask sharing recipient-who who [ set incoming-sharing value ] ]
  let net-sharing outgoing-sharing - incoming-sharing
  set modifier ( incoming-sharing * trust-coefficient * -1 ) ;; if the recipient has given food before, the donor will be more generous than baseline (smaller modifier = more giving)
  if net-sharing > 0 [ set modifier modifier + ( net-sharing * annoyance-coefficient ) ] ;; if the recipient currently owes the donor, they'll be less generous than baseline
  if any? mothers with [ end1 = recipient-who and [age] of end2 < age-until-independence ]  [ set modifier modifier - charity-to-mothers ] ;; if the recipient has a dependent, increase by charity to mothers
  set modifier floor modifier
end 

to update-sharing-link ;; after a trade of food occurs, store off the value of it
  if out-sharing-neighbor? bat recipient-who = false [ create-sharing-to bat recipient-who [ set value 0  ] ] ;; create a sharing link if none exists
  ask sharing who recipient-who
  [
    ask end1 [ set food food - share-value ]
    ask end2 [ set food food + share-value ]
    set value value + share-value
    ask both-ends [ check-sharing-status ]
  ]
end 

to psuedo-recombinate
  ;; we don't have true sexual reproduction, because we're not modeling males.
  ;; instead, we'll just average mom with one other adult, as long as there is one
  ;; This is a hack, but an acceptable one, since males have just as many of moms genes as females
  if any? bats with [ age >= age-until-sexual-maturity and who != parent-who ]
  [
    ask one-of bats with [ age >= age-until-sexual-maturity and who != parent-who ]
    [
      set recombination-sharing-threshold sharing-threshold
      set recombination-charity-to-mothers charity-to-mothers
      set recombination-trust-coefficient trust-coefficient
      set recombination-annoyance-coefficient annoyance-coefficient
    ]
    set sharing-threshold floor mean list recombination-sharing-threshold sharing-threshold
    set charity-to-mothers floor mean list recombination-charity-to-mothers charity-to-mothers
    set trust-coefficient mean list recombination-trust-coefficient trust-coefficient
    set annoyance-coefficient mean list recombination-annoyance-coefficient annoyance-coefficient
  ]
end 

to mutate ;; change the genetic traits slightly
  set sharing-threshold  sharing-threshold + ( ( random 5 ) - 2 ) ;; increases or decreases sharing threshold by up to 2
  set charity-to-mothers charity-to-mothers + ( ( random 5 ) - 2 ) ;; increases or decreases charity to mothers by up to 2
  set trust-coefficient trust-coefficient + ( ( random-float .1 ) - .05 ) ;;  increases or decreases trust coefficient by up to .05
  set annoyance-coefficient annoyance-coefficient + ( ( random-float .1 ) - .05 ) ;;  increases or decreases annoyance coefficient by up to .05
end 

to spawn-new-bat ;; used for initial bat population and immigration
  create-bats 1
  [
  setxy random-xcor random-ycor
  set food random 50
  set pregnant? false
  set next-potential-pregnancy age-until-sexual-maturity ;; bats can have their first child when they're sexually mature
  set age age-until-independence + random ( ( lifespan-average - age-until-independence ) / 3 ) ;; new bats are adults who have lived up to one-third of the average adult lifespan
  set death-age 0
  while [ death-age <= age ] [ set death-age floor random-normal lifespan-average lifespan-standard-deviation ] ;; if a bat lives this long, they'll die of natural causes
  set sharing-threshold random 20
  set personal-threshold sharing-threshold + consumption-cost
  set personal-consumption consumption-cost
  set trust-coefficient random-float .5
  set annoyance-coefficient random-float .5
  set charity-to-mothers random 20
  if setting-up? = false and messages-to-display != "No Messages" [ output-print ( word "Bat " who " has joined the roost." ) ]
  ]
end 

; Copyright 2017 Collin Lysford
; See Info tab for full copyright and license.

There are 3 versions of this model.

Uploaded by When Description Download
Collin Lysford over 6 years ago fixed a typo, WHOOPS Download this version
Collin Lysford over 6 years ago changed message default to major events Download this version
Collin Lysford over 6 years ago Initial upload Download this version

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.