Skip to content
Merged
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: 3 additions & 3 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ agg_SOURCES = \

game_SOURCES = \
src/gambit.h \
src/games/gameseq.cc \
src/games/gameseq.h \
src/games/ndarray.h \
src/games/number.h \
src/games/gameobject.h \
src/games/game.cc \
Expand Down Expand Up @@ -398,9 +401,6 @@ gambit_nashsupport_SOURCES = \

gambit_enumpoly_SOURCES = \
${core_SOURCES} ${game_SOURCES} ${gambit_nashsupport_SOURCES} \
src/solvers/enumpoly/ndarray.h \
src/solvers/enumpoly/gameseq.cc \
src/solvers/enumpoly/gameseq.h \
src/solvers/enumpoly/indexproduct.h \
src/solvers/enumpoly/rectangle.h \
src/solvers/enumpoly/poly.cc \
Expand Down
52 changes: 52 additions & 0 deletions src/games/behavspt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//

#include "gambit.h"
#include "gameseq.h"

namespace Gambit {

Expand Down Expand Up @@ -259,4 +260,55 @@ std::list<GameNode> BehaviorSupportProfile::GetMembers(const GameInfoset &p_info
return answer;
}

//========================================================================
// BehaviorSupportProfile: Sequence form
//========================================================================

std::shared_ptr<GameSequenceForm> BehaviorSupportProfile::GetSequenceForm() const
{
if (!m_sequenceForm) {
m_sequenceForm = std::make_shared<GameSequenceForm>(*this);
}
return m_sequenceForm;
}

SequencesWrapper BehaviorSupportProfile::GetSequences() const
{
return SequencesWrapper(GetSequenceForm()->GetSequences());
}

PlayerSequencesWrapper BehaviorSupportProfile::GetSequences(GamePlayer &p_player) const
{
return PlayerSequencesWrapper(GetSequenceForm()->GetSequences(p_player));
}

int BehaviorSupportProfile::GetConstraintEntry(const GameInfoset &p_infoset,
const GameAction &p_action) const
{
return GetSequenceForm()->GetConstraintEntry(p_infoset, p_action);
}

const Rational &BehaviorSupportProfile::GetPayoff(
const std::map<GamePlayer, std::shared_ptr<GameSequenceRep>> &p_profile,
const GamePlayer &p_player) const
{
return GetSequenceForm()->GetPayoff(p_profile, p_player);
}

MixedBehaviorProfile<double> BehaviorSupportProfile::ToMixedBehaviorProfile(
const std::map<std::shared_ptr<GameSequenceRep>, double> &p_profile) const
{
return GetSequenceForm()->ToMixedBehaviorProfile(p_profile);
}

InfosetsWrapper BehaviorSupportProfile::GetInfosets() const
{
return InfosetsWrapper(GetSequenceForm()->GetInfosets());
}

ContingenciesWrapper BehaviorSupportProfile::GetContingencies() const
{
return ContingenciesWrapper(GetSequenceForm()->GetContingencies());
}

} // end namespace Gambit
21 changes: 21 additions & 0 deletions src/games/behavspt.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@

namespace Gambit {

class GameSequenceForm;
class GameSequenceRep;
class SequencesWrapper;
class PlayerSequencesWrapper;
class InfosetsWrapper;
class ContingenciesWrapper;

/// This class represents a subset of the actions in an extensive game.
/// It is enforced that each player has at least one action at each
/// information set; thus, the actions in a support can be viewed as
Expand Down Expand Up @@ -139,6 +146,20 @@ class BehaviorSupportProfile {
/// Returns a copy of the support with dominated actions eliminated
BehaviorSupportProfile Undominated(bool p_strict) const;
//@}

mutable std::shared_ptr<GameSequenceForm> m_sequenceForm;
std::shared_ptr<GameSequenceForm> GetSequenceForm() const;
SequencesWrapper GetSequences() const;
PlayerSequencesWrapper GetSequences(GamePlayer &p_player) const;
int GetConstraintEntry(const GameInfoset &p_infoset, const GameAction &p_action) const;
const Rational &
GetPayoff(const std::map<GamePlayer, std::shared_ptr<GameSequenceRep>> &p_profile,
const GamePlayer &p_player) const;
GameRep::Players GetPlayers() const { return GetGame()->GetPlayers(); }
MixedBehaviorProfile<double>
ToMixedBehaviorProfile(const std::map<std::shared_ptr<GameSequenceRep>, double> &) const;
InfosetsWrapper GetInfosets() const;
ContingenciesWrapper GetContingencies() const;
};

} // end namespace Gambit
Expand Down
File renamed without changes.
57 changes: 56 additions & 1 deletion src/solvers/enumpoly/gameseq.h → src/games/gameseq.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

