Skip to content

Instantly share code, notes, and snippets.

@bkamins
Last active July 30, 2018 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bkamins/88a3e547a4c56fce668a544cc6f09f8f to your computer and use it in GitHub Desktop.
Save bkamins/88a3e547a4c56fce668a544cc6f09f8f to your computer and use it in GitHub Desktop.
SSC2018 introduction to agent-based modeling in Julia
using Random
function setup(density)
[x == 1 ? 2 : rand() < density ? 1 : 0 for x in 1:251, y in 1:251]
end
function go(grid)
any(isequal(2), grid) || return true
for pos in shuffle!(findall(isequal(2), grid))
x, y = pos[1], pos[2]
for (dx, dy) in ((0, 1), (0, -1), (1, 0), (-1, 0))
nx, ny = x + dx, y + dy
if all((0,0) .< (nx, ny) .≤ size(grid)) && grid[nx, ny] == 1
grid[nx, ny] = 2
end
end
grid[pos] = 3
end
return false
end
function go_repeat(density)
grid = setup(density)
init_green = count(isequal(1), grid)
while true
go(grid) && return count(isequal(3), grid) / init_green * 100
end
end
@time [go_repeat(0.55) for i in 1:100];
@time [go_repeat(0.75) for i in 1:100];
using Random
mutable struct Tree
state::Symbol
when::Int
Tree(state, when=0) = new(state, when)
end
function setup(density)
[Tree(x == 1 ? :red : rand() < density ? :green : :black) for x in 1:251, y in 1:251]
end
function go(grid, tick)
any(t -> t.state == :red, grid) || return true
for pos in shuffle!(findall(t -> t.state == :red, grid))
x, y = pos[1], pos[2]
for (dx, dy) in ((0, 1), (0, -1), (1, 0), (-1, 0))
nx, ny = x + dx, y + dy
if all((0,0) .< (nx, ny) .≤ size(grid)) && grid[nx, ny].state == :green
grid[nx, ny].state = :red
end
end
grid[pos].state = :brown
grid[pos].when = tick
end
return false
end
function go_repeat(density)
grid = setup(density)
init_green = count(t -> t.state == :green, grid)
tick = 1
while true
go(grid, tick) && return count(t -> t.state == :brown, grid) / init_green * 100
tick += 1
end
end
@time [go_repeat(0.55) for i in 1:100];
@time [go_repeat(0.75) for i in 1:100];
using Random
struct TreeGreen
end
struct TreeRed
end
struct TreeBrown
when::Int
end
function setup(density)
[x == 1 ? TreeRed() : rand() < density ?
TreeGreen() : nothing for x in 1:251, y in 1:251]
end
function go(grid, tick)
any(isequal(TreeRed()), grid) || return true
for pos in shuffle!(findall(isequal(TreeRed()), grid))
x, y = pos[1], pos[2]
for (dx, dy) in ((0, 1), (0, -1), (1, 0), (-1, 0))
nx, ny = x + dx, y + dy
if all((0,0) .< (nx, ny) .≤ size(grid)) && grid[nx, ny] isa TreeGreen
grid[nx, ny] = TreeRed()
end
end
grid[pos] = TreeBrown(tick)
end
return false
end
function go_repeat(density)
grid = setup(density)
init_green = count(isequal(TreeGreen()), grid)
tick = 1
while true
go(grid, tick) && return count(t -> t isa TreeBrown, grid) / init_green * 100
tick += 1
end
end
@time [go_repeat(0.55) for i in 1:100];
@time [go_repeat(0.75) for i in 1:100];
using Random
struct TreeID
typ::Int
loc::Int
end
struct TreeGreen
end
struct TreeRed
x::Int
y::Int
end
struct TreeBrown
when::Int
end
function setup(density)
trees = (TreeGreen[], TreeRed[], TreeBrown[])
grid = Matrix{TreeID}(undef, 251, 251)
for x in axes(grid, 1), y in axes(grid, 2)
if x == 1
push!(trees[2], TreeRed(x, y))
grid[x, y] = TreeID(2, length(trees[2]))
elseif rand() < density
push!(trees[1], TreeGreen())
grid[x, y] = TreeID(1, length(trees[1]))
else
grid[x, y] = TreeID(0, 0)
end
end
grid, trees
end
function burn(t, grid, trees, tick)
for (dx, dy) in ((0, 1), (0, -1), (1, 0), (-1, 0))
nx, ny = t.x + dx, t.y + dy
if all((0,0) .< (nx, ny) .≤ size(grid)) && grid[nx, ny].typ == 1
push!(trees[2], TreeRed(nx, ny))
grid[nx, ny] = TreeID(2, length(trees[2]))
end
end
push!(trees[3], TreeBrown(tick))
grid[t.x, t.y] = TreeID(3, length(trees[3]))
end
function go(grid, trees, tick)
any(t -> t.typ == 2, grid) || return true
for pos in shuffle!(findall(t -> t.typ == 2, grid))
burn(trees[2][grid[pos].loc], grid, trees, tick)
end
return false
end
function go_repeat(density)
grid, trees = setup(density)
init_green = count(t -> t.typ == 1, grid)
tick = 1
while true
go(grid, trees, tick) && return count(t -> t.typ == 3, grid) / init_green * 100
tick += 1
end
end
@time [go_repeat(0.55) for i in 1:100];
@time [go_repeat(0.75) for i in 1:100];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment