convert animal parameters to model parameters to make them adjustable in GLMakie
parent
78552bb044
commit
fbf2453ccd
|
@ -15,6 +15,10 @@ mutable struct AnimalDefinition
|
|||
dangers::Vector{String}
|
||||
food::Vector{String}
|
||||
end
|
||||
reproduction_prop(a) = abmproperties(model)[Symbol(a.def.type*"_"*"reproduction_prob")]
|
||||
Δenergy(a) = abmproperties(model)[Symbol(a.def.type*"_"*"Δenergy")]
|
||||
perception(a) = abmproperties(model)[Symbol(a.def.type*"_"*"perception")]
|
||||
energy_threshold(a) = abmproperties(model)[Symbol(a.def.type*"_"*"energy_threshold")]
|
||||
struct StartDefinition
|
||||
n::Int32
|
||||
def::AnimalDefinition
|
||||
|
@ -30,8 +34,8 @@ end
|
|||
|
||||
|
||||
function perceive!(a::Animal,model)
|
||||
if a.def.perception > 0
|
||||
nearby = collect(nearby_agents(a, model, a.def.perception))
|
||||
if perception(a) > 0
|
||||
nearby = collect(nearby_agents(a, model, perception(a)))
|
||||
a.nearby_dangers = map(x -> x.pos, filter(x -> isa(x, Animal) && x.def.type ∈ a.def.dangers && isnothing(x.death_cause), nearby))
|
||||
a.nearby_food = map(x -> x.pos, filter(x -> isa(x, Animal) && x.def.type ∈ a.def.food && isnothing(x.death_cause), nearby))
|
||||
if "Grass" ∈ a.def.food
|
||||
|
@ -65,7 +69,7 @@ function calculate_best_pos(a::Animal,model)
|
|||
push!(danger_scores,danger_score)
|
||||
end
|
||||
if !isempty(a.nearby_food)
|
||||
food_score = sum(map(food -> findmax(abs.(pos.-danger))[1], a.nearby_food))
|
||||
food_score = sum(map(food -> findmax(abs.(pos.-food))[1], a.nearby_food))
|
||||
push!(food_scores,food_score)
|
||||
end
|
||||
end
|
||||
|
@ -86,7 +90,7 @@ function eat!(a::Animal, model)
|
|||
if !isnothing(prey)
|
||||
#remove_agent!(dinner, model)
|
||||
prey.death_cause = Predation
|
||||
a.energy += prey.def.Δenergy
|
||||
a.energy += Δenergy(prey)
|
||||
end
|
||||
if "Grass" ∈ a.def.food && model.fully_grown[a.pos...]
|
||||
model.fully_grown[a.pos...] = false
|
||||
|
@ -95,7 +99,7 @@ function eat!(a::Animal, model)
|
|||
return
|
||||
end
|
||||
function reproduce!(a::Animal, model)
|
||||
if a.energy > a.def.energy_threshold && rand(abmrng(model)) ≤ a.def.reproduction_prob
|
||||
if a.energy > energy_threshold(a) && rand(abmrng(model)) ≤ reproduction_prop(a)#a.def.reproduction_prob
|
||||
a.energy /= 2
|
||||
replicate!(a, model)
|
||||
end
|
||||
|
@ -122,7 +126,7 @@ function move_towards!(agent, pos, model; ifempty=true)
|
|||
walk!(agent,direction,model; ifempty=ifempty)
|
||||
end
|
||||
function nearby_fully_grown(a::Animal, model)
|
||||
nearby_pos = nearby_positions(a.pos, model, a.def.perception)
|
||||
nearby_pos = nearby_positions(a.pos, model, perception(a))
|
||||
fully_grown_positions = filter(x -> model.fully_grown[x...], collect(nearby_pos))
|
||||
return fully_grown_positions
|
||||
end
|
||||
|
@ -165,19 +169,19 @@ function initialize_model(;
|
|||
## Notice how the properties are a `NamedTuple` to ensure type stability.
|
||||
## define as dictionary(mutable) instead of tuples(immutable) as per https://github.com/JuliaDynamics/Agents.jl/issues/727
|
||||
## maybe instead of AnimalDefinition we build the properties dict dynamically and use model properties during the simulation
|
||||
animal_defs = Vector{AnimalDefinition}()
|
||||
for start_def in start_defs
|
||||
push!(animal_defs,start_def.def)
|
||||
end
|
||||
animal_properties = generate_animal_parameters(animal_defs)
|
||||
properties = Dict(
|
||||
:events => events,
|
||||
:fully_grown => falses(dims),
|
||||
:countdown => zeros(Int, dims),
|
||||
:regrowth_time => regrowth_time,
|
||||
:Δenergy_sheep => Δenergy_sheep,
|
||||
:Δenergy_wolf => Δenergy_wolf,
|
||||
:Δenergy_grass => Δenergy_grass,
|
||||
:sheep_reproduce => sheep_reproduce,
|
||||
:wolf_reproduce => wolf_reproduce,
|
||||
:sheep_perception => sheep_perception,
|
||||
:wolf_perception => wolf_perception
|
||||
)
|
||||
properties = merge(properties,animal_properties)
|
||||
model = StandardABM(Animal, space;
|
||||
agent_step! = animal_step!, model_step! = model_step!,
|
||||
properties, rng, scheduler = Schedulers.Randomly(), warn = false, agents_first = false
|
||||
|
@ -317,6 +321,28 @@ function event_handler!(model)
|
|||
end
|
||||
end
|
||||
|
||||
function generate_animal_parameters(defs::Vector{AnimalDefinition})
|
||||
parameter_dict = Dict()
|
||||
for def in defs
|
||||
parameter_dict[Symbol(def.type*"_"*"Δenergy")]=def.Δenergy
|
||||
parameter_dict[Symbol(def.type*"_"*"reproduction_prob")]=def.reproduction_prob
|
||||
parameter_dict[Symbol(def.type*"_"*"perception")]=def.perception
|
||||
parameter_dict[Symbol(def.type*"_"*"energy_threshold")]=def.energy_threshold
|
||||
end
|
||||
return parameter_dict
|
||||
end
|
||||
|
||||
function generate_animal_parameter_ranges(defs::Vector{AnimalDefinition})
|
||||
parameter_range_dict = Dict()
|
||||
for def in defs
|
||||
parameter_range_dict[Symbol(def.type*"_"*"Δenergy")]=0:1:100
|
||||
parameter_range_dict[Symbol(def.type*"_"*"reproduction_prob")]=0:0.01:1
|
||||
parameter_range_dict[Symbol(def.type*"_"*"perception")]=0:1:10
|
||||
parameter_range_dict[Symbol(def.type*"_"*"energy_threshold")]=0:1:100
|
||||
end
|
||||
return parameter_range_dict
|
||||
end
|
||||
|
||||
|
||||
mutable struct RecurringEvent
|
||||
name::String
|
||||
|
|
|
@ -9,7 +9,28 @@
|
|||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[32m\u001b[1m Activating\u001b[22m\u001b[39m project at `~/SCJ/Projekt/SCJ-PredatorPrey/env`\n"
|
||||
"\u001b[32m\u001b[1m Activating\u001b[22m\u001b[39m project at `~/Studium/SCJ-PredatorPrey/env`\n",
|
||||
"\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mSpecialFunctions\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mColorVectorSpace → SpecialFunctionsExt\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mSpecialFunctions → SpecialFunctionsChainRulesCoreExt\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mDualNumbers\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mHypergeometricFunctions\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mStatsFuns\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mStatsFuns → StatsFunsInverseFunctionsExt\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mStatsFuns → StatsFunsChainRulesCoreExt\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mDistributions\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mDistributions → DistributionsTestExt\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mDistributions → DistributionsChainRulesCoreExt\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mKernelDensity\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mStreamSampling\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39mAgents\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mMakie\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39m\u001b[90mAgents → AgentsVisualizations\u001b[39m\n",
|
||||
"\u001b[32m ✓ \u001b[39mAgentsExampleZoo\n",
|
||||
"\u001b[32m ✓ \u001b[39mCairoMakie\n",
|
||||
"\u001b[32m ✓ \u001b[39mGLMakie\n",
|
||||
" 19 dependencies successfully precompiled in 272 seconds. 270 already precompiled.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@ -60,22 +81,12 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[32m\u001b[1mStatus\u001b[22m\u001b[39m `~/SCJ/Projekt/SCJ-PredatorPrey/env/Manifest.toml`\n",
|
||||
" \u001b[90m[46ada45e] \u001b[39mAgents v6.0.13\n",
|
||||
" \u001b[90m[e9467ef8] \u001b[39mGLMakie v0.10.2\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"include(\"./predator_prey_generic.jl\")\n",
|
||||
"Pkg.status([\"Agents\",\"GLMakie\"]; mode = Pkg.Types.PKGMODE_MANIFEST, io=stdout)\n",
|
||||
"#Pkg.status([\"Agents\",\"GLMakie\"]; mode = Pkg.Types.PKGMODE_MANIFEST, io=stdout)\n",
|
||||
"using GLMakie\n",
|
||||
"GLMakie.activate!()\n",
|
||||
"events = RecurringEvent[]\n",
|
||||
|
@ -86,6 +97,7 @@
|
|||
"sheep_def = AnimalDefinition('●',RGBAf(1.0, 1.0, 1.0, 0.8),20, 0.3, 20, 3, \"Sheep\", [\"Wolf\",\"Bear\"], [\"Grass\"])\n",
|
||||
"wolf_def = AnimalDefinition('▲',RGBAf(0.2, 0.2, 0.3, 0.8),20, 0.07, 20, 1, \"Wolf\", [], [\"Sheep\"])\n",
|
||||
"bear_def = AnimalDefinition('■',RGBAf(1.0, 0.8, 0.5, 0.8),20, 0.07, 20, 1, \"Bear\", [], [\"Sheep\"])\n",
|
||||
"parameter_ranges = generate_animal_parameter_ranges([sheep_def,wolf_def,bear_def])\n",
|
||||
"\n",
|
||||
"stable_params = (;\n",
|
||||
" events = events,\n",
|
||||
|
@ -100,7 +112,7 @@
|
|||
" :regrowth_time => 0:1:100,\n",
|
||||
" :Δenergy_grass => 0:1:50,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"params = merge(params,parameter_ranges)\n",
|
||||
"sheep(a) = a.def.type == \"Sheep\"\n",
|
||||
"wolf(a) = a.def.type == \"Wolf\"\n",
|
||||
"eaten(a) = a.def.type == \"Sheep\" && a.death_cause == Predation\n",
|
||||
|
|
Loading…
Reference in New Issue