mirror of https://github.com/gsi-upm/soil
Added rabbits
parent
dbc182c6d0
commit
af76f54a28
@ -0,0 +1,21 @@
|
||||
---
|
||||
load_module: custom_agents
|
||||
name: custom_agent_example
|
||||
max_time: 2500
|
||||
interval: 1
|
||||
seed: MySimulationSeed
|
||||
agent_type: RabbitModel
|
||||
environment_agents:
|
||||
- agent_type: RandomAccident
|
||||
default_state:
|
||||
mating_prob: 1
|
||||
topology:
|
||||
nodes:
|
||||
- id: 1
|
||||
state:
|
||||
gender: female
|
||||
- id: 0
|
||||
state:
|
||||
gender: male
|
||||
directed: true
|
||||
links: []
|
@ -0,0 +1,103 @@
|
||||
import logging
|
||||
from soil.agents import NetworkAgent, FSM, state, default_state, BaseAgent
|
||||
from enum import Enum
|
||||
from random import random, choice
|
||||
from itertools import islice
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Genders(Enum):
|
||||
male = 'male'
|
||||
female = 'female'
|
||||
|
||||
|
||||
class RabbitModel(NetworkAgent, FSM):
|
||||
|
||||
defaults = {
|
||||
'age': 0,
|
||||
'gender': Genders.male.value,
|
||||
'mating_prob': 0.001,
|
||||
'offspring': 0,
|
||||
}
|
||||
|
||||
sexual_maturity = 4*30
|
||||
life_expectancy = 365 * 3
|
||||
gestation = 33
|
||||
pregnancy = -1
|
||||
max_females = 10
|
||||
|
||||
@default_state
|
||||
@state
|
||||
def newborn(self):
|
||||
self['age'] += 1
|
||||
|
||||
if self['age'] >= self.sexual_maturity:
|
||||
return self.fertile
|
||||
|
||||
@state
|
||||
def fertile(self):
|
||||
self['age'] += 1
|
||||
if self['age'] > self.life_expectancy:
|
||||
return self.dead
|
||||
|
||||
if self['gender'] == Genders.female.value:
|
||||
return
|
||||
|
||||
# Males try to mate
|
||||
females = self.get_agents(state_id=self.fertile.id, gender=Genders.female.value, limit_neighbors=False)
|
||||
for f in islice(females, self.max_females):
|
||||
r = random()
|
||||
if r < self['mating_prob']:
|
||||
self.impregnate(f)
|
||||
break # Take a break
|
||||
|
||||
def impregnate(self, whom):
|
||||
if self['gender'] == Genders.female.value:
|
||||
raise NotImplementedError('Females cannot impregnate')
|
||||
whom['pregnancy'] = 0
|
||||
whom['mate'] = self.id
|
||||
whom.set_state(whom.pregnant)
|
||||
logger.debug('{} impregnating: {}. {}'.format(self.id, whom.id, whom.state))
|
||||
|
||||
@state
|
||||
def pregnant(self):
|
||||
self['age'] += 1
|
||||
if self['age'] > self.life_expectancy:
|
||||
return self.dead
|
||||
|
||||
self['pregnancy'] += 1
|
||||
logger.debug('Pregnancy: {}'.format(self['pregnancy']))
|
||||
if self['pregnancy'] >= self.gestation:
|
||||
|
||||
state = {}
|
||||
state['gender'] = choice(list(Genders)).value
|
||||
child = self.env.add_node(self.__class__, state)
|
||||
self.env.add_edge(self.id, child.id)
|
||||
self.env.add_edge(self['mate'], child.id)
|
||||
# self.add_edge()
|
||||
logger.info("A rabbit has been born: {}. Total: {}".format(child.id, len(self.global_topology.nodes)))
|
||||
self['offspring'] += 1
|
||||
self.env.get_agent(self['mate'])['offspring'] += 1
|
||||
del self['mate']
|
||||
self['pregnancy'] = -1
|
||||
return self.fertile
|
||||
|
||||
@state
|
||||
def dead(self):
|
||||
logger.info('Agent {} is dying'.format(self.id))
|
||||
if 'pregnancy' in self and self['pregnancy'] > -1:
|
||||
logger.info('A mother has died carrying a baby!: {}!'.format(self.state))
|
||||
self.die()
|
||||
return
|
||||
|
||||
|
||||
class RandomAccident(BaseAgent):
|
||||
|
||||
def step(self):
|
||||
logger.debug('Killing some rabbits!')
|
||||
prob_death = self.env.get('prob_death', -1)
|
||||
for i in self.env.network_agents:
|
||||
r = random()
|
||||
if r < prob_death:
|
||||
logger.info('I killed a rabbit: {}'.format(i.id))
|
||||
i.set_state(i.dead)
|
Loading…
Reference in New Issue