powered by NetLogo

WHAT IS IT?

According to the traditional competitive exclusion principle, two species that use a limiting resource in the same way can not coexist.

Yet this dynamic model reveals how three can coexist in dynamic equilibrium. Many recent empirical confirm this dynamic is at play among many types of biological organisms. Three strains of bacteria, for example, can co-exist in dynamic equilibrium.
Typically public health focuses on a kind of bacteria we want to eliminate with antibiotics, and the traditional approach is to wipe out the target bacteria with a sufficiently long and aggressive antibiotic regime. That model is antibiotic vs. bacteria, two types of agents, one killing off the other.

Nature, by contrast, often poses three types of agents, each able dominating just one other, e.g. C beats B and B beats A, and A beats C. (“non-transitive” because transitive relationship would be IF C beats B AND B beats A, then C beats A–but that’s not the case here). With those simple rules, and a community of A, B and C, a cyclic dominance results, in which we see one relatively dominant, then another, then the third, such that all three co-exist. In the short terms, each one dominates, but in the longer term perspective, averaging all the populations amounts to a kind of dynamic equilibrium.

A striking natural example are communities of E. coli bacteria strains, in which one strain produces antibiotic which kills a strain sensitive to the antibiotic. This sensitive strain grows very fast in the absence of this bacteriocide.

Would the antibiotic kill the fast growing but sensitive bacteria?

It would seem the antibiotic producer would win, but as the sensitive bacteria gets low, a third strain of bacteria grows. This third strain is resistant to the antibiotic, bacteria and so thrives on the producer, lowering the antibiotic production, maybe wiping out the producing strain. If producers are brought down to very low levels, then the sensitive but fast growing bacteria could take over. The antibiotic producing bacteria was not able to kill off the fast growing bacteria, despite the latter being sensitive to the antibiotic.

The producer of antibiotic overcomes a strain of a fast growing bacteria (like paper covers rock, antibiotic kills growing bacteria). In the absence of that antibiotic, this bacteria is a fast growing bacteria, but it will die in the presence of the antibiotic.

Another strain of bacteria resists the antibiotic, and in fact overwhelms the producer of the antiobiotic, because it also can outgrow the antibiotic producer and so take the resources and space (the shared condition). So if we lower the fast growing strain by adding more of the antibiotic producer, then the resister would grow and lower the population of the producer (scissors cuts paper).

There is a hidden third agent and the three are in dynamic balance. The target pathogen, our sensitive strain, was keeping the resistant strain down. But when we almost wiped out our target strain the resistant strain could thrive, beating out the toxin producing strain.

In sum:

Producer: produces antibiotics that kill the sensitive strain (Producer beats grower)
Grower: sensitive to the antibiotics, but can outgrow the resistant strain (Grower beats Resister)
Resister: resistant to the antibiotics, and can outgrows the producer (Resister beats Producer)

This parallels what we see in a community playing Rock-Paper-Scissors.

Say we wanted the antibiotic Producer to win, so we add much more of it. We find then our intention was thwarted because we were unaware of the dynamic balance. In the �healthy� dynamic balance the resister tends to kill off our hero the producer (Scissors beats Paper), but doesn�t overdo it, and our sensitive fast growing strain kept the resistant strain down. We wanted Paper to cover the Rocks, so we added much Papers, but then that led to a huge an unintended growth of Scissors which beat the Paper. Then the Rocks could thrive. So long as the Rocks don�t overdo it, and kill off the producer.

The fast growing sensitive strain can outgrow the resistant strain, which then would outgrows the producer, which kills the sensitive strain. So when the sensitive strain does too well, it effectively kills itself. Better to restrain its growth, and that would give it an evolutionary advantage.

In fact, researchers found that when resisters restrained their killing off of the producer they did the best (Nahum et al 2011).

A producer can beat a sensitive strain by toxin production. Producing this toxic antibiotic is a costly activity however. Thus a resistant strain can beat the producer strain not only because the toxin has no effect on this resistant strain but also because of the lower “fitness” of the producer (due to the cost of the toxin production). A sensitive strain can beat a resistant one due to the higher fitness of the sensitive strain (due to the cost of the resistance). All three can coexist, perhaps with periodic fluctuations (Riley, 2002).

In the same way, increasing the cost of resistance, actually favors resisters by altering this three-way balance. Increasing the cost of resistance initially reduces resisters of course, but that in turn favors the producers, which grow and then in turn reduce the growers which had earlier been plentiful enough to keep the resisters in check. (Reducing Rock, increases Scissors which had cut the Paper population down to size. Low levels of paper, means Rocks are not covered up. That increases Rock, and if it increases high enough it tips over into the basin of attraction favoring all Rock). This type of cyclic dominance can amplify an inbalance, paradoxically tipping one type that is momentarily depleted into complete dominance.

