@@ -251,7 +251,7 @@ MixedStrategyProfileRep<T>::MixedStrategyProfileRep(const StrategySupportProfile
251251template <class T > void MixedStrategyProfileRep<T>::SetCentroid()
252252{
253253 for (auto player : m_support.GetGame ()->GetPlayers ()) {
254- T center = T (1 ) / T (m_support.GetStrategies (player).size ());
254+ T center = static_cast <T> (1 ) / static_cast <T> (m_support.GetStrategies (player).size ());
255255 for (auto strategy : m_support.GetStrategies (player)) {
256256 (*this )[strategy] = center;
257257 }
@@ -277,39 +277,6 @@ std::unique_ptr<MixedStrategyProfileRep<T>> MixedStrategyProfileRep<T>::Normaliz
277277 return norm;
278278}
279279
280- template <class T > T MixedStrategyProfileRep<T>::GetRegret(const GameStrategy &p_strategy) const
281- {
282- const GamePlayer player = p_strategy->GetPlayer ();
283- T payoff = GetPayoffDeriv (player->GetNumber (), p_strategy);
284- T brpayoff = payoff;
285- for (auto strategy : player->GetStrategies ()) {
286- if (strategy != p_strategy) {
287- brpayoff = std::max (brpayoff, GetPayoffDeriv (player->GetNumber (), strategy));
288- }
289- }
290- return brpayoff - payoff;
291- }
292-
293- template <class T > T MixedStrategyProfileRep<T>::GetRegret(const GamePlayer &p_player) const
294- {
295- auto strategies = p_player->GetStrategies ();
296- T br_payoff = std::accumulate (std::next (strategies.begin ()), strategies.end (),
297- GetPayoff (*strategies.begin ()),
298- [this ](const T &x, const GameStrategy &strategy) {
299- return std::max (x, GetPayoff (strategy));
300- });
301- return br_payoff - GetPayoff (p_player);
302- }
303-
304- template <class T > T MixedStrategyProfileRep<T>::GetMaxRegret() const
305- {
306- auto players = m_support.GetGame ()->GetPlayers ();
307- return std::accumulate (players.begin (), players.end (), T (0 ),
308- [this ](const T &x, const GamePlayer &player) {
309- return std::max (x, this ->GetRegret (player));
310- });
311- }
312-
313280// ========================================================================
314281// MixedStrategyProfile<T>: Lifecycle
315282// ========================================================================
@@ -333,8 +300,7 @@ MixedStrategyProfile<T>::MixedStrategyProfile(const MixedBehaviorProfile<T> &p_p
333300}
334301
335302template <class T >
336- MixedStrategyProfile<T> &
337- MixedStrategyProfile<T>::operator =(const MixedStrategyProfile<T> &p_profile)
303+ MixedStrategyProfile<T> &MixedStrategyProfile<T>::operator =(const MixedStrategyProfile &p_profile)
338304{
339305 if (this != &p_profile) {
340306 InvalidateCache ();
@@ -377,16 +343,15 @@ template <class T> MixedStrategyProfile<T> MixedStrategyProfile<T>::ToFullSuppor
377343
378344template <class T > void MixedStrategyProfile<T>::ComputePayoffs() const
379345{
380- if (!map_profile_payoffs .empty ()) {
381- // caches (map_profile_payoffs and map_strategy_payoffs ) are valid,
346+ if (!m_payoffs .empty ()) {
347+ // caches (m_payoffs and m_strategyValues ) are valid,
382348 // so don't compute anything, simply return
383349 return ;
384350 }
385351 for (const auto &player : m_rep->m_support .GetPlayers ()) {
386- map_profile_payoffs[player] = GetPayoff (player);
387- // values of the player's strategies
352+ m_payoffs[player] = GetPayoff (player);
388353 for (const auto &strategy : m_rep->m_support .GetStrategies (player)) {
389- map_strategy_payoffs [player][strategy] = GetPayoff (strategy);
354+ m_strategyValues [player][strategy] = GetPayoff (strategy);
390355 }
391356 }
392357};
@@ -397,14 +362,47 @@ template <class T> T MixedStrategyProfile<T>::GetLiapValue() const
397362 ComputePayoffs ();
398363
399364 auto liapValue = static_cast <T>(0 );
400- for (auto [player, payoff] : map_profile_payoffs) {
401- for (auto v : map_strategy_payoffs[player]) {
402- liapValue += sqr (std::max (v.second - payoff, static_cast <T>(0 )));
403- }
365+ for (auto p : m_payoffs) {
366+ liapValue += std::transform_reduce (
367+ m_strategyValues.at (p.first ).begin (), m_strategyValues.at (p.first ).end (),
368+ static_cast <T>(0 ), std::plus<T>(), [&p](const auto &v) -> T {
369+ return sqr (std::max (v.second - p.second , static_cast <T>(0 )));
370+ });
404371 }
405372 return liapValue;
406373}
407374
375+ template <class T > T MixedStrategyProfile<T>::GetRegret(const GameStrategy &p_strategy) const
376+ {
377+ CheckVersion ();
378+ ComputePayoffs ();
379+ auto player = p_strategy->GetPlayer ();
380+ T best_other_payoff = maximize_function (exclude_value (player->GetStrategies (), p_strategy),
381+ [this , &player](const auto &strategy) -> T {
382+ return m_strategyValues.at (player).at (strategy);
383+ });
384+ return std::max (best_other_payoff - m_strategyValues.at (player).at (p_strategy),
385+ static_cast <T>(0 ));
386+ }
387+
388+ template <class T > T MixedStrategyProfile<T>::GetRegret(const GamePlayer &p_player) const
389+ {
390+ CheckVersion ();
391+ ComputePayoffs ();
392+ auto br_payoff =
393+ maximize_function (p_player->GetStrategies (), [this , p_player](const auto &strategy) -> T {
394+ return m_strategyValues.at (p_player).at (strategy);
395+ });
396+ return br_payoff - m_payoffs.at (p_player);
397+ }
398+
399+ template <class T > T MixedStrategyProfile<T>::GetMaxRegret() const
400+ {
401+ CheckVersion ();
402+ return maximize_function (GetGame ()->GetPlayers (),
403+ [this ](const auto &player) -> T { return this ->GetRegret (player); });
404+ }
405+
408406template class MixedStrategyProfileRep <double >;
409407template class MixedStrategyProfileRep <Rational>;
410408
0 commit comments