Skip to content

Commit

Permalink
FictitiousPlay: First version
Browse files Browse the repository at this point in the history
  • Loading branch information
oyamad committed Mar 4, 2019
1 parent b29af1d commit 402da59
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/Games.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ include("random.jl")
include("support_enumeration.jl")
include("generators/Generators.jl")

include("fictplay.jl")

export
# Types
Player, NormalFormGame,
Expand Down Expand Up @@ -96,6 +98,10 @@ export
random_game, covariance_game,

# Support Enumeration
support_enumeration, support_enumeration_task
support_enumeration, support_enumeration_task,

# Learning algorithms
play!, play, time_series,
DecreasingGain, ConstantGain, FictitiousPlay

end # module
89 changes: 89 additions & 0 deletions src/fictplay.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
abstract type AbstractGain end

struct DecreasingGain <: AbstractGain end

mutable struct ConstantGain{T<:Real} <: AbstractGain
epsilon::T
end

step_size(T::Type, gain::DecreasingGain, t::Integer) = one(T)/(t+1)
step_size(T::Type, gain::ConstantGain, t::Integer) = T(gain.epsilon)


struct FictitiousPlay{N,T<:Real,TG<:AbstractGain}
players::NTuple{N,Player{N,T}}
nums_actions::NTuple{N,Int}
gain::TG

function FictitiousPlay{N,T,TG}(g::NormalFormGame{N,T},
gain::TG) where {N,T<:Real,TG<:AbstractGain}
return new(g.players, g.nums_actions, gain)
end
end

FictitiousPlay(g::NormalFormGame{N,T},
gain::TG) where {N,T<:Real,TG<:AbstractGain} =
FictitiousPlay{N,T,TG}(g, gain)
FictitiousPlay(g::NormalFormGame) = FictitiousPlay(g, DecreasingGain())

function play!(fp::FictitiousPlay{N,T}, actions::MixedActionProfile{TA,N},
options::BROptions, brs::Vector{Int},
t::Integer) where {N,T<:Real,TA<:Real}
for i in 1:N
opponents_actions =
tuple(actions[i+1:end]..., actions[1:i-1]...)
brs[i] = best_response(fp.players[i], opponents_actions, options)
end

for i in 1:N
actions[i] .*= 1 - step_size(TA, fp.gain, t)
actions[i][brs[i]] += step_size(TA, fp.gain, t)
end

return actions
end

function play!(fp::FictitiousPlay{N,T}, actions::MixedActionProfile{TA,N},
options::BROptions=BROptions(); num_iter::Integer=1,
t_init::Integer=1) where {N,T<:Real,TA<:Real}
brs = Vector{Int}(undef, N)
for t in t_init:(t_init+num_iter-1)
play!(fp, actions, options, brs, t)
end
return actions
end

function play(fp::FictitiousPlay{N,T}, actions::MixedActionProfile{TA,N},
options::BROptions=BROptions(); num_iter::Integer=1,
t_init::Integer=1) where {N,T<:Real,TA<:Real}
actions_copied = ntuple(i -> copy(actions[i]), N)
play!(fp, actions_copied, options, num_iter=num_iter, t_init=t_init)
end

function time_series!(fp::FictitiousPlay{N,T}, out::NTuple{N,Matrix{TA}},
options::BROptions=BROptions();
t_init::Integer=1) where {N,T<:Real,TA<:Real}
ts_length = size(out[1], 2)
actions = ntuple(i -> out[i][:, 1], N)
brs = Vector{Int}(undef, N)

for j in 2:ts_length
play!(fp, actions, options, brs, t_init - 1 + j - 1)
for i in 1:N
out[i][:, j] = actions[i]
end
end

return out
end

function time_series(fp::FictitiousPlay{N,T}, ts_length::Integer,
init_actions::MixedActionProfile{TA,N},
options::BROptions=BROptions();
t_init::Integer=1) where {N,T<:Real,TA<:Real}
out = ntuple(i -> Matrix{TA}(undef, fp.nums_actions[i], ts_length), N)
for i in 1:N
out[i][:, 1] = init_actions[i]
end
time_series!(fp, out, options, t_init=t_init)
end

0 comments on commit 402da59

Please sign in to comment.