@@ -66,6 +66,7 @@ size_t BehaviorSupportProfile::BehaviorProfileLength() const
6666
6767void BehaviorSupportProfile::AddAction (const GameAction &p_action)
6868{
69+ m_reachableInfosets = nullptr ;
6970 auto &support = m_actions.at (p_action->GetInfoset ());
7071 auto pos = std::find_if (support.begin (), support.end (), [p_action](const GameAction &a) {
7172 return a->GetNumber () >= p_action->GetNumber ();
@@ -81,6 +82,7 @@ void BehaviorSupportProfile::AddAction(const GameAction &p_action)
8182
8283bool BehaviorSupportProfile::RemoveAction (const GameAction &p_action)
8384{
85+ m_reachableInfosets = nullptr ;
8486 auto &support = m_actions.at (p_action->GetInfoset ());
8587 auto pos = std::find (support.begin (), support.end (), p_action);
8688 if (pos != support.end ()) {
@@ -272,14 +274,12 @@ std::shared_ptr<GameSequenceForm> BehaviorSupportProfile::GetSequenceForm() cons
272274 return m_sequenceForm;
273275}
274276
275- SequencesWrapper BehaviorSupportProfile::GetSequences () const
276- {
277- return SequencesWrapper (GetSequenceForm ()->GetSequences ());
278- }
277+ BehaviorSupportProfile::Sequences BehaviorSupportProfile::GetSequences () const { return {this }; }
279278
280- PlayerSequencesWrapper BehaviorSupportProfile::GetSequences (GamePlayer &p_player) const
279+ BehaviorSupportProfile::PlayerSequences
280+ BehaviorSupportProfile::GetSequences (GamePlayer &p_player) const
281281{
282- return PlayerSequencesWrapper ( GetSequenceForm ()-> GetSequences ( p_player)) ;
282+ return { this , p_player} ;
283283}
284284
285285int BehaviorSupportProfile::GetConstraintEntry (const GameInfoset &p_infoset,
@@ -288,27 +288,190 @@ int BehaviorSupportProfile::GetConstraintEntry(const GameInfoset &p_infoset,
288288 return GetSequenceForm ()->GetConstraintEntry (p_infoset, p_action);
289289}
290290
291- const Rational &BehaviorSupportProfile::GetPayoff (
292- const std::map<GamePlayer, std::shared_ptr<GameSequenceRep> > &p_profile,
293- const GamePlayer &p_player) const
291+ const Rational &
292+ BehaviorSupportProfile::GetPayoff ( const std::map<GamePlayer, GameSequence > &p_profile,
293+ const GamePlayer &p_player) const
294294{
295295 return GetSequenceForm ()->GetPayoff (p_profile, p_player);
296296}
297297
298- MixedBehaviorProfile<double > BehaviorSupportProfile::ToMixedBehaviorProfile (
299- const std::map<std::shared_ptr<GameSequenceRep>, double > &p_profile) const
298+ BehaviorSupportProfile::SequenceContingencies
299+ BehaviorSupportProfile::GetSequenceContingencies () const
300+ {
301+ return {this };
302+ }
303+
304+ MixedBehaviorProfile<double >
305+ BehaviorSupportProfile::ToMixedBehaviorProfile (const std::map<GameSequence, double > &x) const
300306{
301- return GetSequenceForm ()->ToMixedBehaviorProfile (p_profile);
307+ MixedBehaviorProfile<double > b (*this );
308+ for (auto sequence : GetSequences ()) {
309+ if (sequence->action == nullptr ) {
310+ continue ;
311+ }
312+ const double parent_prob = x.at (sequence->parent .lock ());
313+ if (parent_prob > 0 ) {
314+ b[sequence->action ] = x.at (sequence) / parent_prob;
315+ }
316+ else {
317+ b[sequence->action ] = 0 ;
318+ }
319+ }
320+ return b;
302321}
303322
304- InfosetsWrapper BehaviorSupportProfile::GetInfosets () const
323+ size_t BehaviorSupportProfile::Sequences::size () const
305324{
306- return InfosetsWrapper (GetSequenceForm ()->GetInfosets ());
325+ return std::accumulate (m_support->GetSequenceForm ()->m_sequences .cbegin (),
326+ m_support->GetSequenceForm ()->m_sequences .cend (), 0 ,
327+ [](int acc, const std::pair<GamePlayer, std::vector<GameSequence>> &seq) {
328+ return acc + seq.second .size ();
329+ });
307330}
308331
309- ContingenciesWrapper BehaviorSupportProfile::GetContingencies () const
332+ BehaviorSupportProfile::Sequences::iterator BehaviorSupportProfile::Sequences::begin () const
310333{
311- return ContingenciesWrapper (GetSequenceForm ()->GetContingencies ());
334+ return {m_support->GetSequenceForm (), false };
335+ }
336+ BehaviorSupportProfile::Sequences::iterator BehaviorSupportProfile::Sequences::end () const
337+ {
338+ return {m_support->GetSequenceForm (), true };
339+ }
340+
341+ BehaviorSupportProfile::Sequences::iterator::iterator (
342+ const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
343+ : m_sfg(p_sfg)
344+ {
345+ if (p_end) {
346+ m_currentPlayer = m_sfg->m_sequences .cend ();
347+ }
348+ else {
349+ m_currentPlayer = m_sfg->m_sequences .cbegin ();
350+ m_currentSequence = m_currentPlayer->second .cbegin ();
351+ }
352+ }
353+
354+ BehaviorSupportProfile::Sequences::iterator &
355+ BehaviorSupportProfile::Sequences::iterator::operator ++()
356+ {
357+ if (m_currentPlayer == m_sfg->m_sequences .cend ()) {
358+ return *this ;
359+ }
360+ m_currentSequence++;
361+ if (m_currentSequence != m_currentPlayer->second .cend ()) {
362+ return *this ;
363+ }
364+ m_currentPlayer++;
365+ if (m_currentPlayer != m_sfg->m_sequences .cend ()) {
366+ m_currentSequence = m_currentPlayer->second .cbegin ();
367+ }
368+ return *this ;
369+ }
370+
371+ bool BehaviorSupportProfile::Sequences::iterator::operator ==(const iterator &it) const
372+ {
373+ if (m_sfg != it.m_sfg || m_currentPlayer != it.m_currentPlayer ) {
374+ return false ;
375+ }
376+ if (m_currentPlayer == m_sfg->m_sequences .end ()) {
377+ return true ;
378+ }
379+ return (m_currentSequence == it.m_currentSequence );
380+ }
381+
382+ std::vector<GameSequence>::const_iterator BehaviorSupportProfile::PlayerSequences::begin () const
383+ {
384+ return m_support->GetSequenceForm ()->m_sequences .at (m_player).begin ();
385+ }
386+
387+ std::vector<GameSequence>::const_iterator BehaviorSupportProfile::PlayerSequences::end () const
388+ {
389+ return m_support->GetSequenceForm ()->m_sequences .at (m_player).end ();
390+ }
391+
392+ size_t BehaviorSupportProfile::PlayerSequences::size () const
393+ {
394+ return m_support->GetSequenceForm ()->m_sequences .at (m_player).size ();
395+ }
396+
397+ BehaviorSupportProfile::SequenceContingencies::iterator::iterator (
398+ const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
399+ : m_sfg(p_sfg), m_end(p_end)
400+ {
401+ for (auto [player, sequences] : m_sfg->m_sequences ) {
402+ m_indices[player] = 0 ;
403+ }
404+ }
405+
406+ std::map<GamePlayer, GameSequence>
407+ BehaviorSupportProfile::SequenceContingencies::iterator::operator *() const
408+ {
409+ std::map<GamePlayer, GameSequence> ret;
410+ for (auto [player, index] : m_indices) {
411+ ret[player] = m_sfg->m_sequences .at (player)[index];
412+ }
413+ return ret;
414+ }
415+
416+ std::map<GamePlayer, GameSequence>
417+ BehaviorSupportProfile::SequenceContingencies::iterator::operator ->() const
418+ {
419+ std::map<GamePlayer, GameSequence> ret;
420+ for (auto [player, index] : m_indices) {
421+ ret[player] = m_sfg->m_sequences .at (player)[index];
422+ }
423+ return ret;
424+ }
425+
426+ BehaviorSupportProfile::SequenceContingencies::iterator &
427+ BehaviorSupportProfile::SequenceContingencies::iterator::operator ++()
428+ {
429+ for (auto [player, index] : m_indices) {
430+ if (index < m_sfg->m_sequences .at (player).size () - 1 ) {
431+ m_indices[player]++;
432+ return *this ;
433+ }
434+ m_indices[player] = 0 ;
435+ }
436+ m_end = true ;
437+ return *this ;
438+ }
439+
440+ // ========================================================================
441+ // BehaviorSupportProfile: Reachable Information Sets
442+ // ========================================================================
443+
444+ void BehaviorSupportProfile::FindReachableInfosets (GameNode p_node) const
445+ {
446+ if (!p_node->IsTerminal ()) {
447+ auto infoset = p_node->GetInfoset ();
448+ (*m_reachableInfosets)[infoset] = true ;
449+ if (p_node->GetPlayer ()->IsChance ()) {
450+ for (auto action : infoset->GetActions ()) {
451+ FindReachableInfosets (p_node->GetChild (action));
452+ }
453+ }
454+ else {
455+ for (auto action : GetActions (infoset)) {
456+ FindReachableInfosets (p_node->GetChild (action));
457+ }
458+ }
459+ }
460+ }
461+
462+ std::shared_ptr<std::map<GameInfoset, bool >> BehaviorSupportProfile::GetReachableInfosets () const
463+ {
464+ if (!m_reachableInfosets) {
465+ m_reachableInfosets = std::make_shared<std::map<GameInfoset, bool >>();
466+ for (size_t pl = 0 ; pl <= GetGame ()->NumPlayers (); pl++) {
467+ const GamePlayer player = (pl == 0 ) ? GetGame ()->GetChance () : GetGame ()->GetPlayer (pl);
468+ for (const auto &infoset : player->GetInfosets ()) {
469+ (*m_reachableInfosets)[infoset] = false ;
470+ }
471+ }
472+ FindReachableInfosets (GetGame ()->GetRoot ());
473+ }
474+ return m_reachableInfosets;
312475}
313476
314477} // end namespace Gambit
0 commit comments