Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Games.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ include("repeated_game.jl")
include("random.jl")
include("support_enumeration.jl")
include("generators/Generators.jl")
include("vertex_enumeration.jl")

export
# Types
Expand Down Expand Up @@ -101,6 +102,9 @@ export
random_pure_actions, random_mixed_actions,

# Support Enumeration
support_enumeration, support_enumeration_task
support_enumeration, support_enumeration_task,

# Vertex Enumeration
vertex_enumeration, vertex_enumeration_task

end # module
102 changes: 102 additions & 0 deletions src/vertex_enumeration.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
function vertex_enumeration(g::NormalFormGame{2};
plib=SimplePolyhedraLibrary{Float64}())

c = Channel(0)
task = vertex_enumeration_task(c, g, plib)
bind(c, task)
schedule(task)
NEs = Tuple{Vector{Real}, Vector{Real}}[NE for NE in c]

return NEs

end

function vertex_enumeration_task(c::Channel,
g::NormalFormGame{2},
plib)

task = Task(
() -> _vertex_enumeration_producer(c, g, plib)
)

return task

end

function _vertex_enumeration_producer(c::Channel,
g::NormalFormGame{2, T},
plib)

n, m = size(g.players[1].payoff_array)

# create Representation for player 1
p1, p2 = construction_BRP(g, plib)
V1 = points(p1)
simplex1 = []
for pidx in eachindex(points(p1))
push!(simplex1, [idx.value for idx in incidenthalfspaceindices(p1, pidx)])
end

V2 = points(p2)
simplex2 = []
for pidx in eachindex(points(p2))
push!(simplex2, [idx.value for idx in incidenthalfspaceindices(p2, pidx)])
end

ZERO_LABELING_BITS = (1 << (n+m)) - (1 << m)
COMPLETE_LABELING_BITS = 1 << (n+m) - 1

for (i, v1) in enumerate(V1)
labelings_bits1 = labelings_bits(simplex1[i])
if labelings_bits1 == ZERO_LABELING_BITS
continue
end
for (j, v2) in enumerate(V2)
labelings_bits2 = labelings_bits(simplex2[j])
if xor(labelings_bits1, labelings_bits2) == COMPLETE_LABELING_BITS
put!(c, (_get_mixed_action(v1),
_get_mixed_action(v2)))
end
end
end

end

function construction_BRP(g::NormalFormGame{2, T}, plib)

n, m = size(g.players[1].payoff_array)

# create Representation for player 1
C = Matrix{T}(n+m, n)
C[1:m, :] = g.players[2].payoff_array
C[m+1:end, :] = -eye(T, n)
b1 = Vector{T}(n+m)
b1[1:m] = one(T)
b1[m+1:end] = zero(T)
H1 = hrep(C, b1)
p1 = polyhedron(H1, plib)

# create Representation for player 2
D = Matrix{T}(n+m, m)
D[1:m, :] = -eye(T, m)
D[m+1:end, :] = g.players[1].payoff_array
b2 = Vector{T}(n+m)
b2[1:m] = zero(T)
b2[m+1:end] = one(T)
H2 = hrep(D, b2)
p2 = polyhedron(H2, plib)

return p1, p2
end

function labelings_bits(inchalfindices::Vector{T}) where T <: Integer
b = 0
for i in inchalfindices
b += 1 << (i-1)
end
return b
end

function _get_mixed_action(a::Vector{T})
return a ./ sum(a)
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ include("test_repeated_game.jl")
include("test_normal_form_game.jl")
include("test_random.jl")
include("test_support_enumeration.jl")
include("test_vertex_enumeration.jl")

include("generators/runtests.jl")
91 changes: 91 additions & 0 deletions test/test_vertex_enumeration.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
@testset "Testing vertex Enumeration" begin

