Skip to content

Commit 16c66bc

Browse files
changed LCP solver
1 parent cb215c1 commit 16c66bc

1 file changed

Lines changed: 126 additions & 3 deletions

File tree

src/solvers/lcp/efglcp.cc

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "gambit.h"
2525
#include "solvers/linalg/lemketab.h"
2626
#include "solvers/lcp/lcp.h"
27+
#include "solvers/enumpoly/gameseq.h"
2728

2829
namespace 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

5461
template <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+
291360
template <class T>
292361
void 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+
343466
template <class T>
344467
std::list<MixedBehaviorProfile<T>> LcpBehaviorSolve(const Game &p_game, int p_stopAfter,
345468
int p_maxDepth,

0 commit comments

Comments
 (0)