diff --git a/src/solvers/enumpoly/behavextend.cc b/src/solvers/enumpoly/behavextend.cc index 25872d453..9d7aaf2b4 100644 --- a/src/solvers/enumpoly/behavextend.cc +++ b/src/solvers/enumpoly/behavextend.cc @@ -26,101 +26,77 @@ #include "rectangl.h" #include "ineqsolv.h" -void TerminalDescendants(const Gambit::GameNode &p_node, Gambit::List ¤t) +using namespace Gambit; + +namespace { + +void TerminalDescendants(const GameNode &p_node, std::list ¤t) { if (p_node->IsTerminal()) { current.push_back(p_node); } else { - for (int i = 1; i <= p_node->NumChildren(); i++) { - TerminalDescendants(p_node->GetChild(i), current); + for (auto child : p_node->GetChildren()) { + TerminalDescendants(child, current); } } } -Gambit::List TerminalNodes(const Gambit::Game &p_efg) +std::list TerminalNodes(const Game &p_efg) { - Gambit::List ret; + std::list ret; TerminalDescendants(p_efg->GetRoot(), ret); return ret; } -// -// Design choice: the auxiliary functions here are made static -// rather than members to help hide the gPoly-related details of -// the implementation. Some of these functions might be more -// generally useful, in which case they should be made visible -// somehow. Also, a namespace would be preferable to using -// static, but static is used for portability. -- TLT, 5/2001. -// - -//========================================================================= -// class algExtendsToNash -//========================================================================= - -static void DeviationInfosets(Gambit::List &answer, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::GamePlayer &pl, const Gambit::GameNode &node, - const Gambit::GameAction &act) +void DeviationInfosets(List &answer, const BehaviorSupportProfile &big_supp, + const GamePlayer &pl, const GameNode &node, const GameAction &act) { - Gambit::GameNode child = node->GetChild(act->GetNumber()); - if (!child->IsTerminal()) { - Gambit::GameInfoset iset = child->GetInfoset(); - if (iset->GetPlayer() == pl) { - int insert = 0; - bool done = false; - while (!done) { - insert++; - if (insert > answer.Length() || iset->Precedes(answer[insert]->GetMember(1))) { - done = true; - } + GameNode child = node->GetChild(act); + if (child->IsTerminal()) { + return; + } + GameInfoset iset = child->GetInfoset(); + if (iset->GetPlayer() == pl) { + int insert = 0; + bool done = false; + while (!done) { + insert++; + if (insert > answer.size() || iset->Precedes(answer[insert]->GetMember(1))) { + done = true; } - answer.Insert(iset, insert); } + answer.Insert(iset, insert); + } - Gambit::List action_list; - for (int j = 1; j <= iset->NumActions(); j++) { - action_list.push_back(iset->GetAction(j)); - } - for (int j = 1; j <= action_list.Length(); j++) { - DeviationInfosets(answer, big_supp, pl, child, action_list[j]); - } + for (auto action : iset->GetActions()) { + DeviationInfosets(answer, big_supp, pl, child, action); } } -static Gambit::List -DeviationInfosets(const Gambit::BehaviorSupportProfile &big_supp, const Gambit::GamePlayer &pl, - const Gambit::GameInfoset &iset, const Gambit::GameAction &act) +List DeviationInfosets(const BehaviorSupportProfile &big_supp, const GamePlayer &pl, + const GameInfoset &iset, const GameAction &act) { - Gambit::List answer; - - Gambit::List node_list; - for (int i = 1; i <= iset->NumMembers(); i++) { - node_list.push_back(iset->GetMember(i)); - } - - for (int i = 1; i <= node_list.Length(); i++) { - DeviationInfosets(answer, big_supp, pl, node_list[i], act); + List answer; + for (auto member : iset->GetMembers()) { + DeviationInfosets(answer, big_supp, pl, member, act); } - return answer; } -static gPolyList -ActionProbsSumToOneIneqs(const Gambit::MixedBehaviorProfile &p_solution, - const gSpace &BehavStratSpace, const term_order &Lex, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List> &var_index) +gPolyList ActionProbsSumToOneIneqs(const MixedBehaviorProfile &p_solution, + const gSpace &BehavStratSpace, const term_order &Lex, + const BehaviorSupportProfile &big_supp, + const std::map &var_index) { gPolyList answer(&BehavStratSpace, &Lex); - for (int pl = 1; pl <= p_solution.GetGame()->NumPlayers(); pl++) { - for (int i = 1; i <= p_solution.GetGame()->GetPlayer(pl)->NumInfosets(); i++) { - Gambit::GameInfoset current_infoset = p_solution.GetGame()->GetPlayer(pl)->GetInfoset(i); - if (!big_supp.HasAction(current_infoset)) { - int index_base = var_index[pl][i]; - gPoly factor(&BehavStratSpace, (double)1.0, &Lex); - for (int k = 1; k < current_infoset->NumActions(); k++) { + for (auto player : p_solution.GetGame()->GetPlayers()) { + for (auto infoset : player->GetInfosets()) { + if (!big_supp.HasAction(infoset)) { + int index_base = var_index.at(infoset); + gPoly factor(&BehavStratSpace, 1.0, &Lex); + for (int k = 1; k < infoset->NumActions(); k++) { factor -= gPoly(&BehavStratSpace, index_base + k, 1, &Lex); } answer += factor; @@ -130,21 +106,17 @@ ActionProbsSumToOneIneqs(const Gambit::MixedBehaviorProfile &p_solution, return answer; } -static Gambit::List -DeviationSupports(const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List &isetlist, - const Gambit::GamePlayer & /*pl*/, const Gambit::GameInfoset & /*iset*/, - const Gambit::GameAction & /*act*/) +std::list DeviationSupports(const BehaviorSupportProfile &big_supp, + const List &isetlist) { - Gambit::List answer; - - Gambit::Array active_act_no(isetlist.Length()); + std::list answer; + Array active_act_no(isetlist.size()); for (int k = 1; k <= active_act_no.Length(); k++) { active_act_no[k] = 0; } - Gambit::BehaviorSupportProfile new_supp(big_supp); + BehaviorSupportProfile new_supp(big_supp); for (int i = 1; i <= isetlist.Length(); i++) { for (int j = 1; j < isetlist[i]->NumActions(); j++) { @@ -204,18 +176,15 @@ DeviationSupports(const Gambit::BehaviorSupportProfile &big_supp, return answer; } -static bool NashNodeProbabilityPoly(const Gambit::MixedBehaviorProfile &p_solution, - gPoly &node_prob, const gSpace &BehavStratSpace, - const term_order &Lex, - const Gambit::BehaviorSupportProfile &dsupp, - const Gambit::List> &var_index, - Gambit::GameNode tempnode, const Gambit::GamePlayer & /*pl*/, - const Gambit::GameInfoset &iset, const Gambit::GameAction &act) +bool NashNodeProbabilityPoly(const MixedBehaviorProfile &p_solution, + gPoly &node_prob, const gSpace &BehavStratSpace, + const term_order &Lex, const BehaviorSupportProfile &dsupp, + const std::map &var_index, GameNode tempnode, + const GameInfoset &iset, const GameAction &act) { while (tempnode != p_solution.GetGame()->GetRoot()) { - - Gambit::GameAction last_action = tempnode->GetPriorAction(); - Gambit::GameInfoset last_infoset = last_action->GetInfoset(); + GameAction last_action = tempnode->GetPriorAction(); + GameInfoset last_infoset = last_action->GetInfoset(); if (last_infoset->IsChanceInfoset()) { node_prob *= static_cast(last_infoset->GetActionProb(last_action->GetNumber())); @@ -229,7 +198,7 @@ static bool NashNodeProbabilityPoly(const Gambit::MixedBehaviorProfile & else if (dsupp.Contains(last_action)) { if (last_action->GetInfoset()->GetPlayer() != act->GetInfoset()->GetPlayer() || !act->Precedes(tempnode)) { - node_prob *= (double)p_solution.GetActionProb(last_action); + node_prob *= p_solution.GetActionProb(last_action); } } else { @@ -237,16 +206,14 @@ static bool NashNodeProbabilityPoly(const Gambit::MixedBehaviorProfile & } } else { - int initial_var_no = - var_index[last_infoset->GetPlayer()->GetNumber()][last_infoset->GetNumber()]; + int initial_var_no = var_index.at(last_infoset); if (last_action->GetNumber() < last_infoset->NumActions()) { int varno = initial_var_no + last_action->GetNumber(); node_prob *= gPoly(&BehavStratSpace, varno, 1, &Lex); } else { - gPoly factor(&BehavStratSpace, (double)1.0, &Lex); - int k; - for (k = 1; k < last_infoset->NumActions(); k++) { + gPoly factor(&BehavStratSpace, 1.0, &Lex); + for (int k = 1; k < last_infoset->NumActions(); k++) { factor -= gPoly(&BehavStratSpace, initial_var_no + k, 1, &Lex); } node_prob *= factor; @@ -257,61 +224,44 @@ static bool NashNodeProbabilityPoly(const Gambit::MixedBehaviorProfile & return true; } -static gPolyList -NashExpectedPayoffDiffPolys(const Gambit::MixedBehaviorProfile &p_solution, - const gSpace &BehavStratSpace, const term_order &Lex, - const Gambit::BehaviorSupportProfile &little_supp, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List> &var_index) +gPolyList NashExpectedPayoffDiffPolys(const MixedBehaviorProfile &p_solution, + const gSpace &BehavStratSpace, const term_order &Lex, + const BehaviorSupportProfile &little_supp, + const BehaviorSupportProfile &big_supp, + const std::map &var_index) { gPolyList answer(&BehavStratSpace, &Lex); - Gambit::List terminal_nodes = TerminalNodes(p_solution.GetGame()); - - for (int pl = 1; pl <= p_solution.GetGame()->NumPlayers(); pl++) { - Gambit::Array isets_for_pl; - for (int iset = 1; iset <= p_solution.GetGame()->GetPlayer(pl)->NumInfosets(); iset++) { - isets_for_pl.push_back(p_solution.GetGame()->GetPlayer(pl)->GetInfoset(iset)); - } + auto terminal_nodes = TerminalNodes(p_solution.GetGame()); - for (int i = 1; i <= isets_for_pl.Length(); i++) { - if (little_supp.IsReachable(isets_for_pl[i])) { - Gambit::Array acts_for_iset; - for (int act = 1; act <= isets_for_pl[i]->NumActions(); act++) { - acts_for_iset.push_back(isets_for_pl[i]->GetAction(act)); + for (auto player : p_solution.GetGame()->GetPlayers()) { + for (auto infoset : player->GetInfosets()) { + if (!little_supp.IsReachable(infoset)) { + continue; + } + for (auto action : infoset->GetActions()) { + if (little_supp.Contains(action)) { + continue; } - - for (int j = 1; j <= acts_for_iset.Length(); j++) { - if (!little_supp.Contains(acts_for_iset[j])) { - Gambit::List isetlist = DeviationInfosets( - big_supp, p_solution.GetGame()->GetPlayer(pl), isets_for_pl[i], acts_for_iset[j]); - Gambit::List dsupps = - DeviationSupports(big_supp, isetlist, p_solution.GetGame()->GetPlayer(pl), - isets_for_pl[i], acts_for_iset[j]); - for (int k = 1; k <= dsupps.Length(); k++) { - - // This will be the utility difference between the - // payoff resulting from the profile and deviation to - // the strategy for pl specified by dsupp[k] - - gPoly next_poly(&BehavStratSpace, &Lex); - - for (int n = 1; n <= terminal_nodes.Length(); n++) { - gPoly node_prob(&BehavStratSpace, (double)1.0, &Lex); - if (NashNodeProbabilityPoly(p_solution, node_prob, BehavStratSpace, Lex, dsupps[k], - var_index, terminal_nodes[n], - p_solution.GetGame()->GetPlayer(pl), isets_for_pl[i], - acts_for_iset[j])) { - if (terminal_nodes[n]->GetOutcome()) { - node_prob *= - static_cast(terminal_nodes[n]->GetOutcome()->GetPayoff(pl)); - } - next_poly += node_prob; - } + auto isetlist = DeviationInfosets(big_supp, player, infoset, action); + auto dsupps = DeviationSupports(big_supp, isetlist); + for (auto support : dsupps) { + // The utility difference between the + // payoff resulting from the profile and deviation to + // the strategy for pl specified by dsupp[k] + gPoly next_poly(&BehavStratSpace, &Lex); + + for (auto node : terminal_nodes) { + gPoly node_prob(&BehavStratSpace, 1.0, &Lex); + if (NashNodeProbabilityPoly(p_solution, node_prob, BehavStratSpace, Lex, support, + var_index, node, infoset, action)) { + if (node->GetOutcome()) { + node_prob *= static_cast(node->GetOutcome()->GetPayoff(player)); } - answer += -next_poly + (double)p_solution.GetPayoff(pl); + next_poly += node_prob; } } + answer += -next_poly + p_solution.GetPayoff(player); } } } @@ -319,47 +269,40 @@ NashExpectedPayoffDiffPolys(const Gambit::MixedBehaviorProfile &p_soluti return answer; } -static gPolyList ExtendsToNashIneqs(const Gambit::MixedBehaviorProfile &p_solution, - const gSpace &BehavStratSpace, const term_order &Lex, - const Gambit::BehaviorSupportProfile &little_supp, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List> &var_index) +gPolyList ExtendsToNashIneqs(const MixedBehaviorProfile &p_solution, + const gSpace &BehavStratSpace, const term_order &Lex, + const BehaviorSupportProfile &little_supp, + const BehaviorSupportProfile &big_supp, + const std::map &var_index) { gPolyList answer(&BehavStratSpace, &Lex); answer += ActionProbsSumToOneIneqs(p_solution, BehavStratSpace, Lex, big_supp, var_index); - answer += NashExpectedPayoffDiffPolys(p_solution, BehavStratSpace, Lex, little_supp, big_supp, var_index); return answer; } -bool algExtendsToNash::ExtendsToNash(const Gambit::MixedBehaviorProfile &p_solution, - const Gambit::BehaviorSupportProfile &little_supp, - const Gambit::BehaviorSupportProfile &big_supp) -{ - // This asks whether there is a Nash extension of the Gambit::MixedBehaviorProfile to - // all information sets at which the behavioral probabilities are not - // specified. The assumption is that the support has active actions - // at infosets at which the behavioral probabilities are defined, and - // no others. Also, the BehavSol is assumed to be already a Nash - // equilibrium for the truncated game obtained by eliminating stuff - // outside little_supp. +} // end anonymous namespace - // First we compute the number of variables, and indexing information - int num_vars(0); - Gambit::List> var_index; - int pl; - for (pl = 1; pl <= p_solution.GetGame()->NumPlayers(); pl++) { +namespace Gambit { +namespace Nash { - Gambit::List list_for_pl; +bool ExtendsToNash(const MixedBehaviorProfile &p_solution, + const BehaviorSupportProfile &little_supp, + const BehaviorSupportProfile &big_supp) +{ - for (int i = 1; i <= p_solution.GetGame()->GetPlayer(pl)->NumInfosets(); i++) { - list_for_pl.push_back(num_vars); - if (!big_supp.HasAction(p_solution.GetGame()->GetPlayer(pl)->GetInfoset(i))) { - num_vars += p_solution.GetGame()->GetPlayer(pl)->GetInfoset(i)->NumActions() - 1; + // First we compute the number of variables, and indexing information + int num_vars = 0; + std::map var_index; + for (auto player : p_solution.GetGame()->GetPlayers()) { + List list_for_pl; + for (auto infoset : player->GetInfosets()) { + var_index[infoset] = num_vars; + if (!big_supp.HasAction(infoset)) { + num_vars += infoset->NumActions() - 1; } } - var_index.push_back(list_for_pl); } // We establish the space @@ -367,41 +310,32 @@ bool algExtendsToNash::ExtendsToNash(const Gambit::MixedBehaviorProfile ORD_PTR ptr = &lex; term_order Lex(&BehavStratSpace, ptr); - num_vars = BehavStratSpace.Dmnsn(); - gPolyList inequalities = ExtendsToNashIneqs(p_solution, BehavStratSpace, Lex, little_supp, big_supp, var_index); // set up the rectangle of search - Gambit::Vector bottoms(num_vars), tops(num_vars); - bottoms = (double)0; - tops = (double)1; - gRectangle Cube(bottoms, tops); + Vector bottoms(num_vars), tops(num_vars); + bottoms = 0; + tops = 1; // Set up the test and do it - IneqSolv extension_tester(inequalities); - Gambit::Vector sample(num_vars); - bool answer = extension_tester.ASolutionExists(Cube, sample); + Vector sample(num_vars); + return IneqSolv(inequalities).ASolutionExists(gRectangle(bottoms, tops), sample); +} - // assert (answer == m_profile->ExtendsToNash(little_supp, big_supp, m_status)); +} // namespace Nash +} // end namespace Gambit - return answer; -} +namespace { -//========================================================================= -// class algExtendsToAgentNash -//========================================================================= - -static bool ANFNodeProbabilityPoly(const Gambit::MixedBehaviorProfile &p_solution, - gPoly &node_prob, const gSpace &BehavStratSpace, - const term_order &Lex, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List> &var_index, - Gambit::GameNode tempnode, const int &pl, const int &i, - const int &j) +bool ANFNodeProbabilityPoly(const MixedBehaviorProfile &p_solution, + gPoly &node_prob, const gSpace &BehavStratSpace, + const term_order &Lex, const BehaviorSupportProfile &big_supp, + const std::map &var_index, GameNode tempnode, int pl, + int i, int j) { while (tempnode != p_solution.GetGame()->GetRoot()) { - Gambit::GameAction last_action = tempnode->GetPriorAction(); - Gambit::GameInfoset last_infoset = last_action->GetInfoset(); + GameAction last_action = tempnode->GetPriorAction(); + GameInfoset last_infoset = last_action->GetInfoset(); if (last_infoset->IsChanceInfoset()) { node_prob *= static_cast(last_infoset->GetActionProb(last_action->GetNumber())); @@ -413,23 +347,21 @@ static bool ANFNodeProbabilityPoly(const Gambit::MixedBehaviorProfile &p } } else if (big_supp.Contains(last_action)) { - node_prob *= (double)p_solution.GetActionProb(last_action); + node_prob *= p_solution.GetActionProb(last_action); } else { return false; } } else { - int initial_var_no = - var_index[last_infoset->GetPlayer()->GetNumber()][last_infoset->GetNumber()]; + int initial_var_no = var_index.at(last_infoset); if (last_action->GetNumber() < last_infoset->NumActions()) { int varno = initial_var_no + last_action->GetNumber(); node_prob *= gPoly(&BehavStratSpace, varno, 1, &Lex); } else { - gPoly factor(&BehavStratSpace, (double)1.0, &Lex); - int k; - for (k = 1; k < last_infoset->NumActions(); k++) { + gPoly factor(&BehavStratSpace, 1.0, &Lex); + for (int k = 1; k < last_infoset->NumActions(); k++) { factor -= gPoly(&BehavStratSpace, initial_var_no + k, 1, &Lex); } node_prob *= factor; @@ -440,54 +372,52 @@ static bool ANFNodeProbabilityPoly(const Gambit::MixedBehaviorProfile &p return true; } -static gPolyList -ANFExpectedPayoffDiffPolys(const Gambit::MixedBehaviorProfile &p_solution, - const gSpace &BehavStratSpace, const term_order &Lex, - const Gambit::BehaviorSupportProfile &little_supp, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List> &var_index) +gPolyList ANFExpectedPayoffDiffPolys(const MixedBehaviorProfile &p_solution, + const gSpace &BehavStratSpace, const term_order &Lex, + const BehaviorSupportProfile &little_supp, + const BehaviorSupportProfile &big_supp, + const std::map &var_index) { gPolyList answer(&BehavStratSpace, &Lex); - Gambit::List terminal_nodes = TerminalNodes(p_solution.GetGame()); - - for (int pl = 1; pl <= p_solution.GetGame()->NumPlayers(); pl++) { - for (int i = 1; i <= p_solution.GetGame()->GetPlayer(pl)->NumInfosets(); i++) { - Gambit::GameInfoset infoset = p_solution.GetGame()->GetPlayer(pl)->GetInfoset(i); - if (little_supp.IsReachable(infoset)) { - for (int j = 1; j <= infoset->NumActions(); j++) { - if (!little_supp.Contains(infoset->GetAction(j))) { - - // This will be the utility difference between the - // payoff resulting from the profile and deviation to - // action j - gPoly next_poly(&BehavStratSpace, &Lex); - - for (int n = 1; n <= terminal_nodes.Length(); n++) { - gPoly node_prob(&BehavStratSpace, (double)1.0, &Lex); - if (ANFNodeProbabilityPoly(p_solution, node_prob, BehavStratSpace, Lex, big_supp, - var_index, terminal_nodes[n], pl, i, j)) { - if (terminal_nodes[n]->GetOutcome()) { - node_prob *= static_cast(terminal_nodes[n]->GetOutcome()->GetPayoff(pl)); - } - next_poly += node_prob; - } + auto terminal_nodes = TerminalNodes(p_solution.GetGame()); + + for (auto player : p_solution.GetGame()->GetPlayers()) { + for (auto infoset : player->GetInfosets()) { + if (!little_supp.IsReachable(infoset)) { + continue; + } + for (auto action : infoset->GetActions()) { + if (little_supp.Contains(action)) { + continue; + } + // This will be the utility difference between the + // payoff resulting from the profile and deviation to + // action j + gPoly next_poly(&BehavStratSpace, &Lex); + for (auto terminal : terminal_nodes) { + gPoly node_prob(&BehavStratSpace, 1.0, &Lex); + if (ANFNodeProbabilityPoly(p_solution, node_prob, BehavStratSpace, Lex, big_supp, + var_index, terminal, player->GetNumber(), + infoset->GetNumber(), action->GetNumber())) { + if (terminal->GetOutcome()) { + node_prob *= static_cast(terminal->GetOutcome()->GetPayoff(player)); } - answer += -next_poly + (double)p_solution.GetPayoff(pl); + next_poly += node_prob; } } + answer += -next_poly + p_solution.GetPayoff(player); } } } return answer; } -static gPolyList -ExtendsToANFNashIneqs(const Gambit::MixedBehaviorProfile &p_solution, - const gSpace &BehavStratSpace, const term_order &Lex, - const Gambit::BehaviorSupportProfile &little_supp, - const Gambit::BehaviorSupportProfile &big_supp, - const Gambit::List> &var_index) +gPolyList ExtendsToANFNashIneqs(const MixedBehaviorProfile &p_solution, + const gSpace &BehavStratSpace, const term_order &Lex, + const BehaviorSupportProfile &little_supp, + const BehaviorSupportProfile &big_supp, + const std::map &var_index) { gPolyList answer(&BehavStratSpace, &Lex); answer += ActionProbsSumToOneIneqs(p_solution, BehavStratSpace, Lex, big_supp, var_index); @@ -496,31 +426,25 @@ ExtendsToANFNashIneqs(const Gambit::MixedBehaviorProfile &p_solution, return answer; } -bool algExtendsToAgentNash::ExtendsToAgentNash( - const Gambit::MixedBehaviorProfile &p_solution, - const Gambit::BehaviorSupportProfile &little_supp, - const Gambit::BehaviorSupportProfile &big_supp) -{ - // This asks whether there is an ANF Nash extension of the Gambit::MixedBehaviorProfile - // to all information sets at which the behavioral probabilities are not specified. The - // assumption is that the support has active actions at infosets at which the behavioral - // probabilities are defined, and no others. - - // First we compute the number of variables, and indexing information - int num_vars(0); - Gambit::List> var_index; - int pl; - for (pl = 1; pl <= p_solution.GetGame()->NumPlayers(); pl++) { +} // end anonymous namespace - Gambit::List list_for_pl; +namespace Gambit { +namespace Nash { - for (int i = 1; i <= p_solution.GetGame()->GetPlayer(pl)->NumInfosets(); i++) { - list_for_pl.push_back(num_vars); - if (!big_supp.HasAction(p_solution.GetGame()->GetPlayer(pl)->GetInfoset(i))) { - num_vars += p_solution.GetGame()->GetPlayer(pl)->GetInfoset(i)->NumActions() - 1; +bool ExtendsToAgentNash(const MixedBehaviorProfile &p_solution, + const BehaviorSupportProfile &little_supp, + const BehaviorSupportProfile &big_supp) +{ + // First we compute the number of variables, and indexing information + int num_vars = 0; + std::map var_index; + for (auto player : p_solution.GetGame()->GetPlayers()) { + for (auto infoset : player->GetInfosets()) { + var_index[infoset] = num_vars; + if (!big_supp.HasAction(infoset)) { + num_vars += infoset->NumActions() - 1; } } - var_index.push_back(list_for_pl); } // We establish the space @@ -533,33 +457,14 @@ bool algExtendsToAgentNash::ExtendsToAgentNash( ExtendsToANFNashIneqs(p_solution, BehavStratSpace, Lex, little_supp, big_supp, var_index); // set up the rectangle of search - Gambit::Vector bottoms(num_vars), tops(num_vars); - bottoms = (double)0; - tops = (double)1; - gRectangle Cube(bottoms, tops); + Vector bottoms(num_vars), tops(num_vars); + bottoms = 0; + tops = 1; // Set up the test and do it - IneqSolv extension_tester(inequalities); - Gambit::Vector sample(num_vars); - - // Temporarily, we check the old set up vs. the new - bool ANFanswer = extension_tester.ASolutionExists(Cube, sample); - // assert (ANFanswer == m_profile->ExtendsToANFNash(little_supp, - // big_supp, - // m_status)); - - /* - bool NASHanswer = m_profile->ExtendsToNash(Support(),Support(),m_status); - - //DEBUG - if (ANFanswer && !NASHanswer) - gout << - "The following should be extendable to an ANF Nash, but not to a Nash:\n" - << *m_profile << "\n\n"; - if (NASHanswer && !ANFanswer) - gout << - "ERROR: said to be extendable to a Nash, but not to an ANF Nash:\n" - << *m_profile << "\n\n"; - */ - return ANFanswer; + Vector sample(num_vars); + return IneqSolv(inequalities).ASolutionExists(gRectangle(bottoms, tops), sample); } + +} // namespace Nash +} // end namespace Gambit diff --git a/src/solvers/enumpoly/behavextend.h b/src/solvers/enumpoly/behavextend.h index 837fe2919..be8f5276e 100644 --- a/src/solvers/enumpoly/behavextend.h +++ b/src/solvers/enumpoly/behavextend.h @@ -25,18 +25,29 @@ #include "gambit.h" -class algExtendsToNash { -public: - bool ExtendsToNash(const Gambit::MixedBehaviorProfile &p_solution, - const Gambit::BehaviorSupportProfile &p_littleSupport, - const Gambit::BehaviorSupportProfile &p_bigSupport); -}; +namespace Gambit { +namespace Nash { -class algExtendsToAgentNash { -public: - bool ExtendsToAgentNash(const Gambit::MixedBehaviorProfile &p_solution, - const Gambit::BehaviorSupportProfile &p_littleSupport, - const Gambit::BehaviorSupportProfile &p_bigSupport); -}; +// This asks whether there is a Nash extension of the MixedBehaviorProfile to +// all information sets at which the behavioral probabilities are not +// specified. The assumption is that the support has active actions +// at infosets at which the behavioral probabilities are defined, and +// no others. Also, the BehavSol is assumed to be already a Nash +// equilibrium for the truncated game obtained by eliminating stuff +// outside little_supp. +bool ExtendsToNash(const MixedBehaviorProfile &p_solution, + const BehaviorSupportProfile &p_littleSupport, + const BehaviorSupportProfile &p_bigSupport); + +// This asks whether there is an ANF Nash extension of the MixedBehaviorProfile +// to all information sets at which the behavioral probabilities are not specified. The +// assumption is that the support has active actions at infosets at which the behavioral +// probabilities are defined, and no others. +bool ExtendsToAgentNash(const MixedBehaviorProfile &p_solution, + const BehaviorSupportProfile &p_littleSupport, + const BehaviorSupportProfile &p_bigSupport); + +} // namespace Nash +} // namespace Gambit #endif // BEHAVEXTEND_H diff --git a/src/solvers/enumpoly/efgpoly.cc b/src/solvers/enumpoly/efgpoly.cc index 9249af7aa..be9dc1ab6 100644 --- a/src/solvers/enumpoly/efgpoly.cc +++ b/src/solvers/enumpoly/efgpoly.cc @@ -32,6 +32,7 @@ #include "behavextend.h" using namespace Gambit; +using namespace Gambit::Nash; namespace { @@ -155,13 +156,6 @@ std::map ToSequenceProbs(const ProblemData &p_data, const return x; } -bool ExtendsToNash(const MixedBehaviorProfile &bs) -{ - algExtendsToNash algorithm; - return algorithm.ExtendsToNash(bs, BehaviorSupportProfile(bs.GetGame()), - BehaviorSupportProfile(bs.GetGame())); -} - std::list> SolveSupport(const BehaviorSupportProfile &p_support, bool &p_isSingular) { @@ -191,7 +185,8 @@ std::list> SolveSupport(const BehaviorSupportProfil std::list> solutions; for (auto root : quickie.RootList()) { MixedBehaviorProfile sol(data.sfg.ToMixedBehaviorProfile(ToSequenceProbs(data, root))); - if (ExtendsToNash(sol)) { + if (ExtendsToNash(sol, BehaviorSupportProfile(sol.GetGame()), + BehaviorSupportProfile(sol.GetGame()))) { solutions.push_back(sol); } }