@testset "test 3 by 2 non-degenerate normal form game(Float)" begin
g = NormalFormGame(Player([3.0 3.0; 2.0 5.0; 0.0 6.0]),
Player([3.0 2.0 3.0; 2.0 6.0 1.0]))
NEs = [([0.0, 1/3, 2/3], [1/3, 2/3]),
([0.8, 0.2, 0.0], [2/3, 1/3]),
([1.0, 0.0, 0.0], [1.0, 0.0])]

for (actions_computed, actions) in zip(NEs, vertex_enumeration(g))
for (action_computed, action) in zip(actions_computed, actions)
@test action_computed ≈ action
@test eltype(action_computed) <: AbstractFloat
end
end
end

# @testset "test 3 by 2 non-degenerate normal form game(Int)" begin
# g = NormalFormGame(Player([3 3; 2 5; 0 6]),
# Player([3 2 3; 2 6 1]))
# NEs = [([1.0, 0.0, 0.0], [1.0, 0.0]),
# ([0.8, 0.2, 0.0], [2/3, 1/3]),
# ([0.0, 1/3, 2/3], [1/3, 2/3])]

# for (actions_computed, actions) in zip(NEs, support_enumeration(g))
# for (action_computed, action) in zip(actions_computed, actions)
# @test action_computed ≈ action
# @test eltype(action_computed) <: AbstractFloat
# end
# end
# end

# @testset "test 3 by 2 non-degenerate normal form game(Rational)" begin
# g = NormalFormGame(Player([3//1 3//1; 2//1 5//1; 0//1 6//1]),
# Player([3//1 2//1 3//1; 2//1 6//1 1//1]))
# NEs = [([1//1, 0//1, 0//1], [1//1, 0//1]),
# ([4//5, 1//5, 0//1], [2//3, 1//3]),
# ([0//1, 1//3, 2//3], [1//3, 2//3])]

# for (actions_computed, actions) in zip(NEs, support_enumeration(g))
# for (action_computed, action) in zip(actions_computed, actions)
# @test action_computed ≈ action
# @test eltype(action_computed) <: Rational
# end
# end
# end

@testset "test 3 by 2 degenerate normal form game(Float)" begin
g = NormalFormGame(Player([1.0 -1.0; -1.0 1.0; 0.0 0.0]),
Player([1.0 0.0 0.0; 0.0 0.0 0.0]))
NEs = [([1.0, 0.0, 0.0], [1.0, 0.0]),
([0.0, 1.0, 0.0], [0.0, 1.0])]

for (actions_computed, actions) in zip(NEs, vertex_enumeration(g))
for (action_computed, action) in zip(actions_computed, actions)
@test action_computed ≈ action
@test eltype(action_computed) <: AbstractFloat
end
end
end

# @testset "test 3 by 2 degenerate normal form game(Int)" begin
# g = NormalFormGame(Player([1 -1; -1 1; 0 0]),
# Player([1 0 0; 0 0 0]))
# NEs = [([1.0, 0.0, 0.0], [1.0, 0.0]),
# ([0.0, 1.0, 0.0], [0.0, 1.0])]

# for (actions_computed, actions) in zip(NEs, support_enumeration(g))
# for (action_computed, action) in zip(actions_computed, actions)
# @test action_computed ≈ action
# @test eltype(action_computed) <: AbstractFloat
# end
# end
# end

# @testset "test 3 by 2 degenerate normal form game(Rational)" begin
# g = NormalFormGame(Player([1//1 -1//1; -1//1 1//1; 0//1 0//1]),
# Player([1//1 0//1 0//1; 0//1 0//1 0//1]))
# NEs = [([1//1, 0//1, 0//1], [1//1, 0//1]),
# ([0//1, 1//1, 0//1], [0//1, 1//1])]

# for (actions_computed, actions) in zip(NEs, support_enumeration(g))
# for (action_computed, action) in zip(actions_computed, actions)
# @test action_computed ≈ action
# @test eltype(action_computed) <: Rational
# end
# end
# end


end