📄 efg.cc
字号:
bool efgGame::DeleteEmptyInfoset(Infoset *s){ if (!s) throw Exception(); if (s->NumMembers() > 0) return false; m_revision++; m_dirty = true; s->player->infosets.Remove(s->player->infosets.Find(s)); delete s; return true;}void efgGame::DeleteEmptyInfosets(void){ for (int pl = 1; pl <= NumPlayers(); pl++) { for (int iset = 1; iset <= NumInfosets()[pl]; iset++) { if (DeleteEmptyInfoset(Players()[pl]->Infosets()[iset])) { iset--; } } }} Infoset *efgGame::SwitchPlayer(Infoset *s, EFPlayer *p){ if (!s || !p) throw Exception(); if (s->GetPlayer()->IsChance() || p->IsChance()) throw Exception(); if (s->player == p) return s; m_revision++; m_dirty = true; s->player->infosets.Remove(s->player->infosets.Find(s)); s->player = p; p->infosets.Append(s); DeleteLexicon(); SortInfosets(); return s;}void efgGame::CopySubtree(Node *src, Node *dest, Node *stop){ if (src == stop) { dest->outcome = src->outcome; return; } if (src->children.Length()) { AppendNode(dest, src->infoset); for (int i = 1; i <= src->children.Length(); i++) CopySubtree(src->children[i], dest->children[i], stop); } dest->name = src->name; dest->outcome = src->outcome;}//// MarkSubtree: sets the Node::mark flag on all children of p_node//void efgGame::MarkSubtree(Node *p_node){ p_node->mark = true; for (int i = 1; i <= p_node->children.Length(); i++) { MarkSubtree(p_node->children[i]); }}//// UnmarkSubtree: clears the Node::mark flag on all children of p_node//void efgGame::UnmarkSubtree(Node *p_node){ p_node->mark = false; for (int i = 1; i <= p_node->children.Length(); i++) { UnmarkSubtree(p_node->children[i]); }}void efgGame::Reveal(Infoset *where, const gArray<EFPlayer *> &who){ if (where->actions.Length() <= 1) { // only one action; nothing to reveal! return; } UnmarkSubtree(root); // start with a clean tree m_revision++; m_dirty = true; for (int i = 1; i <= where->actions.Length(); i++) { for (int j = 1; j <= where->members.Length(); j++) { MarkSubtree(where->members[j]->children[i]); } for (int j = who.First(); j <= who.Last(); j++) { // iterate over each information set of player 'j' in the list for (int k = 1; k <= who[j]->infosets.Length(); k++) { // iterate over each member of information set 'k' // make copy of members to iterate correctly // (since the information set may be changed in the process) gArray<Node *> members = who[j]->infosets[k]->members; Infoset *newiset = 0; for (int m = 1; m <= members.Length(); m++) { Node *n = members[m]; if (n->mark) { // If node is marked, is descendant of action 'i' n->mark = false; // unmark so tree is clean at end if (!newiset) { newiset = LeaveInfoset(n); } else { JoinInfoset(newiset, n); } } } } } } Reindex();}Node *efgGame::CopyTree(Node *src, Node *dest){ if (!src || !dest) throw Exception(); if (src == dest || dest->children.Length()) return src; if (src->gameroot != dest->gameroot) return src; if (src->children.Length()) { m_revision++; m_dirty = true; AppendNode(dest, src->infoset); for (int i = 1; i <= src->children.Length(); i++) CopySubtree(src->children[i], dest->children[i], dest); DeleteLexicon(); SortInfosets(); } return dest;}Node *efgGame::MoveTree(Node *src, Node *dest){ if (!src || !dest) throw Exception(); if (src == dest || dest->children.Length() || IsPredecessor(src, dest)) return src; if (src->gameroot != dest->gameroot) return src; m_revision++; m_dirty = true; if (src->parent == dest->parent) { int srcChild = src->parent->children.Find(src); int destChild = src->parent->children.Find(dest); src->parent->children[srcChild] = dest; src->parent->children[destChild] = src; } else { Node *parent = src->parent; parent->children[parent->children.Find(src)] = dest; dest->parent->children[dest->parent->children.Find(dest)] = src; src->parent = dest->parent; dest->parent = parent; } dest->name = ""; dest->outcome = 0; DeleteLexicon(); SortInfosets(); return dest;}Node *efgGame::DeleteTree(Node *n){ if (!n) throw Exception(); m_revision++; m_dirty = true; while (NumChildren(n) > 0) { DeleteTree(n->children[1]); delete n->children.Remove(1); } if (n->infoset) { n->infoset->members.Remove(n->infoset->members.Find(n)); n->infoset = 0; } n->outcome = 0; n->name = ""; DeleteLexicon(); SortInfosets(); return n;}Action *efgGame::InsertAction(Infoset *s){ if (!s) throw Exception(); m_revision++; m_dirty = true; Action *action = s->InsertAction(s->NumActions() + 1); for (int i = 1; i <= s->members.Length(); i++) { s->members[i]->children.Append(new Node(this, s->members[i])); } DeleteLexicon(); SortInfosets(); return action;}Action *efgGame::InsertAction(Infoset *s, const Action *a){ if (!a || !s) throw Exception(); m_revision++; m_dirty = true; int where; for (where = 1; where <= s->actions.Length() && s->actions[where] != a; where++); if (where > s->actions.Length()) return 0; Action *action = s->InsertAction(where); for (int i = 1; i <= s->members.Length(); i++) s->members[i]->children.Insert(new Node(this, s->members[i]), where); DeleteLexicon(); SortInfosets(); return action;}Infoset *efgGame::DeleteAction(Infoset *s, const Action *a){ if (!a || !s) throw Exception(); m_revision++; m_dirty = true; int where; for (where = 1; where <= s->actions.Length() && s->actions[where] != a; where++); if (where > s->actions.Length() || s->actions.Length() == 1) return s; s->RemoveAction(where); for (int i = 1; i <= s->members.Length(); i++) { DeleteTree(s->members[i]->children[where]); delete s->members[i]->children.Remove(where); } DeleteLexicon(); SortInfosets(); return s;}void efgGame::SetChanceProb(Infoset *infoset, int act, const gNumber &value){ if (infoset->IsChanceInfoset()) { m_revision++; m_dirty = true; ((ChanceInfoset *) infoset)->SetActionProb(act, value); }}gNumber efgGame::GetChanceProb(Infoset *infoset, int act) const{ if (infoset->IsChanceInfoset()) return ((ChanceInfoset *) infoset)->GetActionProb(act); else return (gNumber) 0;}gNumber efgGame::GetChanceProb(const Action *a) const{ return GetChanceProbs(a->BelongsTo())[a->GetNumber()];}gArray<gNumber> efgGame::GetChanceProbs(Infoset *infoset) const{ if (infoset->IsChanceInfoset()) return ((ChanceInfoset *) infoset)->GetActionProbs(); else return gArray<gNumber>(infoset->NumActions());}//---------------------------------------------------------------------// Subgame-related functions//---------------------------------------------------------------------void efgGame::MarkTree(Node *n, Node *base){ n->ptr = base; for (int i = 1; i <= NumChildren(n); i++) MarkTree(n->GetChild(i), base);}bool efgGame::CheckTree(Node *n, Node *base){ int i; if (NumChildren(n) == 0) return true; for (i = 1; i <= NumChildren(n); i++) if (!CheckTree(n->GetChild(i), base)) return false; if (n->GetPlayer()->IsChance()) return true; for (i = 1; i <= n->GetInfoset()->NumMembers(); i++) if (n->GetInfoset()->Members()[i]->ptr != base) return false; return true;}bool efgGame::IsLegalSubgame(Node *n){ if (NumChildren(n) == 0) return false; MarkTree(n, n); return CheckTree(n, n);}bool efgGame::MarkSubgame(Node *n){ if(n->gameroot == n) return true; if (n->gameroot != n && IsLegalSubgame(n)) { n->gameroot = 0; MarkSubgame(n, n); return true; } return false;}void efgGame::UnmarkSubgame(Node *n){ if (n->gameroot == n && n->parent) { n->gameroot = 0; MarkSubgame(n, n->parent->gameroot); }} void efgGame::MarkSubgame(Node *n, Node *base){ if (n->gameroot == n) return; n->gameroot = base; for (int i = 1; i <= NumChildren(n); i++) MarkSubgame(n->GetChild(i), base);}void efgGame::MarkSubgames(const gList<Node *> &list){ for (int i = 1; i <= list.Length(); i++) { if (IsLegalSubgame(list[i])) { list[i]->gameroot = 0; MarkSubgame(list[i], list[i]); } }}void efgGame::MarkSubgames(void){ gList<Node *> subgames; LegalSubgameRoots(*this, subgames); for (int i = 1; i <= subgames.Length(); i++) { subgames[i]->gameroot = 0; MarkSubgame(subgames[i], subgames[i]); }}void efgGame::UnmarkSubgames(Node *n){ if (NumChildren(n) == 0) return; for (int i = 1; i <= NumChildren(n); i++) UnmarkSubgames(n->GetChild(i)); if (n->gameroot == n && n->parent) { n->gameroot = 0; MarkSubgame(n, n->parent->gameroot); }}int efgGame::ProfileLength(void) const{ int sum = 0; for (int i = 1; i <= players.Length(); i++) for (int j = 1; j <= players[i]->infosets.Length(); j++) sum += players[i]->infosets[j]->actions.Length(); return sum;}gArray<int> efgGame::NumInfosets(void) const{ gArray<int> foo(players.Length()); for (int i = 1; i <= foo.Length(); i++) { foo[i] = players[i]->NumInfosets(); } return foo;}int efgGame::NumPlayerInfosets() const{ int answer(0); int pl; for (pl = 1; pl <= NumPlayers(); pl++) answer += players[pl]->infosets.Length(); return answer;}int efgGame::NumChanceInfosets() const{ return chance->infosets.Length();}int efgGame::TotalNumInfosets(void) const{ return NumPlayerInfosets() + NumChanceInfosets();}gPVector<int> efgGame::NumActions(void) const{ gArray<int> foo(players.Length()); int i; for (i = 1; i <= players.Length(); i++) foo[i] = players[i]->infosets.Length(); gPVector<int> bar(foo); for (i = 1; i <= players.Length(); i++) { for (int j = 1; j <= players[i]->infosets.Length(); j++) { bar(i, j) = players[i]->infosets[j]->NumActions(); } } return bar;} int efgGame::NumPlayerActions(void) const{ int answer = 0; gPVector<int> nums_actions = NumActions(); for (int i = 1; i <= NumPlayers(); i++) answer += nums_actions[i]; return answer;}int efgGame::NumChanceActions(void) const{ int answer = 0; for (int i = 1; i <= players[0]->infosets.Length(); i++) { answer += players[0]->infosets[i]->NumActions(); } return answer;}gPVector<int> efgGame::NumMembers(void) const{ gArray<int> foo(players.Length()); for (int i = 1; i <= players.Length(); i++) { foo[i] = players[i]->NumInfosets(); } gPVector<int> bar(foo); for (int i = 1; i <= players.Length(); i++) { for (int j = 1; j <= players[i]->NumInfosets(); j++) { bar(i, j) = players[i]->infosets[j]->NumMembers(); } } return bar;}//------------------------------------------------------------------------// Efg: Payoff computation//------------------------------------------------------------------------void efgGame::Payoff(Node *n, gNumber prob, const gPVector<int> &profile, gVector<gNumber> &payoff) const{ if (n->outcome) { for (int i = 1; i <= players.Length(); i++) payoff[i] += prob * n->outcome->m_payoffs[i]; } if (n->infoset && n->infoset->player->IsChance()) for (int i = 1; i <= n->children.Length(); i++) Payoff(n->children[i], prob * GetChanceProb(n->infoset, i), profile, payoff); else if (n->infoset) Payoff(n->children[profile(n->infoset->player->number,n->infoset->number)], prob, profile, payoff);}void efgGame::InfosetProbs(Node *n, gNumber prob, const gPVector<int> &profile, gPVector<gNumber> &probs) const{ if (n->infoset && n->infoset->player->IsChance()) for (int i = 1; i <= n->children.Length(); i++) InfosetProbs(n->children[i], prob * GetChanceProb(n->infoset, i), profile, probs); else if (n->infoset) { probs(n->infoset->player->number, n->infoset->number) += prob; InfosetProbs(n->children[profile(n->infoset->player->number,n->infoset->number)], prob, profile, probs); }}void efgGame::Payoff(const gPVector<int> &profile, gVector<gNumber> &payoff) const{ ((gVector<gNumber> &) payoff).operator=((gNumber) 0); Payoff(root, 1, profile, payoff);}void efgGame::InfosetProbs(const gPVector<int> &profile, gPVector<gNumber> &probs) const{ ((gVector<gNumber> &) probs).operator=((gNumber) 0); InfosetProbs(root, 1, profile, probs);}void efgGame::Payoff(Node *n, gNumber prob, const gArray<gArray<int> *> &profile, gArray<gNumber> &payoff) const{ if (n->outcome) { for (int i = 1; i <= players.Length(); i++) payoff[i] += prob * n->outcome->m_payoffs[i]; } if (n->infoset && n->infoset->player->IsChance()) for (int i = 1; i <= n->children.Length(); i++) Payoff(n->children[i], prob * GetChanceProb(n->infoset, i), profile, payoff); else if (n->infoset) Payoff(n->children[(*profile[n->infoset->player->number])[n->infoset->number]], prob, profile, payoff);}void efgGame::Payoff(const gArray<gArray<int> *> &profile, gArray<gNumber> &payoff) const{ for (int i = 1; i <= payoff.Length(); i++) payoff[i] = 0; Payoff(root, 1, profile, payoff);}Nfg *efgGame::AssociatedNfg(void) const{ if (lexicon) { return lexicon->N; } else { return 0; }}Nfg *efgGame::AssociatedAfg(void) const{ return afg;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -