📄 efstrat.cc
字号:
//// $Source: /home/gambit/CVS/gambit/sources/game/efstrat.cc,v $// $Date: 2002/08/26 05:50:07 $// $Revision: 1.5 $//// DESCRIPTION:// Implementation of supports for extensive forms//// This file is part of Gambit// Copyright (c) 2002, The Gambit Project//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//#include "efg.h"#include "efplayer.h"#include "efstrat.h"#include "base/glist.imp"class EFActionArray { friend class EFActionSet;protected: gBlock<Action *> acts;public: EFActionArray ( const gArray <Action *> &a); EFActionArray ( const EFActionArray &a); virtual ~EFActionArray(); EFActionArray &operator=( const EFActionArray &a); bool operator==( const EFActionArray &a) const; inline const Action *operator[](const int &i) const { return acts[i]; } // Information inline const int Length() const { return acts.Length(); }};//----------------------------------------------------// EFActionArray: Constructors, Destructor, operators// ---------------------------------------------------EFActionArray::EFActionArray(const gArray<Action *> &a) : acts(a.Length()){ for (int i = 1; i <= acts.Length(); i++) acts[i] = a[i]; }EFActionArray::EFActionArray(const EFActionArray &a) : acts(a.acts){ }EFActionArray::~EFActionArray (){ }EFActionArray &EFActionArray::operator=( const EFActionArray &a){ acts = a.acts; return *this;}#ifdef __BORLANDC__bool operator==(const gArray<Action *> &a, const gArray<Action *> &b){ if (a.First() != b.First() || a.Last() != b.Last()) { return false; } for (int i = a.First(); i <= a.Last(); i++) { if (a[i] != b[i]) return false; } return true;}#endifbool EFActionArray::operator==(const EFActionArray &a) const{ return (acts == a.acts);}class EFActionSet{protected: EFPlayer *efp; gArray < EFActionArray *> infosets;public: //---------------------------------------- // Constructors, Destructor, operators //----------------------------------------// EFActionSet(); EFActionSet(const EFActionSet &); EFActionSet(EFPlayer &); virtual ~EFActionSet(); EFActionSet &operator=(const EFActionSet &); bool operator==(const EFActionSet &s) const; //-------------------- // Member Functions //-------------------- // Append an action to an infoset; void AddAction(int iset, Action *); // Insert an action in a particular place in an infoset; void AddAction(int iset, Action *, int index); // Remove an action at int i, returns the removed action pointer const Action *RemoveAction(int iset, int i); // Remove an action from an infoset . // Returns true if the action was successfully removed, false otherwise. bool RemoveAction(int iset, Action *); // Get a garray of the actions in an Infoset const gArray<Action *> &ActionList(int iset) const { return infosets[iset]->acts; } // Get the EFActionArray of an iset const EFActionArray *ActionArray(int iset) const { return infosets[iset]; } // Get the EFActionArray of an Infoset const EFActionArray *ActionArray(const Infoset *i) const { return infosets[i->GetNumber()]; } // Get an Action const Action *GetAction(int iset, int index); // returns the index of the action if it is in the ActionSet int Find(const Action *) const; int Find(int, Action *) const; // Number of Actions in a particular infoset int NumActions(int iset) const; // return the EFPlayer of the EFActionSet EFPlayer &GetPlayer(void) const; // checks for a valid EFActionSet bool HasActiveActionsAtAllInfosets(void) const; bool HasActiveActionAt(const int &iset) const;};//--------------------------------------------------// EFActionSet: Constructors, Destructor, operators//--------------------------------------------------EFActionSet::EFActionSet(EFPlayer &p) : infosets(p.NumInfosets()){ efp = &p; for (int i = 1; i <= p.NumInfosets(); i++){ infosets[i] = new EFActionArray(p.Infosets()[i]->Actions()); }}EFActionSet::EFActionSet( const EFActionSet &s ): infosets(s.infosets.Length()){ efp = s.efp; for (int i = 1; i <= s.infosets.Length(); i++){ infosets[i] = new EFActionArray(*(s.infosets[i])); }}EFActionSet::~EFActionSet(){ for (int i = 1; i <= infosets.Length(); i++) delete infosets[i];}EFActionSet &EFActionSet::operator=(const EFActionSet &s){ if (this != &s && efp == s.efp) { for (int i = 1; i<= infosets.Length(); i++) { delete infosets[i]; infosets[i] = new EFActionArray(*(s.infosets[i])); } } return *this;}bool EFActionSet::operator==(const EFActionSet &s) const{ if (infosets.Length() != s.infosets.Length() || efp != s.efp) return false; int i; for (i = 1; i <= infosets.Length() && *(infosets[i]) == *(s.infosets[i]); i++); return (i > infosets.Length());}//------------------------------------------// EFActionSet: Member functions //------------------------------------------// Append an action to a particular infoset;void EFActionSet::AddAction(int iset, Action *s){ if (infosets[iset]->acts.Find(s)) return; if (infosets[iset]->acts.Length() == 0) { infosets[iset]->acts.Append(s); } else { int index = 1; while (index <= infosets[iset]->acts.Length() && infosets[iset]->acts[index]->GetNumber() < s->GetNumber()) index++; infosets[iset]->acts.Insert(s,index); }}// Insert an action to a particular infoset at a particular place;void EFActionSet::AddAction(int iset, Action *s, int index){ if (!infosets[iset]->acts.Find(s)) infosets[iset]->acts.Insert(s,index); }// Remove an action from infoset iset at int i, // returns the removed Infoset pointerconst Action* EFActionSet::RemoveAction(int iset, int i) { return (infosets[iset]->acts.Remove(i)); }// Removes an action from infoset iset . Returns true if the //Action was successfully removed, false otherwise.bool EFActionSet::RemoveAction(int iset, Action *s ){ int t = infosets[iset]->acts.Find(s); if (t>0) infosets[iset]->acts.Remove(t); return (t>0); } // Get an actionconst Action *EFActionSet::GetAction(int iset, int index){ return (infosets[iset]->acts)[index];}// Number of Actions in a particular infosetint EFActionSet::NumActions(int iset) const{ return (infosets[iset]->acts.Length());}// Return the EFPlayer of this EFActionSetEFPlayer &EFActionSet::GetPlayer(void) const{ return (*efp);}int EFActionSet::Find(const Action *a) const{ return (infosets[a->BelongsTo()->GetNumber()]->acts.Find((Action *)a));}int EFActionSet::Find(int p_infoset, Action *a) const{ return (infosets[p_infoset]->acts.Find(a));}// checks for a valid EFActionSetbool EFActionSet::HasActiveActionsAtAllInfosets(void) const{ if (infosets.Length() != efp->NumInfosets()) return false; for (int i = 1; i <= infosets.Length(); i++) if (infosets[i]->acts.Length() == 0) return false; return true;}// checks for a valid EFActionSetbool EFActionSet::HasActiveActionAt(const int &iset) const{ if (iset > efp->NumInfosets()) return false; if (infosets[iset]->acts.Length() == 0) return false; return true;}//--------------------------------------------------// EFSupport: Constructors, Destructors, Operators//--------------------------------------------------EFSupport::EFSupport(const efgGame &p_efg) : m_efg((efgGame *) &p_efg), m_players(p_efg.NumPlayers()){ for (int pl = 1; pl <= m_players.Length(); pl++) m_players[pl] = new EFActionSet(*(p_efg.Players()[pl]));}EFSupport::EFSupport(const EFSupport &p_support) : m_name(p_support.m_name), m_efg(p_support.m_efg), m_players(p_support.m_players.Length()){ for (int pl = 1; pl <= m_players.Length(); pl++) m_players[pl] = new EFActionSet(*(p_support.m_players[pl]));}EFSupport::~EFSupport(){ for (int pl = 1; pl <= m_players.Length(); pl++) delete m_players[pl];}EFSupport &EFSupport::operator=(const EFSupport &p_support){ if (this != &p_support && m_efg == p_support.m_efg) { m_name = p_support.m_name; for (int pl = 1; pl <= m_players.Length(); pl++) { delete m_players[pl]; m_players[pl] = new EFActionSet(*(p_support.m_players[pl])); } } return *this;}bool EFSupport::operator==(const EFSupport &p_support) const{ if (m_players.Length() != p_support.m_players.Length()) return false; int pl; for (pl = 1; (pl <= m_players.Length() && *(m_players[pl]) == *(p_support.m_players[pl])); pl++); return (pl > m_players.Length());}bool EFSupport::operator!=(const EFSupport &p_support) const{ return !(*this == p_support);}//-----------------------------// EFSupport: Member Functions //-----------------------------int EFSupport::NumActions(int pl, int iset) const{ return m_players[pl]->NumActions(iset);}int EFSupport::NumActions(const Infoset *i) const{ if (i->GetPlayer()->IsChance()) return i->Actions().Length(); else return m_players[i->GetPlayer()->GetNumber()]->NumActions(i->GetNumber());}const gArray<Action *> &EFSupport::Actions(int pl, int iset) const{ return m_players[pl]->ActionList(iset);}const gArray<Action *> &EFSupport::Actions(const Infoset *i) const{ if (i->GetPlayer()->IsChance()) return i->Actions(); else return m_players[i->GetPlayer()->GetNumber()]->ActionList(i->GetNumber());}gList<Action *> EFSupport::ListOfActions(const Infoset *i) const{ gArray<Action *> actions = Actions(i); gList<Action *> answer; for (int i = 1; i <= actions.Length(); i++) answer += actions[i]; return answer;}int EFSupport::Find(const Action *a) const{ if (a->BelongsTo()->Game() != m_efg) assert(0); int pl = a->BelongsTo()->GetPlayer()->GetNumber(); return m_players[pl]->Find(a);}int EFSupport::Find(int p_player, int p_infoset, Action *p_action) const{ return m_players[p_player]->Find(p_infoset, p_action);}bool EFSupport::ActionIsActive(Action *a) const{ //DEBUG // if (a == NULL) { gout << "Action* is null.\n"; exit(0); } if (a->BelongsTo()->Game() != m_efg) return false; int pl = a->BelongsTo()->GetPlayer()->GetNumber(); if (pl == 0) return true; // Chance int act = m_players[pl]->Find(a); if (act == 0) return false; else return true;}bool EFSupport::ActionIsActive(const int pl, const int iset, const int act) const{ return ActionIsActive(GetGame().Players()[pl]->GetInfoset(iset)->GetAction(act));}bool EFSupport::AllActionsInSupportAtInfosetAreActive(const EFSupport &S, const Infoset *infset) const{ gArray<Action *> support_actions = S.Actions(infset); for (int i = 1; i <= support_actions.Length(); i++) { if (!ActionIsActive(support_actions[i])) return false; } return true;}bool EFSupport::HasActiveActionAt(const Infoset *infoset) const{ if ( !m_players[infoset->GetPlayer()->GetNumber()]-> HasActiveActionAt(infoset->GetNumber()) ) return false; return true;}int EFSupport::NumDegreesOfFreedom(void) const{ int answer(0); gList<Infoset *> active_infosets = ReachableInfosets(GetGame().RootNode()); for (int i = 1; i <= active_infosets.Length(); i++) answer += NumActions(active_infosets[i]) - 1; return answer; }bool EFSupport::HasActiveActionsAtAllInfosets(void) const{ if (m_players.Length() != m_efg->NumPlayers()) return false; for (int i = 1; i <= m_players.Length(); i++) if (!m_players[i]->HasActiveActionsAtAllInfosets()) return false; return true;}gPVector<int> EFSupport::NumActions(void) const{ gArray<int> foo(m_efg->NumPlayers()); int i; for (i = 1; i <= m_efg->NumPlayers(); i++) foo[i] = m_players[i]->GetPlayer().NumInfosets(); gPVector<int> bar(foo); for (i = 1; i <= m_efg->NumPlayers(); i++) for (int j = 1; j <= m_players[i]->GetPlayer().NumInfosets(); j++) bar(i, j) = NumActions(i,j); return bar;} bool EFSupport::RemoveAction(const Action *s){ Infoset *infoset = s->BelongsTo(); EFPlayer *player = infoset->GetPlayer(); return m_players[player->GetNumber()]->RemoveAction(infoset->GetNumber(), (Action *)s);}void EFSupport::AddAction(const Action *s){ Infoset *infoset = s->BelongsTo(); EFPlayer *player = infoset->GetPlayer(); m_players[player->GetNumber()]->AddAction(infoset->GetNumber(), (Action *)s);}int EFSupport::NumSequences(int j) const{ if (j < m_efg->Players().First() || j > m_efg->Players().Last()) return 1; gList<Infoset *> isets = ReachableInfosets(m_efg->Players()[j]); int num = 1; for(int i = 1; i <= isets.Length(); i++) num+=NumActions(isets[i]); return num;}int EFSupport::TotalNumSequences(void) const{ int total = 0; for (int i = 1 ; i <= m_efg->NumPlayers(); i++) total += NumSequences(i); return total;}gList<Node *> EFSupport::ReachableNonterminalNodes(const Node *n) const{ gList<Node *> answer; if (n->IsNonterminal()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -