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
43 changes: 22 additions & 21 deletions src/games/game.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ MixedStrategyProfile<T> &MixedStrategyProfile<T>::operator=(const MixedStrategyP
template <class T> Vector<T> MixedStrategyProfile<T>::GetStrategy(const GamePlayer &p_player) const
{
CheckVersion();
auto strategies = m_rep->m_support.GetStrategies(p_player);
auto strategies = m_rep->GetSupport().GetStrategies(p_player);
Vector<T> probs(strategies.size());
std::transform(strategies.begin(), strategies.end(), probs.begin(),
[this](const GameStrategy &s) { return (*m_rep)[s]; });
Expand All @@ -326,12 +326,12 @@ template <class T> Vector<T> MixedStrategyProfile<T>::GetStrategy(const GamePlay
template <class T> MixedStrategyProfile<T> MixedStrategyProfile<T>::ToFullSupport() const
{
CheckVersion();
MixedStrategyProfile<T> full(m_rep->m_support.GetGame()->NewMixedStrategyProfile(T(0)));
MixedStrategyProfile<T> full(m_rep->GetSupport().GetGame()->NewMixedStrategyProfile(T(0)));

for (const auto &player : m_rep->m_support.GetGame()->GetPlayers()) {
for (const auto &player : m_rep->GetSupport().GetGame()->GetPlayers()) {
for (const auto &strategy : player->GetStrategies()) {
full[strategy] =
(m_rep->m_support.Contains(strategy)) ? (*m_rep)[strategy] : static_cast<T>(0);
(m_rep->GetSupport().Contains(strategy)) ? (*m_rep)[strategy] : static_cast<T>(0);
}
}
return full;
Expand All @@ -343,17 +343,18 @@ template <class T> MixedStrategyProfile<T> MixedStrategyProfile<T>::ToFullSuppor

template <class T> void MixedStrategyProfile<T>::ComputePayoffs() const
{
if (!m_payoffs.empty()) {
// caches (m_payoffs and m_strategyValues) are valid,
// so don't compute anything, simply return
if (m_cache.m_valid) {
return;
}
for (const auto &player : m_rep->m_support.GetPlayers()) {
m_payoffs[player] = GetPayoff(player);
for (const auto &strategy : m_rep->m_support.GetStrategies(player)) {
m_strategyValues[player][strategy] = GetPayoff(strategy);
Cache newCache;
for (const auto &player : m_rep->GetSupport().GetPlayers()) {
newCache.m_payoffs[player] = GetPayoff(player);
for (const auto &strategy : m_rep->GetSupport().GetStrategies(player)) {
newCache.m_strategyValues[player][strategy] = GetPayoff(strategy);
}
}
newCache.m_valid = true;
m_cache = std::move(newCache);
};

template <class T> T MixedStrategyProfile<T>::GetLiapValue() const
Expand All @@ -362,12 +363,11 @@ template <class T> T MixedStrategyProfile<T>::GetLiapValue() const
ComputePayoffs();

auto liapValue = static_cast<T>(0);
for (auto p : m_payoffs) {
liapValue += std::transform_reduce(
m_strategyValues.at(p.first).begin(), m_strategyValues.at(p.first).end(),
static_cast<T>(0), std::plus<T>(), [&p](const auto &v) -> T {
return sqr(std::max(v.second - p.second, static_cast<T>(0)));
});
for (const auto &p : m_cache.m_payoffs) {
const auto &values = m_cache.m_strategyValues.at(p.first);
liapValue += sum_function(values, [&](const auto &v) {
return sqr(std::max(v.second - p.second, static_cast<T>(0)));
});
}
return liapValue;
}
Expand All @@ -376,13 +376,14 @@ template <class T> T MixedStrategyProfile<T>::GetRegret(const GameStrategy &p_st
{
CheckVersion();
ComputePayoffs();

auto player = p_strategy->GetPlayer();
T best_other_payoff = maximize_function(
filter_if(player->GetStrategies(), [&](const auto &s) { return s != p_strategy; }),
[this, &player](const auto &strategy) -> T {
return m_strategyValues.at(player).at(strategy);
return m_cache.m_strategyValues.at(player).at(strategy);
});
return std::max(best_other_payoff - m_strategyValues.at(player).at(p_strategy),
return std::max(best_other_payoff - m_cache.m_strategyValues.at(player).at(p_strategy),
static_cast<T>(0));
}

Expand All @@ -392,9 +393,9 @@ template <class T> T MixedStrategyProfile<T>::GetRegret(const GamePlayer &p_play
ComputePayoffs();
auto br_payoff =
maximize_function(p_player->GetStrategies(), [this, p_player](const auto &strategy) -> T {
return m_strategyValues.at(p_player).at(strategy);
return m_cache.m_strategyValues.at(p_player).at(strategy);
});
return br_payoff - m_payoffs.at(p_player);
return br_payoff - m_cache.m_payoffs.at(p_player);
}

template <class T> T MixedStrategyProfile<T>::GetMaxRegret() const
Expand Down
31 changes: 17 additions & 14 deletions src/games/gametable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Rational TablePureStrategyProfileRep::GetPayoff(const GamePlayer &p_player) cons
Rational TablePureStrategyProfileRep::GetStrategyValue(const GameStrategy &p_strategy) const
{
const auto &player = p_strategy->GetPlayer();
GameOutcomeRep *outcome =
const GameOutcomeRep *outcome =
dynamic_cast<GameTableRep &>(*m_nfg)
.m_results[m_index - m_profile.at(player)->m_offset + p_strategy->m_offset];
if (outcome) {
Expand Down Expand Up @@ -159,17 +159,18 @@ std::unique_ptr<MixedStrategyProfileRep<T>> TableMixedStrategyProfileRep<T>::Cop
template <class T>
T TableMixedStrategyProfileRep<T>::GetPayoff(int pl, int index, int current) const
{
if (current > static_cast<int>(this->m_support.GetGame()->NumPlayers())) {
const Game game = this->m_support.GetGame();
if (current > static_cast<int>(this->GetSupport().GetGame()->NumPlayers())) {
const Game game = this->GetSupport().GetGame();
auto &g = dynamic_cast<GameTableRep &>(*game);
if (const auto outcome = g.m_results[index]) {
return outcome->GetPayoff<T>(this->m_support.GetGame()->GetPlayer(pl));
return outcome->GetPayoff<T>(this->GetSupport().GetGame()->GetPlayer(pl));
}
return static_cast<T>(0);
}

T sum = static_cast<T>(0);
for (auto s : this->m_support.GetStrategies(this->m_support.GetGame()->GetPlayer(current))) {
for (auto s :
this->GetSupport().GetStrategies(this->GetSupport().GetGame()->GetPlayer(current))) {
if ((*this)[s] != T(0)) {
sum += ((*this)[s] * GetPayoff(pl, index + s->m_offset, current + 1));
}
Expand All @@ -189,15 +190,16 @@ void TableMixedStrategyProfileRep<T>::GetPayoffDeriv(int pl, int const_pl, int c
if (cur_pl == const_pl) {
cur_pl++;
}
if (cur_pl > static_cast<int>(this->m_support.GetGame()->NumPlayers())) {
const Game game = this->m_support.GetGame();
if (cur_pl > static_cast<int>(this->GetSupport().GetGame()->NumPlayers())) {
const Game game = this->GetSupport().GetGame();
auto &g = dynamic_cast<GameTableRep &>(*game);
if (const auto outcome = g.m_results[index]) {
value += prob * outcome->GetPayoff<T>(this->m_support.GetGame()->GetPlayer(pl));
value += prob * outcome->GetPayoff<T>(this->GetSupport().GetGame()->GetPlayer(pl));
}
}
else {
for (auto s : this->m_support.GetStrategies(this->m_support.GetGame()->GetPlayer(cur_pl))) {
for (auto s :
this->GetSupport().GetStrategies(this->GetSupport().GetGame()->GetPlayer(cur_pl))) {
if ((*this)[s] > T(0)) {
GetPayoffDeriv(pl, const_pl, cur_pl + 1, index + s->m_offset, prob * (*this)[s], value);
}
Expand All @@ -221,15 +223,16 @@ void TableMixedStrategyProfileRep<T>::GetPayoffDeriv(int pl, int const_pl1, int
while (cur_pl == const_pl1 || cur_pl == const_pl2) {
cur_pl++;
}
if (cur_pl > static_cast<int>(this->m_support.GetGame()->NumPlayers())) {
const Game game = this->m_support.GetGame();
if (cur_pl > static_cast<int>(this->GetSupport().GetGame()->NumPlayers())) {
const Game game = this->GetSupport().GetGame();
auto &g = dynamic_cast<GameTableRep &>(*game);
if (const auto outcome = g.m_results[index]) {
value += prob * outcome->GetPayoff<T>(this->m_support.GetGame()->GetPlayer(pl));
value += prob * outcome->GetPayoff<T>(this->GetSupport().GetGame()->GetPlayer(pl));
}
}
else {
for (auto s : this->m_support.GetStrategies(this->m_support.GetGame()->GetPlayer(cur_pl))) {
for (auto s :
this->GetSupport().GetStrategies(this->GetSupport().GetGame()->GetPlayer(cur_pl))) {
if ((*this)[s] > static_cast<T>(0)) {
GetPayoffDeriv(pl, const_pl1, const_pl2, cur_pl + 1, index + s->m_offset,
prob * (*this)[s], value);
Expand Down Expand Up @@ -524,7 +527,7 @@ void GameTableRep::RebuildTable()
IndexStrategies();
}

void GameTableRep::IndexStrategies()
void GameTableRep::IndexStrategies() const
{
long offset = 1L;
for (auto player : m_players) {
Expand Down
2 changes: 1 addition & 1 deletion src/games/gametable.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class GameTableRep : public GameExplicitRep {

/// @name Private auxiliary functions
//@{
void IndexStrategies();
void IndexStrategies() const;
void RebuildTable();
//@}

Expand Down
11 changes: 5 additions & 6 deletions src/games/gametree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,20 @@ std::unique_ptr<MixedStrategyProfileRep<T>> TreeMixedStrategyProfileRep<T>::Copy

template <class T> void TreeMixedStrategyProfileRep<T>::MakeBehavior() const
{
if (mixed_behav_profile_sptr.get() == nullptr) {
mixed_behav_profile_sptr =
std::make_shared<MixedBehaviorProfile<T>>(MixedStrategyProfile<T>(Copy()));
if (m_mixedBehavior == nullptr) {
m_mixedBehavior = std::make_shared<MixedBehaviorProfile<T>>(MixedStrategyProfile<T>(Copy()));
}
}

template <class T> void TreeMixedStrategyProfileRep<T>::InvalidateCache() const
template <class T> void TreeMixedStrategyProfileRep<T>::OnProfileChanged() const
{
mixed_behav_profile_sptr = nullptr;
m_mixedBehavior = nullptr;
}

template <class T> T TreeMixedStrategyProfileRep<T>::GetPayoff(int pl) const
{
MakeBehavior();
return mixed_behav_profile_sptr->GetPayoff(mixed_behav_profile_sptr->GetGame()->GetPlayer(pl));
return m_mixedBehavior->GetPayoff(m_mixedBehavior->GetGame()->GetPlayer(pl));
}

template <class T>
Expand Down
4 changes: 2 additions & 2 deletions src/games/gametree.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@ template <class T> class TreeMixedStrategyProfileRep : public MixedStrategyProfi
T GetPayoffDeriv(int pl, const GameStrategy &, const GameStrategy &) const override;

private:
mutable std::shared_ptr<MixedBehaviorProfile<T>> mixed_behav_profile_sptr;
mutable std::shared_ptr<MixedBehaviorProfile<T>> m_mixedBehavior;

void MakeBehavior() const;
void InvalidateCache() const override;
void OnProfileChanged() const override;
};

} // namespace Gambit
Expand Down
Loading