# A template for bootstrapping new models. # See https://helipad.dev/ for complete documentation #=============== # SETUP # Instantiate the object and add parameters, breeds, and goods below. #=============== from helipad import Helipad # from utility import CobbDouglas heli = Helipad() heli.name = 'Model Name' heli.order = 'random' #Can be changed to 'linear' or 'match' heli.stages = 1 #Change to create a multi-stage model # heli.addParameter('name', 'title', 'type (slider, menu, or check)', dflt=default, opts={depends on type}) # heli.addGood('good1','hex color', lambda breed: endowment) # heli.addBreed('name1', 'hex color') # heli.addBreed('name2', 'hex color') #=============== # BEHAVIOR # A list of hooks and their function signatures can be found at http://helipad-docs.nfshost.com/hooks/ #=============== #Any variables or properties the agent should keep track of should have default values set here. @heli.hook def agentInit(agent, model): #agent.myAgentProperty = 0
# A sample spatial model with agents eating grass off patches. # No visualization as of yet #=============== # SETUP #=============== from helipad import Helipad heli = Helipad() heli.name = 'Grass Eating' heli.order = 'random' heli.stages = 5 heli.addParameter('energy', 'Energy from grass', 'slider', dflt=2, opts={'low': 2, 'high': 10, 'step': 1}) heli.addParameter('smart', 'Smart consumption', 'check', dflt=True) heli.addParameter('e2reproduce', 'Energy to reproduce', 'slider', dflt=25, opts={'low': 0, 'high': 100, 'step': 5}) heli.addParameter('maleportion', 'Male portion reproduction', 'slider', dflt=40, opts={'low': 0, 'high': 100, 'step': 5}) heli.addParameter('maxLife', 'Max Lifespan', 'slider', dflt=200, opts={'low': 100, 'high': 1000, 'step': 10}) heli.addParameter('grassrate', 'Grass Rate', 'slider', dflt=10, opts={'low': 1, 'high': 100, 'step': 1}) heli.params['num_agent'].opts = {'low': 1, 'high': 200, 'step': 1} heli.param('num_agent', 200) heli.addBreed('male', 'blue') heli.addBreed('female', 'pink') heli.addGood('energy', 'red', 5) from random import choice, randint from numpy import mean
# Replicates the repeated PD tournament from Axelrod (1980) # Paper here: https://www.jstor.org/stable/173932 # Strategies indexed here: https://axelrod.readthedocs.io/en/stable/reference/overview_of_strategies.html#axelrod-s-first-tournament # Strategies requiring chi-squared tests for randomness or such not yet implemented # Difference from the original: The tournament matches stochastically, rather than being a round-robin, and repeats. #=============== # SETUP #=============== from helipad import Helipad import numpy.random as random from numpy import mean heli = Helipad() heli.name = 'Axelrod Tournament' heli.order = 'match' heli.params[ 'num_agent'].type = 'hidden' #So we can postpone breed determination until the end #Initial parameter values match the payoffs in Table 1 heli.addParameter('cc', 'C-C payoff', 'slider', dflt=3, opts={ 'low': 0, 'high': 10, 'step': 0.5 })
# A model of the long-run cyclical dynamics of urbanization and human capital. from collections import namedtuple import pandas, random as rand2 from helipad import Helipad from math import sqrt, log, floor from numpy import * heli = Helipad() #================ # CONFIGURATION #================ heli.addBreed('urban', '#CC0000') heli.addBreed('rural', '#00CC00') heli.addGood('consumption', '#000000') #Constrain the parameter space to values resulting in H* = 100 def constrain(model, var, val): if var=='city': model.params['rent'].disabled(val) elif model.param('city'): if var=='fixed': model.params['rent'].enable() #Tkinter won't let you update the value of a disabled widget... model.param('rent', .3099+.4598*val) model.params['rent'].disable() elif var=='rent': model.param('fixed', 2.1748486*val-.67398869) heli.addParameter('city', 'City?', 'check', True, desc='Whether agents have the possibility of moving to the city', callback=constrain) heli.addParameter('breedThresh', 'Breeding Threshold (φ)', 'slider', dflt=20, opts={'low':5, 'high': 500, 'step': 5}, desc='Proportional to the minimum wealth necessary to breed') heli.addParameter('movecost', 'Moving Cost (ω)', 'slider', dflt=15, opts={'low':0, 'high': 150, 'step': 1}, desc='Cost incurred by moving location')
# A decentralized price discovery model with random matching #=============== # SETUP #=============== from helipad import Helipad from helipad.utility import CobbDouglas from math import sqrt, exp, floor import random heli = Helipad() heli.order = 'random' heli.addParameter('ratio', 'Log Endowment Ratio', 'slider', dflt=0, opts={ 'low': -3, 'high': 3, 'step': 0.5 }) heli.addGood('shmoo', '11CC00', lambda breed: random.randint(1, 1000)) heli.addGood( 'soma', 'CC0000', lambda breed: random.randint(1, floor(exp(heli.param('ratio')) * 1000))) #=============== # BEHAVIOR #===============
# A decentralized price discovery model with random matching #=============== # SETUP #=============== from helipad import Helipad from helipad.utility import CobbDouglas from math import sqrt, exp, floor import random heli = Helipad() heli.name = 'Price Discover' heli.order = 'match' heli.addParameter('ratio', 'Log Endowment Ratio', 'slider', dflt=0, opts={ 'low': -3, 'high': 3, 'step': 0.5 }, runtime=False) heli.params['num_agent'].opts['step'] = 2 #Make sure we don't get stray agents heli.params['num_agent'].opts['low'] = 2 #Make sure we don't get stray agents heli.addGood('shmoo', '#11CC00', (1, 1000)) heli.addGood('soma', '#CC0000', lambda breed: (1, floor(exp(heli.param('ratio')) * 1000)))
# A model of the long-run cyclical dynamics of urbanization and human capital. from collections import namedtuple import pandas from helipad import Helipad from math import sqrt, log from numpy import * import random as rand2 heli = Helipad() #================ # CONFIGURATION #================ heli.addBreed('urban', 'CC0000') heli.addBreed('rural', '00CC00') heli.addGood('consumption', '000000') heli.addParameter('breedThresh', 'Breeding Threshold (φ)', 'slider', dflt=20, opts={ 'low': 5, 'high': 500, 'step': 5 }, desc='Proportional to the minimum wealth necessary to breed') heli.addParameter('movecost', 'Moving Cost (ω)',
# A group-selection model of the evolution of cooperation with deme extinction # Loosely based on chapter 7.1 of Bowles and Gintis, "A Cooperative Species" #=============== # SETUP #=============== from helipad import Helipad, MultiLevel, Agent from random import choice import numpy.random as nprand from math import exp, sqrt heli = Helipad() heli.name = 'Deme Selection' heli.order = ['linear', 'linear', 'match'] heli.stages = 3 #Stage 1 for intra-demic competition, stage 2 for reproduction, stage 3 for war heli.addPrimitive('deme', MultiLevel, dflt=20, priority=1) heli.removePrimitive('agent') heli.addParameter('b', 'Benefit conferred', 'slider', dflt=6, opts={ 'low': 0, 'high': 10, 'step': 1 }) heli.addParameter('c', 'Cost incurred', 'slider',
#Registers parameters of every available type in order to test the rendering of the control panel, and runs a dummy model to test the Charts visualizer. #=============== # PREAMBLE #=============== from helipad import Helipad heli = Helipad() heli.name = 'Test' #A handful of breeds and goods breeds = [('hobbit', 'jam', '#D73229'), ('dwarf', 'axe', '#2D8DBE'), ('elf', 'lembas', '#CCBB22')] AgentGoods = {} for b in breeds: heli.addBreed(b[0], b[2], prim='agent') heli.addGood(b[1], b[2]) def gcallback(model, name, val): print(name, '=', val) def icallback(model, name, item, val): print(name, '/', item, '=', val) #=============== # ADD PARAMETERS #===============
#A reconstruction of Hurford (1991), "The Evolution of the Critical Period for Language Acquisition" #https://www.sciencedirect.com/science/article/abs/pii/001002779190024X from helipad import Helipad, Agent import random from numpy.random import choice from numpy import mean heli = Helipad() heli.name = 'Critical Period' heli.order = 'random' heli.addParameter('pleio', 'Pleiotropy', 'slider', dflt=7, opts={'low': 0, 'high': 10, 'step': 1}, runtime=False) heli.addParameter('acq', 'Acquisition from', 'menu', dflt='mother', opts={'mother': 'Mother', 'wholepop': 'Whole Population'}) heli.addParameter('condition', 'Language affects', 'menu', dflt='rep', opts={'rep': 'Reproduction', 'srv': 'Survival'}) heli.params['num_agent'].opts['step'] = 10 #Need it to be divisible by the number of life stages heli.params['num_agent'].opts['low'] = 10 heli.param('num_agent', 30) #Returns language capacity def capacity(self, gene=None, age=None): if gene is None: gene = self.dominantLap if age is None: age=self.age start = (10-self.model.param('pleio'))*age l = sum(gene[start:start+10]) return 0 if l<0 else l Agent.capacity = capacity @heli.hook
# An implementation of Conway's Game Of Life # https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life from helipad import Helipad heli = Helipad() heli.name = 'Game of Life' heli.stages = 2 heli.param('refresh', 1) heli.removePrimitive('agent') mapPlot = heli.spatial(x=30, square=True, wrap=True, diag=True) mapPlot.config('patchProperty', 'active') @heli.hook def patchInit(patch, model): patch.active = False @heli.hook def patchStep(patch, model, stage): if stage == 1: #Calculate neighbors *before* dying or coming to life patch.activeNeighbors = len([n for n in patch.neighbors if n.active]) elif stage == 2: if patch.active and not 1 < patch.activeNeighbors < 4: patch.active = False elif not patch.active and patch.activeNeighbors == 3: patch.active = True