The support enumeration algorithm implemented in Nashpy
is based on the one described in [Nisan2007].
The algorithm is as follows:
For a degenerate 2 player game (A, B) ∈ ℝm × n2 the following algorithm returns all nash equilibria:
- For all 1 ≤ k1 ≤ m and 1 ≤ k2 ≤ n;
- For all pairs of support (I, J) with |I| = k1 and |J| = k2.
-
Solve the following equations (this ensures we have best responses):
∑i ∈ IσriBij = v for all j ∈ J
∑j ∈ JAijσcj = u for all i ∈ I - Solve
-
$\sum_{i=1}^{m}{\sigma_{r}}_i=1$ and σri ≥ 0 for all i -
$\sum_{j=1}^{n}{\sigma_{c}}_i=1$ and σcj ≥ 0 for all j
-
- Check the best response condition.
Repeat steps 3,4 and 5 for all potential support pairs.
- Step 1 is a complete enumeration of all possible strategies that the equilibria could be.
- Step 2 can be modified to only consider degenerate games ensuring that only supports of equal size are considered |I| = |J|. This is described further in
degenerate-games
. - Step 3 are the linear equations that are to be solved, for a given pair of supports these ensure that neither player has an incentive to move to another strategy on that support.
- Step 4 is to ensure we have mixed strategies.
- Step 5 is a final check that there is no better utility outside of the supports.
In Nashpy
this is all implemented algebraically using Numpy
to solve the linear equations.