⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 efg.cc

📁 Gambit 是一个游戏库理论软件
💻 CC
📖 第 1 页 / 共 3 页
字号:
//// $Source: /home/gambit/CVS/gambit/sources/game/efg.cc,v $// $Date: 2002/08/26 05:50:06 $// $Revision: 1.7 $//// DESCRIPTION:// Implementation of extensive form game representation//// 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 "base/base.h"#include "math/rational.h"#ifdef __GNUG__#pragma implementation "infoset.h"#pragma implementation "efplayer.h"#pragma implementation "node.h"#endif   // __GNUG__#include "efg.h"#include "efgutils.h"#include "efstrat.h"//----------------------------------------------------------------------//                 EFPlayer: Member function definitions//----------------------------------------------------------------------EFPlayer::~EFPlayer(){  while (infosets.Length())   delete infosets.Remove(1);}//----------------------------------------------------------------------//                 Action: Member function definitions//----------------------------------------------------------------------bool Action::Precedes(const Node * n) const{  while ( n != n->Game()->RootNode() ) {    if ( n->GetAction() == this )      return true;    else      n = n->GetParent();  }  return false;}//----------------------------------------------------------------------//                 Infoset: Member function definitions//----------------------------------------------------------------------bool Infoset::Precedes(const Node * n) const{  while ( n != n->Game()->RootNode() ) {    if ( n->GetInfoset() == this )      return true;    else      n = n->GetParent();  }  return false;}Infoset::Infoset(efgGame *e, int n, EFPlayer *p, int br)  : E(e), number(n), player(p), actions(br), flag(0) {  while (br)   {    actions[br] = new Action(br, "", this);    br--;   }}Infoset::~Infoset()  {  for (int i = 1; i <= actions.Length(); i++)  delete actions[i];}void Infoset::PrintActions(gOutput &f) const{   f << "{ ";  for (int i = 1; i <= actions.Length(); i++)    f << '"' << EscapeQuotes(actions[i]->name) << "\" ";  f << "}";}Action *Infoset::InsertAction(int where){  Action *action = new Action(where, "", this);  actions.Insert(action, where);  for (; where <= actions.Length(); where++)    actions[where]->number = where;  return action;}void Infoset::RemoveAction(int which){  delete actions.Remove(which);  for (; which <= actions.Length(); which++)    actions[which]->number = which;}const gList<Action *> Infoset::ListOfActions(void) const{  gList<Action *> answer;  for (int i = 1; i <= actions.Length(); i++)     answer += actions[i];  return answer;}const gList<const Node *> Infoset::ListOfMembers(void) const{  gList<const Node *> answer;  for (int i = 1; i <= members.Length(); i++)     answer += members[i];  return answer;}//------------------------------------------------------------------------//           ChanceInfoset: Member function definitions//------------------------------------------------------------------------ChanceInfoset::ChanceInfoset(efgGame *E, int n, EFPlayer *p, int br)  : Infoset(E, n, p, br), probs(br){  for (int i = 1; i <= br; probs[i++] = gRational(1, br));}Action *ChanceInfoset::InsertAction(int where){   Action *action = Infoset::InsertAction(where);  probs.Insert((gNumber) 0, where);  return action;}void ChanceInfoset::RemoveAction(int which){  Infoset::RemoveAction(which);  probs.Remove(which);}void ChanceInfoset::PrintActions(gOutput &f) const{   f << "{ ";  for (int i = 1; i <= actions.Length(); i++) {    f << '"' << EscapeQuotes(actions[i]->GetName()) << "\" ";    f << probs[i] << ' ';  }  f << "}";}//----------------------------------------------------------------------//                   Node: Member function definitions//----------------------------------------------------------------------Node::Node(efgGame *e, Node *p)  : mark(false), number(0), E(e), infoset(0), parent(p), outcome(0),    gameroot((p) ? p->gameroot : this){ }Node::~Node(){  for (int i = children.Length(); i; delete children[i--]);}int Node::NumberInInfoset(void) const{  for (int i = 1; i <= GetInfoset()->NumMembers(); i++)    if (GetInfoset()->GetMember(i) == this)      return i;  //  This could be speeded up by adding a member to Node to keep track of this  throw efgGame::Exception();}Node *Node::NextSibling(void) const  {  if (!parent)   return 0;  if (parent->children.Find((Node * const) this) == parent->children.Length())    return 0;  else    return parent->children[parent->children.Find((Node * const)this) + 1];}Node *Node::PriorSibling(void) const{   if (!parent)   return 0;  if (parent->children.Find((Node * const)this) == 1)    return 0;  else    return parent->children[parent->children.Find((Node * const)this) - 1];}Action *Node::GetAction(void) const{  if (this == Game()->RootNode()) {    return 0;  }    const gArray<Action *> &actions = GetParent()->GetInfoset()->Actions();  for (int i = 1; i <= actions.Length(); i++) {    if (this == GetParent()->GetChild(actions[i])) {      return actions[i];    }  }  return 0;}void Node::DeleteOutcome(efgOutcome *outc){  if (outc == outcome)   outcome = 0;  for (int i = 1; i <= children.Length(); i++)    children[i]->DeleteOutcome(outc);}//------------------------------------------------------------------------//       Efg: Constructors, destructor, constructive operators//------------------------------------------------------------------------#ifdef MEMCHECKint efgGame::_NumObj = 0;#endif // MEMCHECKefgGame::efgGame(void)  : sortisets(true), m_dirty(false), m_revision(0),     m_outcome_revision(-1), title("UNTITLED"),    chance(new EFPlayer(this, 0)), afg(0), lexicon(0){  root = new Node(this, 0);#ifdef MEMCHECK  _NumObj++;  gout << "--- Efg Ctor: " << _NumObj << "\n";#endif // MEMCHECK  SortInfosets();}efgGame::efgGame(const efgGame &E, Node *n /* = 0 */)  : sortisets(false), m_dirty(false), m_revision(0),     m_outcome_revision(-1), title(E.title), comment(E.comment),    players(E.players.Length()), outcomes(0, E.outcomes.Last()),    chance(new EFPlayer(this, 0)),    afg(0), lexicon(0) {  for (int i = 1; i <= players.Length(); i++)  {    (players[i] = new EFPlayer(this, i))->name = E.players[i]->name;    for (int j = 1; j <= E.players[i]->infosets.Length(); j++)   {      Infoset *s = new Infoset(this, j, players[i],			       E.players[i]->infosets[j]->actions.Length());      s->name = E.players[i]->infosets[j]->name;      for (int k = 1; k <= s->actions.Length(); k++)	s->actions[k]->name = E.players[i]->infosets[j]->actions[k]->name;      players[i]->infosets.Append(s);    }  }  for (int i = 1; i <= E.GetChance()->NumInfosets(); i++)   {    ChanceInfoset *t = (ChanceInfoset *) E.GetChance()->Infosets()[i];    ChanceInfoset *s = new ChanceInfoset(this, i, chance,					       t->NumActions());    s->name = t->GetName();    for (int act = 1; act <= s->probs.Length(); act++) {      s->probs[act] = t->probs[act];      s->actions[act]->name = t->actions[act]->name;    }    chance->infosets.Append(s);  }  for (int outc = 1; outc <= E.NumOutcomes(); outc++)  {    outcomes[outc] = new efgOutcome(this, outc);    outcomes[outc]->m_name = E.outcomes[outc]->m_name;    outcomes[outc]->m_payoffs = E.outcomes[outc]->m_payoffs;  }  root = new Node(this, 0);  CopySubtree(root, (n ? n : E.RootNode()));    if (n)   {    for (int pl = 1; pl <= players.Length(); pl++)  {      for (int i = 1; i <= players[pl]->infosets.Length(); i++)  {	if (players[pl]->infosets[i]->members.Length() == 0)	  delete players[pl]->infosets.Remove(i--);      }    }  }  sortisets = true;  SortInfosets();}#include "lexicon.h"efgGame::~efgGame(){  delete root;  delete chance;  for (int i = 1; i <= players.Length(); delete players[i++]);  for (int i = 1; i <= outcomes.Last(); delete outcomes[i++]);  if (lexicon)   delete lexicon;  lexicon = 0;}//------------------------------------------------------------------------//                  Efg: Private member functions//------------------------------------------------------------------------void efgGame::DeleteLexicon(void) const{  if (lexicon)   delete lexicon;  lexicon = 0;}Infoset *efgGame::GetInfosetByIndex(EFPlayer *p, int index) const{  for (int i = 1; i <= p->infosets.Length(); i++)    if (p->infosets[i]->number == index)   return p->infosets[i];  return 0;}efgOutcome *efgGame::GetOutcomeByIndex(int index) const{  for (int i = 1; i <= outcomes.Last(); i++) {    if (outcomes[i]->m_number == index)  {      return outcomes[i];    }  }  return 0;}void efgGame::Reindex(void){  int i;  for (i = 1; i <= players.Length(); i++)  {    EFPlayer *p = players[i];    for (int j = 1; j <= p->infosets.Length(); j++)      p->infosets[j]->number = j;  }  for (i = 1; i <= outcomes.Last(); i++)    outcomes[i]->m_number = i;}void efgGame::NumberNodes(Node *n, int &index){  n->number = index++;  for (int child = 1; child <= n->children.Length();       NumberNodes(n->children[child++], index));} void efgGame::SortInfosets(void){  if (!sortisets)  return;  int pl;  for (pl = 0; pl <= players.Length(); pl++)  {    gList<Node *> nodes;    Nodes(*this, nodes);    EFPlayer *player = (pl) ? players[pl] : chance;    int i, isets = 0;    // First, move all empty infosets to the back of the list so    // we don't "lose" them    int foo = player->infosets.Length();    i = 1;    while (i < foo)   {      if (player->infosets[i]->members.Length() == 0)  {	Infoset *bar = player->infosets[i];	player->infosets[i] = player->infosets[foo];	player->infosets[foo--] = bar;      }      else	i++;    }    // This will give empty infosets their proper number; the nonempty    // ones will be renumbered by the next loop    for (i = 1; i <= player->infosets.Length(); i++)      if (player->infosets[i]->members.Length() == 0)	player->infosets[i]->number = i;      else	player->infosets[i]->number = 0;      for (i = 1; i <= nodes.Length(); i++)  {      Node *n = nodes[i];      if (n->GetPlayer() == player && n->GetInfoset()->number == 0)  {	n->GetInfoset()->number = ++isets;	player->infosets[isets] = n->GetInfoset();      }    }    }  // Now, we sort the nodes within the infosets    gList<Node *> nodes;  Nodes(*this, nodes);  for (pl = 0; pl <= players.Length(); pl++)  {    EFPlayer *player = (pl) ? players[pl] : chance;    for (int iset = 1; iset <= player->infosets.Length(); iset++)  {      Infoset *s = player->infosets[iset];      for (int i = 1, j = 1; i <= nodes.Length(); i++)  {	if (nodes[i]->infoset == s)	  s->members[j++] = nodes[i];      }    }  }  int nodeindex = 1;  NumberNodes(root, nodeindex);}  Infoset *efgGame::CreateInfoset(int n, EFPlayer *p, int br){  Infoset *s = (p->IsChance()) ? new ChanceInfoset(this, n, p, br) :               new Infoset(this, n, p, br);  p->infosets.Append(s);  return s;}efgOutcome *efgGame::CreateOutcomeByIndex(int index){  NewOutcome(index);  return outcomes[outcomes.Last()];}void efgGame::CopySubtree(Node *n, Node *m){  n->name = m->name;  if (m->gameroot == m)    n->gameroot = n;  if (m->outcome) {    n->outcome = m->outcome;  }  if (m->infoset)   {    EFPlayer *p;    if (m->infoset->player->number)      p = players[m->infoset->player->number];    else      p = chance;    Infoset *s = p->Infosets()[m->infoset->number];    AppendNode(n, s);    for (int i = 1; i <= n->children.Length(); i++)      CopySubtree(n->children[i], m->children[i]);  }}//------------------------------------------------------------------------//               Efg: Title access and manipulation//------------------------------------------------------------------------void efgGame::SetTitle(const gText &s){  title = s;   m_revision++;  m_dirty = true;}const gText &efgGame::GetTitle(void) const{ return title; }void efgGame::SetComment(const gText &s){  comment = s;  m_revision++;  m_dirty = true;}const gText &efgGame::GetComment(void) const{ return comment; }  //------------------------------------------------------------------------//                    Efg: Writing data files//------------------------------------------------------------------------void efgGame::WriteEfgFile(gOutput &f, Node *n) const{  if (n->children.Length() == 0)   {    f << "t \"" << EscapeQuotes(n->name) << "\" ";    if (n->outcome)  {      f << n->outcome->m_number << " \"" <<	EscapeQuotes(n->outcome->m_name) << "\" ";      f << "{ ";      for (int pl = 1; pl <= NumPlayers(); pl++)  {	f << n->outcome->m_payoffs[pl];	if (pl < NumPlayers())	  f << ", ";	else	  f << " }\n";      }    }    else      f << "0\n";  }  else if (n->infoset->player->number)   {    f << "p \"" << EscapeQuotes(n->name) << "\" " <<      n->infoset->player->number << ' ';    f << n->infoset->number << " \"" <<      EscapeQuotes(n->infoset->name) << "\" ";    n->infoset->PrintActions(f);    f << " ";    if (n->outcome)  {      f << n->outcome->m_number << " \"" <<	EscapeQuotes(n->outcome->m_name) << "\" ";      f << "{ ";      for (int pl = 1; pl <= NumPlayers(); pl++)  {	f << n->outcome->m_payoffs[pl];	if (pl < NumPlayers())	  f << ", ";	else	  f << " }\n";      }    }    else      f << "0\n";  }  else   {    // chance node    f << "c \"" << n->name << "\" ";    f << n->infoset->number << " \"" <<      EscapeQuotes(n->infoset->name) << "\" ";    n->infoset->PrintActions(f);    f << " ";    if (n->outcome)  {      f << n->outcome->m_number << " \"" <<	EscapeQuotes(n->outcome->m_name) << "\" ";      f << "{ ";      for (int pl = 1; pl <= NumPlayers(); pl++)  {	f << n->outcome->m_payoffs[pl];        if (pl < NumPlayers())           f << ", ";        else          f << " }\n";      }    }    else      f << "0\n";  }  for (int i = 1; i <= n->children.Length(); i++)    WriteEfgFile(f, n->children[i]);}void efgGame::WriteEfgFile(gOutput &p_file, int p_nDecimals) const{  int oldPrecision = p_file.GetPrec();  p_file.SetPrec(p_nDecimals);  try {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -