``````

In [1]:

type Agent{TI<:Integer, TF<:AbstractFloat}
kind::TI
location::Vector{TF}
end

#goddamnit this is so annoying. I'm jus goingto run this here at the start
#so it is run and then the rest can just sort itself out

# holy crap! once we sorted that, it worked!!! I've actually implemented Schellings
#model in julia!!! that's really great!

``````
``````

In [6]:

#okay, this is following the quantitive econ course on the schelling model
# should be fun to try implementing this briefly
#more fun than my phd work i'm procrastinating out of anyhow!
using Plots
#using PyPlot
pyplot()
#ioff() # necessary for inline plotting
srand(42) # set the seed for random numbers so wecan have reproducible output

``````
``````

UndefVarError: ioff not defined

``````
``````

In [5]:

# constructor
Agent(k::Integer) = Agent(k, rand(2))

function draw_location!(a::Agent)
a.location = rand(2)
nothing
end

# distance is just 2 norm: uses our subtraction function
get_distance(a::Agent, o::Agent) = norm(a.location - o.location)

function is_happy(a::Agent, others::Vector{Agent})
"True if sufficient number of nearest neighbors are of the same type."
# distances is a list of pairs (d, agent), where d is distance from
# agent to self
distances = Any[]

for agent in others
if a != agent
dist = get_distance(a, agent)
push!(distances, (dist, agent))
end
end

# == Sort from smallest to largest, according to distance == #
sort!(distances)

# == Extract the neighboring agents == #
neighbors = [agent for (d, agent) in distances[1:num_neighbors]]

# == Count how many neighbors have the same type as self == #
num_same_type = sum([a.kind == other.kind for other in neighbors])

return num_same_type >= require_same_type
end

function update!(a::Agent, others::Vector{Agent})
"If not happy, then randomly choose new locations until happy."
while !is_happy(a, others)
draw_location!(a)
end
return nothing
end

function plot_distribution(agents::Vector{Agent}, cycle_num)
x_vals_0, y_vals_0 = Float64[], Float64[]
x_vals_1, y_vals_1 = Float64[], Float64[]

# == Obtain locations of each type == #
for agent in agents
x, y = agent.location
if agent.kind == 0
push!(x_vals_0, x)
push!(y_vals_0, y)
else
push!(x_vals_1, x)
push!(y_vals_1, y)
end
end

p = scatter(x_vals_0, y_vals_0, color=:orange, markersize=8, alpha=0.6)
scatter!(x_vals_1, y_vals_1, color=:green, markersize=8, alpha=0.6)
plot!(title="Cycle \$(cycle_num)", legend=:none)

return p
end;

# == Main == #

num_of_type_0 = 250
num_of_type_1 = 250
num_neighbors = 10      # Number of agents regarded as neighbors
require_same_type = 5   # Want at least this many neighbors to be same type

# == Create a list of agents == #
agents = Agent[Agent(0) for i in 1:num_of_type_0]
push!(agents, [Agent(1) for i in 1:num_of_type_1]...)

count = 1

# ==  Loop until none wishes to move == #
while true
println("Entering loop \$count")
p = plot_distribution(agents, count)
display(p)
count += 1
no_one_moved = true
movers = 0
for agent in agents
old_location = agent.location
update!(agent, agents)
if !isapprox(0.0, maximum(old_location - agent.location))
no_one_moved = false
end
end
if no_one_moved
break
end
end

println("Converged, terminating")
#workspace()

``````
``````

Entering loop 1

WARNING: Method definition (::Type{Main.Agent})(Integer) in module Main at In[4]:3 overwritten at In[5]:3.
WARNING: Method definition draw_location!(Main.Agent) in module Main at In[4]:7 overwritten at In[5]:7.
WARNING: Method definition get_distance(Main.Agent, Main.Agent) in module Main at In[4]:12 overwritten at In[5]:12.
WARNING: Method definition is_happy(Main.Agent, Array{Main.Agent, 1}) in module Main at In[4]:15 overwritten at In[5]:15.
WARNING: Method definition update!(Main.Agent, Array{Main.Agent, 1}) in module Main at In[4]:40 overwritten at In[5]:40.
WARNING: Method definition plot_distribution(Array{Main.Agent, 1}, Any) in module Main at In[4]:49 overwritten at In[5]:49.

Entering loop 2

Entering loop 3

Entering loop 4
Converged, terminating

``````
``````

In [17]:

# our main functoin, where we ste up variables and run the mode

num_type_0 = 250
num_type_1 = 250
num_neighbours = 10
require_same_type=5

#create a list of agents
agents = Agent[Agent(0) for i in 1:num_type_0]
push!(agents,[Agent(1) for i in 1:num_type_1]...)

count = 1

# loop until none wish to move
while true
println("Entering loop \$count")
p = plot_distribution(agents, count)
display(p)
count +=1
no_one_moved=true
movers = 0
for agent in agents
old_location = agent.location
update!(agent, agents)
if !isapprox(0.0, maximum(old_location-agent.location))
no_one_moved = false
end
end
if no_one_moved
break
end
end
println("Converged, terminating")

workspace()

``````
``````

Entering loop 1

MethodError: no method matching colon(::ColorTypes.#color, ::ColorTypes.#green)
Closest candidates are:
colon{T}(::T, ::Any, ::T) at range.jl:118
colon{T<:Real}(::T<:Real, ::Any, ::T<:Real) at range.jl:114
colon{A<:Real,C<:Real}(::A<:Real, ::Any, ::C<:Real) at range.jl:112
...

in plot_distribution(::Array{Agent,1}, ::Int64) at ./In[8]:66
in macro expansion; at ./In[17]:17 [inlined]
in anonymous at ./<missing>:?

``````
``````

In [ ]:

``````