Other research has demonstrated that among certain strains of e-coli, a very small proportion of cells sacrifice their own lives to spread resistance to other cells. This small proportion is enough to spread resistance. I have included that dynamic–choose “two strains with some altruism.” A few altruistic cells will turn yellow briefly, then will die when they spread a protein that confers resistance to other cells. This is a gross simplification but illustrates a general point.

What implications might all this have for antibiotic resistance? We know that many individuals stop taking antibiotics when they feel better. This defiance of doctors orders to take the meds for the full duration, rather than to stop when feeling better can lead to resistance, but also other unexpected consequences. Experiment with this.

Some researchers have tried shaking the flask of bacterial to break up the non-local effects, similar to establishing non-local links. That disrupts the balance, prevents the establishment of biodiversity; eventually one strain takes over. To approximate that effect rry “rewiring” a certain proportion. A certain amount of this “rewiring” creates a “small-world” network, mostly local clustering but links to distant locations.

HOW IT WORKS

The agents follow these rules:

Resister beat Producers (Red beats Purple)
Growers beat Resisters (Green beats Red)
Producers beat Growers (Purple beats Green)

These rules translate to the following Netlogo code, which asks each agent on the grid to check their partner’s color and change it according to the following rules:

if color = red [ask partner [if color = violet [set color red] ] ]
if color = green [ask partner [if color = red [set color green] ] ]
if color = violet [ask partner [if color = green [set color violet] ] ]

Agents first must pair off as partners. When partners lose they change to the winner�s color. So we include commands that ask all agents to pair off with one other agent, at random. At each round of the game, agents again randomly pick a partner.

note:
A similar dynamic is found among three varieties of a certain species of lizard:

Orange throated lizards are aggressive and beat blue throated lizards (rock beat scissors).
Blue throats guard their mates and so beat yellow (as scissors beats paper).
Yellow throats beat orange by stealing orange throat’s mates (paper beats rock).

HOW TO USE IT

Hit setup, then Go.

THINGS TO NOTICE

The three exist in cyclic dominance.

NETLOGO FEATURES

I adapted the Partnering command from the Netlogo Code example “Partners.” I changed that code to work for a grid of neighbors (the Netlogo example had neighbors move around to find a neighbor on the same patch, whereas I wanted agents to find a neighbor to partner with). This partnering command greatly simplifies the programming of the actual game, as we can just refer to “partner.”

CREDITS AND REFERENCES

This supplements chapter 2 of Modeling Behavior in Complex Public Health Systems, by Christopher Keane. Dr. Keane programmed the netlogo version of the model based on well-known Rock-Paper-Scissors models, and wrote up the application to e.coli, based on findings reported by Nahum et al (2011) and Kerr et al (2002), among others. Dr. Keane was able to program the Rock-Paper-Scissors with very simple code by taking advantage of the Netlogo “find partner” code, that comes with NetLogo.

Netlogo by Wilensky 92006). In other publications, please use: Copyright 2006 Uri Wilensky. All rights reserved.

CODE

turtles-own [partner payoff] ;; turtles also have color, but that variable is built into Netlogo, so we don't need to list it.

globals [red-over-time green-over-time violet-over-time total-turtles] 

to setup
  ;;clear-all
  reset-ticks clear-turtles clear-patches clear-drawing clear-plot clear-output
  ask patches [sprout 1] ;; creates one turtle per patch
  ask turtles  [set shape "circle" set color one-of (list green violet red)   set partner nobody]
  update-plot-proportions
  tick
end

to go 

 if selection-mode = "select locally fittest" ;; a common evolutionary game strategy (sometimes called death-birth)
   [
    ask turtles [
       compute-payoff  
       select-best-strategy
                ] 
      ] 

 if selection-mode = "likely select best" 
   [
    ask turtles [
      compute-payoff
      likely-select-best
                 ] 
      ] 


if selection-mode = "bacterial costs and benefits" 
   [
    ask turtles [
      compute-cost-benefit-payoff
      select-best-strategy
                 ] 
      ] 

 if selection-mode = "play with partners"  
  [
   ask turtles [set partner nobody ] 
   ask links [die]
   find-partners
   ask turtles [
     if color = red [ask partner [if color = violet [set color red ] ] ] ;; red beats violet (Rock beats Scissors)
     if color = green [ask partner [if color = red [set color green] ] ] ;; green beats red (Paper beats Rock)
     if color = violet [ask partner [if color = green [set color violet] ] ] ;; violet beats green (Scissors beats Paper)  
                ] 
    ]   



 if selection-mode = "blindly imitate partner" 
    [
  ask turtles [set partner nobody ] 
  ask links [die]
 
 find-partners

 ask turtles [
   set color [color] of partner
            ] 
   ]

 if selection-mode = "blindly imitate majority"
   [
    ask turtles [
      set color one-of modes [color] of (turtles-on neighbors) ;; selects most common, but if two are equally common, selects one-of these
                   ]
    ]           
        
 

   

 

 
 update-plot-proportions
 tick
end

to compute-payoff

   set payoff 0
   
   if color = red [set payoff payoff + count (turtles-on neighbors)  with [color = violet] ;;red beats violet, so get a point 
                                 - count (turtles-on neighbors)  with [color = green]] ;; green beats red, so lose a point
                               
   if color = green [set payoff payoff + count (turtles-on neighbors)  with [color = red] ;; green beats red, so gain a point
                                 - count (turtles-on neighbors)  with [color = violet]] ;; violet beats green, so lose a point

   if color = violet [set payoff payoff + count (turtles-on neighbors)  with [color = green] ;; violet beats green, so gain a point
                                 - count (turtles-on neighbors)  with [color = red]] ;; red beats violet, so lose a point
               
end


to compute-cost-benefit-payoff

   set payoff 0
   
   if color = red [set payoff payoff + count (turtles-on neighbors)  with [color = violet] ;;Resistant (red) beats Producer (Purple), so get a point 
                                 - cost-resist ] ;; cost of Resistance
                               
   if color = green [set payoff payoff + count (turtles-on neighbors)  with [color = red] ;; Grower (green) beats Resistance (red), so gain a point
                                 - cost-grow] ;; cost of Growth

   if color = violet [set payoff payoff + count (turtles-on neighbors)  with [color = green] ;; Producer of bacteriocide (Purple) beats Grower (Green), so gain a point
                                 - cost-produce] ;; cost of Producing bacteriocide
               
end





to select-best-strategy  
   set color one-of modes [color] of ((turtle-set self turtles-on neighbors) with-max [payoff]) 
end

;; The key command for the above "select the best" (select locally fittest) strategy is identifying the turtle with-max [payoff], picking the behavior (color) of that turtle.
;; "modes" picks out the most common color, in case there are several with the highest payoff. 
;; "One-of covers the possibility that more than one color is the most common among the fittest.
;; In the above, "turtle-set" essentially are nine local individuals, including oneself and one's eight neighbors 
;; If we don't use turtle-set, set we just have to first be sure the individual doesn't already have the highest payoff,  with the following:
;;   to select-best-strategy  
;;      if payoff < max [payoff] of (turtles-on neighbors) 
;;        [set color one-of modes [color] of ((turtles-on neighbors) with-max [payoff] )] 
;;   end




to likely-select-best  
  let total-local-fitness sum [payoff] of (turtle-set self turtles-on neighbors)
  let caller self
  
  ask (turtle-set self turtles-on neighbors) [ if total-local-fitness > 0 
    [  
     if random 100 < 100 * payoff / total-local-fitness [ask caller [set color [color] of myself]]    
      ]
               ]           
end

;to likely-select-best  
;if sum [payoff] of (turtle-set self turtles-on neighbors) > 0 
;   [  
;   if random 100 < 100 * payoff / sum [payoff] of (turtle-set self turtles-on neighbors) [ask partner [set color [color] of myself]    
;    ]
;               ]           
;end


to find-partners  ;; only among neighbors, only one partner per individual turtle. This means some turtles will not find a partner. 
   
  if not any? turtles with [partner = nobody] [ stop ]
  ask turtles    ;; ask the unpartnered turtles to check if they are next to a neighbor patch with a turtle that also don't have a partner.
     [
       if (partner = nobody) and (any? (turtle-set self turtles-on neighbors) with [partner = nobody])
        [
         set partner one-of (turtle-set self turtles-on neighbors) with [partner = nobody]
         ask partner [set partner myself] ;; Ask our partner to partner with ourselves.
         ]
      ]
  
ask turtles [
   if random 100 < %non-local 
      [set partner one-of turtles ask partner [set partner myself]]
               ]
 
ifelse show-partners? [ask turtles [set size .8 
   if partner != self and [partner] of partner = self
       [create-link-with partner [set color white]]] ] [ask turtles [set size 1]]

end






to update-plot-proportions 
  set-current-plot "Proportions by time"
  set-current-plot-pen "Resister" ;;Scissors
  plotxy ticks (count turtles with [color = red] / count turtles)
  set-current-plot-pen "Grower" ;; Paper
  plotxy ticks (count turtles with [color = green] / count turtles)
  set-current-plot-pen "Producer" ;; Rock 
  plotxy ticks (count turtles with [color = violet] / count turtles)

end