namespace Gambit {

struct GameSequenceRep {
class GameSequenceRep {
public:
GamePlayer player;
GameAction action;
Expand Down Expand Up @@ -293,6 +293,61 @@ class GameSequenceForm {
ToMixedBehaviorProfile(const std::map<GameSequence, double> &) const;
};

class SequencesWrapper {
public:
explicit SequencesWrapper(const GameSequenceForm::Sequences &sequences) : m_sequences(sequences)
{
}

auto begin() const { return m_sequences.begin(); }
auto end() const { return m_sequences.end(); }

std::size_t size() const { return m_sequences.size(); }

private:
GameSequenceForm::Sequences m_sequences;
};

class PlayerSequencesWrapper {
public:
explicit PlayerSequencesWrapper(const GameSequenceForm::PlayerSequences &sequences)
: m_sequences(sequences)
{
}

auto begin() const { return m_sequences.begin(); }
auto end() const { return m_sequences.end(); }

std::size_t size() const { return m_sequences.size(); }

private:
GameSequenceForm::PlayerSequences m_sequences;
};

class InfosetsWrapper {
public:
explicit InfosetsWrapper(const GameSequenceForm::Infosets &infosets) : m_infosets(infosets) {}

std::size_t size() const { return m_infosets.size(); }

private:
GameSequenceForm::Infosets m_infosets;
};

class ContingenciesWrapper {
public:
explicit ContingenciesWrapper(const GameSequenceForm::Contingencies &contingencies)
: m_contingencies(contingencies)
{
}

auto begin() { return m_contingencies.begin(); }
auto end() { return m_contingencies.end(); }

private:
GameSequenceForm::Contingencies m_contingencies;
};

} // end namespace Gambit

#endif // GAMESEQ_H
File renamed without changes.
38 changes: 19 additions & 19 deletions src/solvers/enumpoly/efgpoly.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include "enumpoly.h"
#include "solvers/nashsupport/nashsupport.h"
#include "gameseq.h"
#include "games/gameseq.h"
#include "polysystem.h"
#include "polysolver.h"
#include "behavextend.h"
Expand All @@ -48,7 +48,7 @@ namespace {

class ProblemData {
public:
GameSequenceForm sfg;
BehaviorSupportProfile m_support;
std::shared_ptr<VariableSpace> space;
std::map<GameSequence, int> var;
std::map<GameSequence, Polynomial<double>> variables;
Expand All @@ -62,36 +62,36 @@ Polynomial<double> BuildSequenceVariable(ProblemData &p_data, const GameSequence
if (!p_sequence->action) {
return {p_data.space, 1};
}
if (p_sequence->action != p_data.sfg.GetSupport().GetActions(p_sequence->GetInfoset()).back()) {
if (p_sequence->action != p_data.m_support.GetActions(p_sequence->GetInfoset()).back()) {
return {p_data.space, var.at(p_sequence), 1};
}

Polynomial<double> equation(p_data.space);
for (auto seq : p_data.sfg.GetSequences(p_sequence->player)) {
for (auto seq : p_data.m_support.GetSequences(p_sequence->player)) {
if (seq == p_sequence) {
continue;
}
if (const int constraint_coef =
p_data.sfg.GetConstraintEntry(p_sequence->GetInfoset(), seq->action)) {
p_data.m_support.GetConstraintEntry(p_sequence->GetInfoset(), seq->action)) {
equation += BuildSequenceVariable(p_data, seq, var) * double(constraint_coef);
}
}
return equation;
}

ProblemData::ProblemData(const BehaviorSupportProfile &p_support)
: sfg(p_support),
space(std::make_shared<VariableSpace>(sfg.GetSequences().size() - sfg.GetInfosets().size() -
sfg.GetPlayers().size()))
: m_support(p_support), space(std::make_shared<VariableSpace>(m_support.GetSequences().size() -
m_support.GetInfosets().size() -
m_support.GetPlayers().size()))
{
for (auto sequence : sfg.GetSequences()) {
for (auto sequence : m_support.GetSequences()) {
if (sequence->action &&
(sequence->action != p_support.GetActions(sequence->GetInfoset()).back())) {
var[sequence] = var.size() + 1;
}
}

for (auto sequence : sfg.GetSequences()) {
for (auto sequence : m_support.GetSequences()) {
variables.emplace(sequence, BuildSequenceVariable(*this, sequence, var));
}
}
Expand All @@ -100,11 +100,11 @@ Polynomial<double> GetPayoff(ProblemData &p_data, const GamePlayer &p_player)
{
Polynomial<double> equation(p_data.space);

for (auto profile : p_data.sfg.GetContingencies()) {
auto pay = p_data.sfg.GetPayoff(profile, p_player);
for (auto profile : p_data.m_support.GetContingencies()) {
auto pay = p_data.m_support.GetPayoff(profile, p_player);
if (pay != Rational(0)) {
Polynomial<double> term(p_data.space, double(pay));
for (auto player : p_data.sfg.GetPlayers()) {
for (auto player : p_data.m_support.GetPlayers()) {
term *= p_data.variables.at(profile[player]);
}
equation += term;
Expand All @@ -115,9 +115,9 @@ Polynomial<double> GetPayoff(ProblemData &p_data, const GamePlayer &p_player)

void IndifferenceEquations(ProblemData &p_data, PolynomialSystem<double> &p_equations)
{
for (auto player : p_data.sfg.GetPlayers()) {
for (auto player : p_data.m_support.GetPlayers()) {
const Polynomial<double> payoff = GetPayoff(p_data, player);
for (auto sequence : p_data.sfg.GetSequences(player)) {
for (auto sequence : p_data.m_support.GetSequences(player)) {
try {
p_equations.push_back(payoff.PartialDerivative(p_data.var.at(sequence)));
}
Expand All @@ -131,11 +131,11 @@ void IndifferenceEquations(ProblemData &p_data, PolynomialSystem<double> &p_equa

void LastActionProbPositiveInequalities(ProblemData &p_data, PolynomialSystem<double> &p_equations)
{
for (auto sequence : p_data.sfg.GetSequences()) {
for (auto sequence : p_data.m_support.GetSequences()) {
if (!sequence->action) {
continue;
}
const auto &actions = p_data.sfg.GetSupport().GetActions(sequence->action->GetInfoset());
const auto &actions = p_data.m_support.GetActions(sequence->action->GetInfoset());
if (actions.size() > 1 && sequence->action == actions.back()) {
p_equations.push_back(p_data.variables.at(sequence));
}
Expand All @@ -145,7 +145,7 @@ void LastActionProbPositiveInequalities(ProblemData &p_data, PolynomialSystem<do
std::map<GameSequence, double> ToSequenceProbs(const ProblemData &p_data, const Vector<double> &v)
{
std::map<GameSequence, double> x;
for (auto sequence : p_data.sfg.GetSequences()) {
for (auto sequence : p_data.m_support.GetSequences()) {
x[sequence] = p_data.variables.at(sequence).Evaluate(v);
}
return x;
Expand Down Expand Up @@ -181,7 +181,7 @@ std::list<MixedBehaviorProfile<double>> SolveSupport(const BehaviorSupportProfil
std::list<MixedBehaviorProfile<double>> solutions;
for (auto root : roots) {
const MixedBehaviorProfile<double> sol(
data.sfg.ToMixedBehaviorProfile(ToSequenceProbs(data, root)));
data.m_support.ToMixedBehaviorProfile(ToSequenceProbs(data, root)));
if (ExtendsToNash(sol, BehaviorSupportProfile(sol.GetGame()),
BehaviorSupportProfile(sol.GetGame()))) {
solutions.push_back(sol);
Expand Down
Loading