Algorithmic Game Theory with Nashpy | by Valentina Alto | Towards Data Science

Game Theory is a method of studying strategic situations. A ‘strategic’ situation is a setting where the outcomes which affect you depend not just on your own actions, but on the actions of others as well. Let’s think about the market of firms: if the scenario is that of Perfect Competition, all the firms are price takers, hence they do not have to worry about the strategic setting of the price. Similarly, if the scenario is a Monopoly, the only firm in the market can set its own price without caring about other firms’ strategies.
Everything between perfect competition and monopoly is a strategic situation.
Algorithmic game theory is an area in the intersection of game theory and computer science, with the objective of understanding and design of algorithms in strategic environments.
In this article, I’ll show you a very intuitive implementation of Game Theory in Python, with the aid of the library Nashpy. As the name suggests, Nashpy provides algorithmic ways to find the Nash equilibrium of the game.
The Nash equilibrium of a game is a profile of strategies where all the players are doing the best response analysis (we will explain this concept later on). Basically, it finds an equilibrium strategy profile s* such that everyone is playing their best response.
But what does it means ‘best response’?
To better understand this concept, let’s have a look at the well-known Prisoner’s Dilemma:
The idea is that there are two Players (the prisoners) which have to decide whether to cooperate with each other, not revealing the other’s name while interviewed by the police. If both cooperate, they will have a utility of 3 each. However, they are incentivized not to cooperate, since the one who will not cooperate will gain a utility of 4 (while the other will gain nothing). However, if both make the same reasoning, they will end up not cooperating, which means gaining only 1 of utility each. Why are they going to deviate from cooperation? Let’s examine the best response analysis of Player 1 (P1)
If P2 cooperates, P1’s best response is not cooperating, since the utility of NC is 4>3.
If P2 does not cooperate, P1’s best response is not cooperating, since 1>0.
Hence, P1 has a dominant strategy which is (NC, NC). As it being a symmetric game, the same reasoning holds for P2. Hence, in this game, the Nash equilibrium is (NC, NC)=P1 plays NC and P2 plays NC: each player plays its best response against the other player.
Now let’s see how to implement this procedure in Python.
First, you have to run on your Jupyter console pip install nashpy and then import the module. With that being done, you can create your game environment. For a 2-players game with no-zero sum (which is the default interpretation of Nashpy), you have to create two matrices which represent the game from each player’s point of view. Namely, for P1 we will have:
While for P2:
Let’s do the same in Python:
import nashpy as nashimport numpy as npP1=np.array([[3,0],[4,1]])P2=np.array([[3,4],[0,1]])prisoner_dilemma=nash.Game(P1,P2)prisoner_dilemma
We can also get the utility of players’ strategies. Namely, if P1 cooperates while P2 does not, looking at the table we will see that the pair of utility is (0,4).
We obtained the former result (0,4) by looking at the game table, however we can get the same result with a matrix computation, which is the same procedure followed by Nashpy. Indeed, if we consider a vector sigma, as long as the number of actions (in this case, only 2 — cooperate and not cooperate), where each entry is equal to 0 except for that in the position of the action which the player will take, where the entry is 1, we can see that the utility of P1 derived from a given action when P2 plays another given action is:
And the same holds for P2:
If we apply this formula to our previous example, when P1 plays C and P2 plays NC, we have:
Let’s check it out with Nashpy:
p1_sigma=[1,0]p2_sigma=[0,1]prisoner_dilemma[p1_sigma,p2_sigma]
Now let’s see if our algorithm is able to find the Nash equilibrium which, as mentioned above, is (NC, NC):
eqs = prisoner_dilemma.support_enumeration()list(eqs)
As you can see, the Nash equilibrium consists of two vectors, each indicating one player’s action: P1 has [0 1], and the 1 in the second position means P1 will play NC; the same reasoning holds for P2.