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
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,6 @@ 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 \
Expand All @@ -261,6 +259,8 @@ game_SOURCES = \
src/games/behavpure.h \
src/games/behavmixed.cc \
src/games/behavmixed.h \
src/games/seqpure.cc \
src/games/seqpure.h \
src/games/stratspt.cc \
src/games/stratspt.h \
src/games/stratpure.h \
Expand Down
1 change: 1 addition & 0 deletions src/gambit.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "games/behavspt.h"
#include "games/behavmixed.h"
#include "games/behavpure.h"
#include "games/seqpure.h"

#include "games/stratspt.h"
#include "games/stratpure.h"
Expand Down
83 changes: 38 additions & 45 deletions src/games/behavspt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
//

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

namespace Gambit {

Expand Down Expand Up @@ -66,6 +65,7 @@ size_t BehaviorSupportProfile::BehaviorProfileLength() const
void BehaviorSupportProfile::AddAction(const GameAction &p_action)
{
m_reachableInfosets = nullptr;
m_sequences = nullptr;
auto &support = m_actions.at(p_action->GetInfoset());
auto pos = std::find_if(support.begin(), support.end(), [p_action](const GameAction &a) {
return a->GetNumber() >= p_action->GetNumber();
Expand All @@ -84,6 +84,7 @@ void BehaviorSupportProfile::AddAction(const GameAction &p_action)
bool BehaviorSupportProfile::RemoveAction(const GameAction &p_action)
{
m_reachableInfosets = nullptr;
m_sequences = nullptr;
auto &support = m_actions.at(p_action->GetInfoset());
auto pos = std::find(support.begin(), support.end(), p_action);
if (pos != support.end()) {
Expand Down Expand Up @@ -147,12 +148,19 @@ void BehaviorSupportProfile::DeactivateSubtree(const GameNode &n)
// BehaviorSupportProfile: Sequence form
//========================================================================

std::shared_ptr<GameSequenceForm> BehaviorSupportProfile::GetSequenceForm() const
std::shared_ptr<BehaviorSupportProfile::SequenceMap> BehaviorSupportProfile::GetSequenceMap() const
{
if (!m_sequenceForm) {
m_sequenceForm = std::make_shared<GameSequenceForm>(*this);
if (!m_sequences) {
m_sequences = std::make_shared<SequenceMap>();
for (const auto &player : GetGame()->GetPlayers()) {
for (const auto &sequence : player->GetSequences()) {
if (!sequence->GetAction() || Contains(sequence->GetAction())) {
(*m_sequences)[player].emplace_back(sequence);
}
}
}
}
return m_sequenceForm;
return m_sequences;
}

BehaviorSupportProfile::Sequences BehaviorSupportProfile::GetSequences() const { return {this}; }
Expand All @@ -163,19 +171,6 @@ BehaviorSupportProfile::GetSequences(const GamePlayer &p_player) const
return {this, 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, GameSequence> &p_profile,
const GamePlayer &p_player) const
{
return GetSequenceForm()->GetPayoff(p_profile, p_player);
}

BehaviorSupportProfile::SequenceContingencies
BehaviorSupportProfile::GetSequenceContingencies() const
{
Expand Down Expand Up @@ -203,103 +198,101 @@ BehaviorSupportProfile::ToMixedBehaviorProfile(const std::map<GameSequence, doub

size_t BehaviorSupportProfile::Sequences::size() const
{
return std::accumulate(m_support->GetSequenceForm()->m_sequences.cbegin(),
m_support->GetSequenceForm()->m_sequences.cend(), 0,
const auto sequences = m_support->GetSequenceMap();
return std::accumulate(sequences->cbegin(), sequences->cend(), 0,
[](int acc, const std::pair<GamePlayer, std::vector<GameSequence>> &seq) {
return acc + seq.second.size();
});
}

BehaviorSupportProfile::Sequences::iterator BehaviorSupportProfile::Sequences::begin() const
{
return {m_support->GetSequenceForm(), false};
return {m_support->GetSequenceMap(), false};
}
BehaviorSupportProfile::Sequences::iterator BehaviorSupportProfile::Sequences::end() const
{
return {m_support->GetSequenceForm(), true};
return {m_support->GetSequenceMap(), true};
}

BehaviorSupportProfile::Sequences::iterator::iterator(
const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
: m_sfg(p_sfg)
const std::shared_ptr<SequenceMap> p_sequences, bool p_end)
: m_sequences(p_sequences)
{
if (p_end) {
m_currentPlayer = m_sfg->m_sequences.cend();
m_currentPlayer = m_sequences->cend();
}
else {
m_currentPlayer = m_sfg->m_sequences.cbegin();
m_currentPlayer = m_sequences->cbegin();
m_currentSequence = m_currentPlayer->second.cbegin();
}
}

BehaviorSupportProfile::Sequences::iterator &
BehaviorSupportProfile::Sequences::iterator::operator++()
{
if (m_currentPlayer == m_sfg->m_sequences.cend()) {
if (m_currentPlayer == m_sequences->cend()) {
return *this;
}
m_currentSequence++;
if (m_currentSequence != m_currentPlayer->second.cend()) {
return *this;
}
m_currentPlayer++;
if (m_currentPlayer != m_sfg->m_sequences.cend()) {
if (m_currentPlayer != m_sequences->cend()) {
m_currentSequence = m_currentPlayer->second.cbegin();
}
return *this;
}

bool BehaviorSupportProfile::Sequences::iterator::operator==(const iterator &it) const
{
if (m_sfg != it.m_sfg || m_currentPlayer != it.m_currentPlayer) {
if (m_sequences != it.m_sequences || m_currentPlayer != it.m_currentPlayer) {
return false;
}
if (m_currentPlayer == m_sfg->m_sequences.end()) {
if (m_currentPlayer == m_sequences->end()) {
return true;
}
return (m_currentSequence == it.m_currentSequence);
}

std::vector<GameSequence>::const_iterator BehaviorSupportProfile::PlayerSequences::begin() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).begin();
return m_support->GetSequenceMap()->at(m_player).begin();
}

std::vector<GameSequence>::const_iterator BehaviorSupportProfile::PlayerSequences::end() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).end();
return m_support->GetSequenceMap()->at(m_player).end();
}

size_t BehaviorSupportProfile::PlayerSequences::size() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).size();
return m_support->GetSequenceMap()->at(m_player).size();
}

BehaviorSupportProfile::SequenceContingencies::iterator::iterator(
const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
: m_sfg(p_sfg), m_end(p_end)
const Game &p_efg, const std::shared_ptr<SequenceMap> p_sequences, bool p_end)
: m_efg(p_efg), m_sequences(p_sequences), m_end(p_end)
{
for (auto [player, sequences] : m_sfg->m_sequences) {
for (auto [player, sequences] : *m_sequences) {
m_indices[player] = 0;
}
}

std::map<GamePlayer, GameSequence>
BehaviorSupportProfile::SequenceContingencies::iterator::operator*() const
PureSequenceProfile BehaviorSupportProfile::SequenceContingencies::iterator::operator*() const
{
std::map<GamePlayer, GameSequence> ret;
PureSequenceProfile ret(m_efg);
for (auto [player, index] : m_indices) {
ret[player] = m_sfg->m_sequences.at(player)[index];
ret.SetSequence(m_sequences->at(player)[index]);
}
return ret;
}

std::map<GamePlayer, GameSequence>
BehaviorSupportProfile::SequenceContingencies::iterator::operator->() const
PureSequenceProfile BehaviorSupportProfile::SequenceContingencies::iterator::operator->() const
{
std::map<GamePlayer, GameSequence> ret;
PureSequenceProfile ret(m_efg);
for (auto [player, index] : m_indices) {
ret[player] = m_sfg->m_sequences.at(player)[index];
ret.SetSequence(m_sequences->at(player)[index]);
}
return ret;
}
Expand All @@ -308,7 +301,7 @@ BehaviorSupportProfile::SequenceContingencies::iterator &
BehaviorSupportProfile::SequenceContingencies::iterator::operator++()
{
for (auto [player, index] : m_indices) {
if (index < m_sfg->m_sequences.at(player).size() - 1) {
if (index < m_sequences->at(player).size() - 1) {
m_indices[player]++;
return *this;
}
Expand Down
42 changes: 21 additions & 21 deletions src/games/behavspt.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,10 @@
#include <list>
#include <map>
#include "game.h"
#include "seqpure.h"

namespace Gambit {

class GameSequenceForm;
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 All @@ -43,9 +38,15 @@ class ContingenciesWrapper;
/// computational approaches that enumerate possible equilibrium
/// supports.
class BehaviorSupportProfile {
public:
/// The sequences of each player that are consistent with this support,
/// i.e. those whose action is in the support (or the empty sequence).
using SequenceMap = std::map<GamePlayer, std::vector<GameSequence>>;

private:
Game m_efg;
std::map<GameInfoset, std::vector<GameAction>> m_actions;
mutable std::shared_ptr<GameSequenceForm> m_sequenceForm;
mutable std::shared_ptr<SequenceMap> m_sequences;
mutable std::shared_ptr<std::map<GameInfoset, bool>> m_reachableInfosets;

std::map<GameInfoset, bool> m_infosetReachable;
Expand All @@ -54,6 +55,7 @@ class BehaviorSupportProfile {
bool HasReachableMembers(const GameInfoset &) const;
void ActivateSubtree(const GameNode &);
void DeactivateSubtree(const GameNode &);
std::shared_ptr<SequenceMap> GetSequenceMap() const;

public:
class Support {
Expand Down Expand Up @@ -156,12 +158,12 @@ class BehaviorSupportProfile {

public:
class iterator {
const std::shared_ptr<GameSequenceForm> m_sfg;
std::map<GamePlayer, std::vector<GameSequence>>::const_iterator m_currentPlayer;
const std::shared_ptr<SequenceMap> m_sequences;
SequenceMap::const_iterator m_currentPlayer;
std::vector<GameSequence>::const_iterator m_currentSequence;

public:
iterator(const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end);
iterator(const std::shared_ptr<SequenceMap> p_sequences, bool p_end);

GameSequence operator*() const { return *m_currentSequence; }
GameSequence operator->() const { return *m_currentSequence; }
Expand Down Expand Up @@ -203,38 +205,36 @@ class BehaviorSupportProfile {

class iterator {
private:
const std::shared_ptr<GameSequenceForm> m_sfg;
Game m_efg;
const std::shared_ptr<SequenceMap> m_sequences;
bool m_end{false};
std::map<GamePlayer, size_t> m_indices;

public:
using iterator_category = std::input_iterator_tag;

iterator(const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end = false);
iterator(const Game &p_efg, const std::shared_ptr<SequenceMap> p_sequences,
bool p_end = false);

std::map<GamePlayer, GameSequence> operator*() const;
PureSequenceProfile operator*() const;

std::map<GamePlayer, GameSequence> operator->() const;
PureSequenceProfile operator->() const;

iterator &operator++();

bool operator==(const iterator &it) const
{
return (m_end == it.m_end && m_sfg == it.m_sfg && m_indices == it.m_indices);
return (m_end == it.m_end && m_sequences == it.m_sequences && m_indices == it.m_indices);
}
bool operator!=(const iterator &it) const { return !(*this == it); }
};

iterator begin() { return {m_support->GetSequenceForm()}; }
iterator end() { return {m_support->GetSequenceForm(), true}; }
iterator begin() { return {m_support->GetGame(), m_support->GetSequenceMap()}; }
iterator end() { return {m_support->GetGame(), m_support->GetSequenceMap(), true}; }
};

std::shared_ptr<GameSequenceForm> GetSequenceForm() const;
Sequences GetSequences() const;
PlayerSequences GetSequences(const GamePlayer &p_player) const;
int GetConstraintEntry(const GameInfoset &p_infoset, const GameAction &p_action) const;
const Rational &GetPayoff(const std::map<GamePlayer, GameSequence> &p_profile,
const GamePlayer &p_player) const;
GameRep::Players GetPlayers() const { return GetGame()->GetPlayers(); }
MixedBehaviorProfile<double>
ToMixedBehaviorProfile(const std::map<GameSequence, double> &) const;
Expand Down
Loading
Loading