Skip to content

Commit

Permalink
Refactor out iteration from contingencies concept
Browse files Browse the repository at this point in the history
  • Loading branch information
tturocy committed Nov 7, 2024
1 parent 373b652 commit b25072b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 38 deletions.
41 changes: 28 additions & 13 deletions src/games/behavpure.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,39 +114,54 @@ MixedBehaviorProfile<Rational> PureBehaviorProfile::ToMixedBehaviorProfile() con
//========================================================================

BehaviorContingencies::BehaviorContingencies(const BehaviorSupportProfile &p_support,
const std::list<GameAction> &p_frozen)
: m_atEnd(false), m_support(p_support), m_profile(p_support.GetGame()), m_frozen(p_frozen)
const std::vector<GameAction> &p_frozen)
: m_support(p_support), m_frozen(p_frozen)
{
for (auto player : m_support.GetGame()->GetPlayers()) {
for (auto infoset : player->GetInfosets()) {
m_currentBehav[infoset] = 1;
m_profile.SetAction(infoset->GetActions().front());
if (p_support.IsReachable(infoset)) {
m_activeInfosets.push_back(infoset);
}
}
}

for (auto action : m_frozen) {
m_currentBehav[action->GetInfoset()] = p_support.GetIndex(action);
m_profile.SetAction(action);
m_activeInfosets.erase(std::find_if(
m_activeInfosets.begin(), m_activeInfosets.end(),
[action](const GameInfoset &infoset) { return infoset == action->GetInfoset(); }));
}
}

void BehaviorContingencies::operator++()
BehaviorContingencies::iterator::iterator(BehaviorContingencies *p_cont, bool p_end)
: m_atEnd(p_end), m_cont(p_cont), m_profile(p_cont->m_support.GetGame())
{
if (m_atEnd) {
return;
}
for (auto player : m_cont->m_support.GetGame()->GetPlayers()) {
for (auto infoset : player->GetInfosets()) {
m_currentBehav[infoset] = 1;
m_profile.SetAction(infoset->GetActions().front());
}
}
for (auto action : m_cont->m_frozen) {
m_currentBehav[action->GetInfoset()] = m_cont->m_support.GetIndex(action);
m_profile.SetAction(action);
}
}

BehaviorContingencies::iterator &BehaviorContingencies::iterator::operator++()
{
for (auto infoset = m_activeInfosets.crbegin(); infoset != m_activeInfosets.crend(); ++infoset) {
if (m_currentBehav.at(*infoset) < m_support.NumActions(*infoset)) {
m_profile.SetAction(m_support.GetActions(*infoset)[++m_currentBehav[*infoset]]);
return;
for (auto infoset = m_cont->m_activeInfosets.crbegin();
infoset != m_cont->m_activeInfosets.crend(); ++infoset) {
if (m_currentBehav.at(*infoset) < m_cont->m_support.NumActions(*infoset)) {
m_profile.SetAction(m_cont->m_support.GetActions(*infoset)[++m_currentBehav[*infoset]]);
return *this;
}
m_currentBehav[*infoset] = 1;
m_profile.SetAction(m_support.GetActions(*infoset).front());
m_profile.SetAction(m_cont->m_support.GetActions(*infoset).front());
}
m_atEnd = true;
return *this;
}

} // end namespace Gambit
57 changes: 39 additions & 18 deletions src/games/behavpure.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class PureBehaviorProfile {
//@{
/// Construct a new behavior profile on the specified game
explicit PureBehaviorProfile(Game);
//@}

bool operator==(const PureBehaviorProfile &p_other) const
{
return m_profile == p_other.m_profile;
}

/// @name Data access and manipulation
//@{
Expand Down Expand Up @@ -81,31 +87,46 @@ template <> inline std::string PureBehaviorProfile::GetPayoff(const GamePlayer &

class BehaviorContingencies {
private:
bool m_atEnd;
BehaviorSupportProfile m_support;
std::map<GameInfoset, int> m_currentBehav;
PureBehaviorProfile m_profile;
std::list<GameAction> m_frozen;
std::vector<GameAction> m_frozen;
std::list<GameInfoset> m_activeInfosets;

public:
class iterator {
private:
BehaviorContingencies *m_cont;
bool m_atEnd;
std::map<GameInfoset, int> m_currentBehav;
PureBehaviorProfile m_profile;

public:
iterator(BehaviorContingencies *, bool p_end);

iterator &operator++();

bool operator==(const iterator &p_other) const
{
if (m_atEnd && p_other.m_atEnd && m_cont == p_other.m_cont) {
return true;
}
if (m_atEnd != p_other.m_atEnd || m_cont != p_other.m_cont) {
return false;
}
return (m_profile == p_other.m_profile);
}
bool operator!=(const iterator &p_other) const { return !(*this == p_other); }

PureBehaviorProfile &operator*() { return m_profile; }
const PureBehaviorProfile &operator*() const { return m_profile; }
};
/// @name Lifecycle
//@{
/// Construct a new iterator on the support, holding the action fixed
BehaviorContingencies(const BehaviorSupportProfile &, const std::list<GameAction> & = {});
//@}

/// @name Iteration and data access
//@{
/// Advance to the next contingency (prefix version)
void operator++();
/// Advance to the next contingency (postfix version)
void operator++(int) { ++(*this); }
/// Has iterator gone past the end?
bool AtEnd() const { return m_atEnd; }
/// Get the current behavior profile
const PureBehaviorProfile &operator*() const { return m_profile; }
/// Construct a new iterator on the support, holding the listed actions fixed
explicit BehaviorContingencies(const BehaviorSupportProfile &,
const std::vector<GameAction> &p_frozen = {});
//@}
iterator begin() { return {this, false}; }
iterator end() { return {this, true}; }
};

} // end namespace Gambit
Expand Down
6 changes: 3 additions & 3 deletions src/games/behavspt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,9 @@ bool BehaviorSupportProfile::Dominates(const GameAction &a, const GameAction &b,
bool equal = true;

if (!p_conditional) {
for (BehaviorContingencies iter(*this, {a}); !iter.AtEnd(); iter++) {
auto ap = (*iter).GetPayoff<Rational>(a);
auto bp = (*iter).GetPayoff<Rational>(b);
for (auto iter : BehaviorContingencies(*this, {a})) {
auto ap = iter.GetPayoff<Rational>(a);
auto bp = iter.GetPayoff<Rational>(b);

if (p_strict) {
if (ap <= bp) {
Expand Down
7 changes: 3 additions & 4 deletions src/solvers/enumpure/enumpure.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,9 @@ inline List<MixedBehaviorProfile<Rational>> EnumPureAgentSolver::Solve(const Gam
{
List<MixedBehaviorProfile<Rational>> solutions;
BehaviorSupportProfile support(p_game);
for (auto citer = BehaviorContingencies(BehaviorSupportProfile(p_game)); !citer.AtEnd();
citer++) {
if ((*citer).IsAgentNash()) {
MixedBehaviorProfile<Rational> profile = (*citer).ToMixedBehaviorProfile();
for (auto citer : BehaviorContingencies(BehaviorSupportProfile(p_game))) {
if (citer.IsAgentNash()) {
MixedBehaviorProfile<Rational> profile = citer.ToMixedBehaviorProfile();
m_onEquilibrium->Render(profile);
solutions.push_back(profile);
}
Expand Down

0 comments on commit b25072b

Please sign in to comment.