2424#include " gambit.h"
2525#include " solvers/linalg/lemketab.h"
2626#include " solvers/lcp/lcp.h"
27+ #include " solvers/enumpoly/gameseq.h"
2728
2829namespace Gambit ::Nash {
2930
@@ -45,10 +46,16 @@ template <class T> class NashLcpBehaviorSolver {
4546 class Solution ;
4647
4748 void FillTableau (Matrix<T> &, const GameNode &, T, int , int , Solution &) const ;
49+ void FillTableauNew (Matrix<T> &A, const Gambit::GameSequenceForm &sequenceForm,
50+ Solution &p_solution) const ;
4851 void AllLemke (const Game &, int dup, linalg::LemkeTableau<T> &B, int depth, Matrix<T> &,
4952 Solution &) const ;
5053 void GetProfile (const linalg::LemkeTableau<T> &tab, MixedBehaviorProfile<T> &, const Vector<T> &,
5154 const GameNode &n, int , int , Solution &) const ;
55+ void GetProfileNew (const linalg::LemkeTableau<T> &tab,
56+ MixedBehaviorProfile<T> &v, const Vector<T> &sol,
57+ const Gambit::GameSequenceForm &sequenceForm,
58+ Solution &p_solution) const ;
5259};
5360
5461template <class T > class NashLcpBehaviorSolver <T>::Solution {
@@ -126,7 +133,12 @@ std::list<MixedBehaviorProfile<T>> NashLcpBehaviorSolver<T>::Solve(const Game &p
126133 const int ntot = solution.ns1 + solution.ns2 + solution.ni1 + solution.ni2 ;
127134 Matrix<T> A (1 , ntot, 0 , ntot);
128135 A = static_cast <T>(0 );
129- FillTableau (A, p_game->GetRoot (), static_cast <T>(1 ), 1 , 1 , solution);
136+
137+ BehaviorSupportProfile full_support (p_game);
138+ Gambit::GameSequenceForm sequenceForm (full_support);
139+
140+ // FillTableau(A, p_game->GetRoot(), static_cast<T>(1), 1, 1, solution);
141+ FillTableauNew (A, sequenceForm, solution);
130142 for (int i = A.MinRow (); i <= A.MaxRow (); i++) {
131143 A (i, 0 ) = static_cast <T>(-1 );
132144 }
@@ -159,7 +171,8 @@ std::list<MixedBehaviorProfile<T>> NashLcpBehaviorSolver<T>::Solve(const Game &p
159171 Vector<T> sol (tab.MinRow (), tab.MaxRow ());
160172 tab.BasisVector (sol);
161173 MixedBehaviorProfile<T> profile (p_game);
162- GetProfile (tab, profile, sol, p_game->GetRoot (), 1 , 1 , solution);
174+ // GetProfile(tab, profile, sol, p_game->GetRoot(), 1, 1, solution);
175+ GetProfileNew (tab, profile, sol, sequenceForm, solution);
163176 profile.UndefinedToCentroid ();
164177 solution.m_equilibria .push_back (profile);
165178 this ->m_onEquilibrium (profile, " NE" );
@@ -214,7 +227,10 @@ void NashLcpBehaviorSolver<T>::AllLemke(const Game &p_game, int j, linalg::Lemke
214227 if (BCopy.SF_LCPPath (-missing) == 1 ) {
215228 newsol = p_solution.AddBFS (BCopy);
216229 BCopy.BasisVector (sol);
217- GetProfile (BCopy, profile, sol, p_game->GetRoot (), 1 , 1 , p_solution);
230+ BehaviorSupportProfile full_support (p_game);
231+ Gambit::GameSequenceForm sequenceForm (full_support);
232+ // GetProfile(BCopy, profile, sol, p_game->GetRoot(), 1, 1, p_solution);
233+ GetProfileNew (BCopy, profile, sol, sequenceForm, p_solution);
218234 profile.UndefinedToCentroid ();
219235 if (newsol) {
220236 m_onEquilibrium (profile, " NE" );
@@ -288,6 +304,59 @@ void NashLcpBehaviorSolver<T>::FillTableau(Matrix<T> &A, const GameNode &n, T pr
288304 }
289305}
290306
307+
308+ template <class T >
309+ void NashLcpBehaviorSolver<T>::FillTableauNew(Matrix<T> &A,
310+ const Gambit::GameSequenceForm &sequenceForm,
311+ Solution &p_solution) const
312+ {
313+ const int ns1 = p_solution.ns1 ;
314+ const int ns2 = p_solution.ns2 ;
315+ const int ni1 = p_solution.ni1 ;
316+ auto players = sequenceForm.GetPlayers ();
317+ auto it = players.begin ();
318+ auto player1 = *it;
319+ ++it;
320+ auto player2 = *it;
321+ auto sequences1 = sequenceForm.GetSequences (player1);
322+ auto sequences2 = sequenceForm.GetSequences (player2);
323+ for (auto seq : sequences1) {
324+ auto parentSeq = seq->parent .lock ();
325+ if (parentSeq) {
326+ const int infoset_idx = ns1 + ns2 + seq->GetInfoset ()->GetNumber () + 1 ;
327+ const int seq_idx = seq->number ;
328+ const int parent_idx = parentSeq->number ;
329+ A (parent_idx, infoset_idx) = static_cast <T>(-1 );
330+ A (infoset_idx, parent_idx) = static_cast <T>(1 );
331+ A (seq_idx, infoset_idx) = static_cast <T>(1 );
332+ A (infoset_idx, seq_idx) = static_cast <T>(-1 );
333+ }
334+ }
335+ for (auto seq : sequences2) {
336+ auto parentSeq = seq->parent .lock ();
337+ if (parentSeq) {
338+ const int infoset_idx = ns1 + ns2 + ni1 + seq->GetInfoset ()->GetNumber () + 1 ;
339+ const int seq_idx = seq->number ;
340+ const int parent_idx = parentSeq->number ;
341+ A (ns1 + parent_idx, infoset_idx) = static_cast <T>(-1 );
342+ A (infoset_idx, ns1 + parent_idx) = static_cast <T>(1 );
343+ A (ns1 + seq_idx, infoset_idx) = static_cast <T>(1 );
344+ A (infoset_idx, ns1 + seq_idx) = static_cast <T>(-1 );
345+ }
346+ }
347+ for (auto seq1 : sequences1) {
348+ for (auto seq2 : sequences2) {
349+ const int s1 = seq1->number ;
350+ const int s2 = seq2->number ;
351+ std::map<GamePlayer, GameSequence> profile;
352+ profile[player1] = seq1;
353+ profile[player2] = seq2;
354+ A (s1, ns1 + s2) = sequenceForm.GetPayoff (profile, player1) - p_solution.maxpay ;
355+ A (ns1 + s2, s1) = sequenceForm.GetPayoff (profile, player2) - p_solution.maxpay ;
356+ }
357+ }
358+ }
359+
291360template <class T >
292361void NashLcpBehaviorSolver<T>::GetProfile(const linalg::LemkeTableau<T> &tab,
293362 MixedBehaviorProfile<T> &v, const Vector<T> &sol,
@@ -340,6 +409,60 @@ void NashLcpBehaviorSolver<T>::GetProfile(const linalg::LemkeTableau<T> &tab,
340409 }
341410}
342411
412+ template <class T >
413+ void NashLcpBehaviorSolver<T>::GetProfileNew(const linalg::LemkeTableau<T> &tab,
414+ MixedBehaviorProfile<T> &v, const Vector<T> &sol,
415+ const Gambit::GameSequenceForm &sequenceForm,
416+ Solution &p_solution) const
417+ {
418+ const int ns1 = p_solution.ns1 ;
419+ auto players = sequenceForm.GetPlayers ();
420+ auto it = players.begin ();
421+ auto player1 = *it;
422+ ++it;
423+ auto player2 = *it;
424+ auto sequences1 = sequenceForm.GetSequences (player1);
425+ auto sequences2 = sequenceForm.GetSequences (player2);
426+ for (auto seq : sequences1) {
427+ auto parentSeq = seq->parent .lock ();
428+ if (parentSeq) {
429+ auto action = seq->action ;
430+ int index = seq->number ;
431+ int parentIndex = parentSeq->number ;
432+ v[action] = static_cast <T>(0 );
433+ if (tab.Member (parentIndex)) {
434+ const int ind = tab.Find (parentIndex);
435+ if (sol[ind] > p_solution.eps && tab.Member (index)) {
436+ const int ind2 = tab.Find (index);
437+ if (sol[ind2] > p_solution.eps ) {
438+ v[action] = sol[ind2] / sol[ind];
439+ }
440+ }
441+ }
442+ }
443+ }
444+ for (auto seq : sequences2) {
445+ auto parentSeq = seq->parent .lock ();
446+ if (parentSeq) {
447+ auto action = seq->action ;
448+ int index = seq->number ;
449+ int parentIndex = parentSeq->number ;
450+ v[action] = static_cast <T>(0 );
451+ if (tab.Member (ns1 + parentIndex)) {
452+ const int ind = tab.Find (ns1 + parentIndex);
453+ if (sol[ind] > p_solution.eps && tab.Member (ns1 + index)) {
454+ const int ind2 = tab.Find (ns1 + index);
455+ if (sol[ind2] > p_solution.eps ) {
456+ v[action] = sol[ind2] / sol[ind];
457+ }
458+ }
459+ }
460+ }
461+ }
462+ }
463+
464+
465+
343466template <class T >
344467std::list<MixedBehaviorProfile<T>> LcpBehaviorSolve (const Game &p_game, int p_stopAfter,
345468 int p_maxDepth,
0 commit comments