diff --git a/game_theory_py.ipynb b/game_theory_py.ipynb index c425c88..6a91e71 100644 --- a/game_theory_py.ipynb +++ b/game_theory_py.ipynb @@ -2,20 +2,14 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ - "# Tools for Game Theory" + "# Tools for Game Theory in QuantEcon.py" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "**Daisuke Oyama** \n", "*Faculty of Economics, University of Tokyo*" @@ -23,21 +17,17 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ - "This notebook demonstrates the functionalities of the `game_theory` module." + "This notebook demonstrates the functionalities of the [`game_theory`](http://quanteconpy.readthedocs.io/en/latest/game_theory.html) module\n", + "in [QuantEcon.py](https://github.com/QuantEcon/QuantEcon.py)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -47,20 +37,14 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "## Normal Form Games" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "An $N$-player *normal form game* is a triplet $g = (I, (A_i)_{i \\in I}, (u_i)_{i \\in I})$ where\n", "\n", @@ -78,10 +62,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In our module,\n", "a normal form game and a player are represented by\n", @@ -96,30 +77,21 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "### Creating a `NormalFormGame`" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "There are several ways to create a `NormalFormGame` instance." ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The first is to pass an array of payoffs for all the players, i.e.,\n", "an $(N+1)$-dimenstional array of shape $(n_0, \\ldots, n_{N-1}, N)$\n", @@ -129,10 +101,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "As an example, consider the following game (\"**Matching Pennies**\"):\n", "\n", @@ -148,9 +117,7 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -163,9 +130,6 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, "scrolled": true }, "outputs": [ @@ -186,11 +150,7 @@ { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -209,11 +169,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -232,11 +188,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -257,11 +209,7 @@ { "cell_type": "code", "execution_count": 7, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -282,11 +230,7 @@ { "cell_type": "code", "execution_count": 8, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -305,10 +249,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "If a square matrix (2-dimensional array) is given,\n", "then it is considered to be a symmetric two-player game.\n", @@ -327,9 +268,7 @@ "cell_type": "code", "execution_count": 9, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -341,11 +280,7 @@ { "cell_type": "code", "execution_count": 10, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -364,11 +299,7 @@ { "cell_type": "code", "execution_count": 11, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -389,11 +320,7 @@ { "cell_type": "code", "execution_count": 12, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -413,10 +340,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Another example (\"**Rock-Paper-Scissors**\"):\n", "\n", @@ -433,9 +357,7 @@ "cell_type": "code", "execution_count": 13, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -448,11 +370,7 @@ { "cell_type": "code", "execution_count": 14, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -471,10 +389,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The second is to specify the sizes of the action sets of the players\n", "to create a `NormalFormGame` instance filled with payoff zeros,\n", @@ -494,9 +409,7 @@ "cell_type": "code", "execution_count": 15, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -510,11 +423,7 @@ { "cell_type": "code", "execution_count": 16, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -532,10 +441,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Finally, a `NormalFormGame` instance can be constructed by giving an array of `Player` instances,\n", "as explained in the next section." @@ -543,20 +449,14 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "### Creating a `Player`" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "A `Player` instance is created by passing an array of dimension $N$\n", "that represents the player's payoff function (\"payoff array\").\n", @@ -575,9 +475,7 @@ "cell_type": "code", "execution_count": 17, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -589,10 +487,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Beware that in `payoff_array[h, k]`, `h` refers to the player's own action,\n", "while `k` refers to the opponent player's action." @@ -601,11 +496,7 @@ { "cell_type": "code", "execution_count": 18, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -626,11 +517,7 @@ { "cell_type": "code", "execution_count": 19, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -650,10 +537,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Passing an array of Player instances is the third way to create a `NormalFormGame` instance:" ] @@ -662,9 +546,7 @@ "cell_type": "code", "execution_count": 20, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -674,11 +556,7 @@ { "cell_type": "code", "execution_count": 21, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -696,30 +574,21 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "### More than two players" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `game_theory` module also supports games with more than two players." ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Let us consider the following version of $N$-player **Cournot Game**.\n", "\n", @@ -738,10 +607,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Theoretically, the set of actions, i.e., available quantities, may be\n", "the set of all nonnegative real numbers $\\mathbb{R}_+$\n", @@ -757,9 +623,7 @@ "cell_type": "code", "execution_count": 22, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -804,10 +668,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Here's a simple example with three firms,\n", "marginal cost $20$, and inverse demand function $80 - Q$,\n", @@ -818,9 +679,7 @@ "cell_type": "code", "execution_count": 23, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -834,11 +693,7 @@ { "cell_type": "code", "execution_count": 24, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -860,11 +715,7 @@ { "cell_type": "code", "execution_count": 25, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -886,11 +737,7 @@ { "cell_type": "code", "execution_count": 26, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -909,20 +756,14 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "## Nash Equilibrium" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "A *Nash equilibrium* of a normal form game is a profile of actions\n", "where the action of each player is a best response to the others'." @@ -930,10 +771,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The `Player` object has a method `best_response`.\n", "\n", @@ -944,11 +782,7 @@ { "cell_type": "code", "execution_count": 27, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -967,10 +801,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Player 0's best responses to the opponent's mixed action `[0.5, 0.5]`\n", "(we know they are 0 and 1):" @@ -979,11 +810,7 @@ { "cell_type": "code", "execution_count": 28, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1004,11 +831,7 @@ { "cell_type": "code", "execution_count": 29, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1029,11 +852,7 @@ { "cell_type": "code", "execution_count": 30, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1053,10 +872,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "For this game, we know that `([0.5, 0.5], [0.5, 0.5])` is a (unique) Nash equilibrium." ] @@ -1064,11 +880,7 @@ { "cell_type": "code", "execution_count": 31, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1088,11 +900,7 @@ { "cell_type": "code", "execution_count": 32, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1112,11 +920,7 @@ { "cell_type": "code", "execution_count": 33, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1135,20 +939,14 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "### Finding Nash equilibria" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "There are several algorithms implemented to compute Nash equilibria:\n", "\n", @@ -1158,30 +956,26 @@ " Find one pure-action Nash equilibrium of an $N$-player game (if any).\n", "* Support enumeration \n", " Find all mixed-action Nash equilibria of a two-player nondegenerate game.\n", + "* Vertex enumeration \n", + " Find all mixed-action Nash equilibria of a two-player nondegenerate game.\n", "* Lemke-Howson \n", " Find one mixed-action Nash equilibrium of a two-player game.\n", "* McLennan-Tourky \n", " Find one mixed-action Nash equilibrium of an $N$-player game.\n", "\n", - "For more variety of algorithms, one should look at [Gambit](http://gambit.sourceforge.net)." + "For more variety of algorithms, one should look at [Gambit](http://www.gambit-project.org)." ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "#### Brute force" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "For small games, we can find pure action Nash equilibria by brute force,\n", "by calling the routine [`pure_nash_brute`](http://quanteconpy.readthedocs.io/en/latest/game_theory/pure_nash.html#quantecon.game_theory.pure_nash.pure_nash_brute).\n", @@ -1193,9 +987,7 @@ "cell_type": "code", "execution_count": 34, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -1222,10 +1014,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Matching Pennies:" ] @@ -1233,11 +1022,7 @@ { "cell_type": "code", "execution_count": 35, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1253,10 +1038,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Coordination game:" ] @@ -1264,11 +1046,7 @@ { "cell_type": "code", "execution_count": 36, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1285,10 +1063,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Rock-Paper-Scissors:" ] @@ -1296,11 +1071,7 @@ { "cell_type": "code", "execution_count": 37, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1316,10 +1087,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Battle of the Sexes:" ] @@ -1327,11 +1095,7 @@ { "cell_type": "code", "execution_count": 38, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1348,10 +1112,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Prisoners' Dillema:" ] @@ -1359,11 +1120,7 @@ { "cell_type": "code", "execution_count": 39, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1380,10 +1137,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Cournot game:" ] @@ -1391,11 +1145,7 @@ { "cell_type": "code", "execution_count": 40, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1412,20 +1162,14 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "#### Sequential best response" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In some games, such as \"supermodular games\" and \"potential games\",\n", "the process of sequential best responses converges to a Nash equilibrium." @@ -1433,10 +1177,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Here's a script to find *one* pure Nash equilibrium by sequential best response, if it converges." ] @@ -1445,9 +1186,7 @@ "cell_type": "code", "execution_count": 41, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -1504,10 +1243,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "A Cournot game with linear demand is known to be a potential game,\n", "for which sequential best response converges to a Nash equilibrium.\n", @@ -1519,9 +1255,7 @@ "cell_type": "code", "execution_count": 42, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -1534,11 +1268,7 @@ { "cell_type": "code", "execution_count": 43, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1571,11 +1301,7 @@ { "cell_type": "code", "execution_count": 44, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1617,10 +1343,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The limit action profile is indeed a Nash equilibrium:" ] @@ -1628,11 +1351,7 @@ { "cell_type": "code", "execution_count": 45, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -1651,10 +1370,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In fact, the game has other Nash equilibria\n", "(because of our choice of grid points and parameter values):" @@ -1663,11 +1379,7 @@ { "cell_type": "code", "execution_count": 46, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1684,10 +1396,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Make it bigger:" ] @@ -1696,9 +1405,7 @@ "cell_type": "code", "execution_count": 47, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -1710,11 +1417,7 @@ { "cell_type": "code", "execution_count": 48, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1773,11 +1476,7 @@ { "cell_type": "code", "execution_count": 49, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1831,10 +1530,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Sequential best response does not converge in all games:" ] @@ -1842,11 +1538,7 @@ { "cell_type": "code", "execution_count": 50, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1865,11 +1557,7 @@ { "cell_type": "code", "execution_count": 51, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1895,9 +1583,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "source": [ "#### Support enumeration" @@ -1905,10 +1591,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The routine [`support_enumeration`](http://quanteconpy.readthedocs.io/en/latest/game_theory/support_enumeration.html#quantecon.game_theory.support_enumeration.support_enumeration),\n", "which is for two-player games,\n", @@ -1916,15 +1599,12 @@ "checks whether each pair has a Nash equilibrium (in mixed actions)\n", "by the indifference condition.\n", "(This should thus be used only for small games.)\n", - "For nondegenerate games, this routine returns all Nash equilibria." + "For nondegenerate games, this routine returns all the Nash equilibria." ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Matching Pennies:" ] @@ -1933,9 +1613,6 @@ "cell_type": "code", "execution_count": 52, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, "scrolled": false }, "outputs": [ @@ -1956,10 +1633,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The output list contains a pair of mixed actions as a tuple of two NumPy arrays,\n", "which constitues the unique Nash equilibria of this game." @@ -1967,10 +1641,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Coordination game:" ] @@ -1978,11 +1649,7 @@ { "cell_type": "code", "execution_count": 53, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -2001,11 +1668,7 @@ { "cell_type": "code", "execution_count": 54, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2026,10 +1689,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The output contains three tuples of mixed actions,\n", "where the first two correspond to the two pure action equilibria,\n", @@ -2038,10 +1698,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Rock-Paper-Scissors:" ] @@ -2049,11 +1706,7 @@ { "cell_type": "code", "execution_count": 55, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -2073,11 +1726,7 @@ { "cell_type": "code", "execution_count": 56, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2097,10 +1746,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Consider the $6 \\times 6$ game by\n", "von Stengel (1997), page 12:" @@ -2110,9 +1756,7 @@ "cell_type": "code", "execution_count": 57, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ @@ -2140,11 +1784,7 @@ { "cell_type": "code", "execution_count": 58, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2163,10 +1803,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Note that the $n \\times n$ game where the payoff matrices are given by the identy matrix\n", "has $2^n−1$ equilibria.\n", @@ -2178,10 +1815,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Next, let us study the **All-Pay Acution**,\n", "where, unlike standard auctions,\n", @@ -2197,10 +1831,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Specifically, each of $N$ players simultaneously bids an integer from $\\{0, 1, \\ldots, c\\}$,\n", "where $c$ is the common (integer) bid cap.\n", @@ -2221,10 +1852,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The following is a script to construct a `NormalFormGame` instance\n", "for the All-Pay Auction game,\n", @@ -2236,16 +1864,14 @@ "cell_type": "code", "execution_count": 59, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ "from numba import jit\n", "\n", "\n", - "def all_pay_auction(r, e, N, dissipation=True):\n", + "def all_pay_auction(r, c, N, dissipation=True):\n", " \"\"\"\n", " Create a `NormalFormGame` instance for the symmetric N-player\n", " All-Pay Auction game with common reward `r` and common bid cap `e`.\n", @@ -2255,7 +1881,7 @@ " r : scalar(float)\n", " Common reward value.\n", "\n", - " e : scalar(int)\n", + " c : scalar(int)\n", " Common bid cap.\n", "\n", " N : scalar(int)\n", @@ -2272,7 +1898,7 @@ " NormalFormGame instance representing the All-Pay Auction game.\n", "\n", " \"\"\"\n", - " player = gt.Player(np.empty((e+1,)*N))\n", + " player = gt.Player(np.empty((c+1,)*N))\n", " populate_APA_payoff_array(r, dissipation, player.payoff_array)\n", " return gt.NormalFormGame((player,)*N)\n", "\n", @@ -2324,10 +1950,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Consider the two-player case with the following parameter values:" ] @@ -2336,14 +1959,12 @@ "cell_type": "code", "execution_count": 60, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ "N = 2\n", - "e = 5 # odd\n", + "c = 5 # odd\n", "r = 8" ] }, @@ -2351,9 +1972,6 @@ "cell_type": "code", "execution_count": 61, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, "scrolled": true }, "outputs": [ @@ -2372,16 +1990,13 @@ } ], "source": [ - "g_APA_odd = all_pay_auction(r, e, N)\n", + "g_APA_odd = all_pay_auction(r, c, N)\n", "print(g_APA_odd)" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Clearly, this game has no pure-action Nash equilibrium.\n", "Indeed:" @@ -2390,11 +2005,7 @@ { "cell_type": "code", "execution_count": 62, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2413,13 +2024,10 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "As pointed out by Dechenaux et al. (2006),\n", - "there are three Nash equilibria when the bid cap `e` is odd\n", + "there are three Nash equilibria when the bid cap `c` is odd\n", "(so that there are an even number of actions for each player):" ] }, @@ -2427,9 +2035,6 @@ "cell_type": "code", "execution_count": 63, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, "scrolled": true }, "outputs": [ @@ -2455,10 +2060,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "In addition to a symmetric, totally mixed equilibrium (the third),\n", "there are two asymmetric, \"alternating\" equilibria (the first and the second)." @@ -2466,23 +2068,16 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ - "If `e` is even, there is a unique equilibrium, which is symmetric and totally mixed.\n", + "If `c` is even, there is a unique equilibrium, which is symmetric and totally mixed.\n", "For example:" ] }, { "cell_type": "code", "execution_count": 64, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "metadata": {}, "outputs": [ { "data": { @@ -2497,27 +2092,140 @@ } ], "source": [ - "e = 6 # even\n", - "g_APA_even = all_pay_auction(r, e, N)\n", + "c = 6 # even\n", + "g_APA_even = all_pay_auction(r, c, N)\n", "gt.support_enumeration(g_APA_even)" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, + "source": [ + "#### Vertex enumeration" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The routine [`vertex_enumeration`](http://quanteconpy.readthedocs.io/en/latest/game_theory/vertex_enumeration.html#quantecon.game_theory.vertex_enumeration.vertex_enumeration)\n", + "computes mixed-action Nash equilibria of a 2-player normal form game\n", + "by enumeration and matching of vertices of the best response polytopes.\n", + "For a non-degenerate game input, these are all the Nash equilibria.\n", + "\n", + "Internally,\n", + "[`scipy.spatial.ConvexHull`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.ConvexHull.html)\n", + "is used to compute vertex enumeration of the best response polytopes,\n", + "or equivalently, facet enumeration of their polar polytopes.\n", + "Then, for each vertex of the polytope for player 0,\n", + "vertices of the polytope for player 1 are searched to find a completely labeled pair." + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(array([ 0.5, 0.5]), array([ 0.5, 0.5]))]" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gt.vertex_enumeration(g_MP)" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "75" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(gt.support_enumeration(g_vonStengel))" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(array([ 0. , 0.25, 0. , 0.25, 0. , 0.5 ]),\n", + " array([ 0.5 , 0. , 0.25, 0. , 0.25, 0. ])),\n", + " (array([ 0.5 , 0. , 0.25, 0. , 0.25, 0. ]),\n", + " array([ 0. , 0.25, 0. , 0.25, 0. , 0.5 ])),\n", + " (array([ 0.125, 0.125, 0.125, 0.125, 0.125, 0.375]),\n", + " array([ 0.125, 0.125, 0.125, 0.125, 0.125, 0.375]))]" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gt.vertex_enumeration(g_APA_odd)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(array([ 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.25 ]),\n", + " array([ 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.25 ]))]" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gt.vertex_enumeration(g_APA_even)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`support_enumeration` and `vertex_enumeration` the same functionality\n", + "(i.e., enumeration of Nash equilibria of a two-player game),\n", + "but the latter seems to run faster than the former." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ "#### Lemke-Howson" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The routine [`lemke_howson`](http://quanteconpy.readthedocs.io/en/latest/game_theory/lemke_howson.html#quantecon.game_theory.lemke_howson.lemke_howson)\n", "implements the Lemke-Howson algorithm (Lemke and Howson 1964),\n", @@ -2527,21 +2235,15 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Matching Pennies:" ] }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 69, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, "scrolled": true }, "outputs": [ @@ -2551,7 +2253,7 @@ "(array([ 0.5, 0.5]), array([ 0.5, 0.5]))" ] }, - "execution_count": 65, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -2562,22 +2264,15 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Coordination game:" ] }, { "cell_type": "code", - "execution_count": 66, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 70, + "metadata": {}, "outputs": [ { "data": { @@ -2585,7 +2280,7 @@ "(array([ 1., 0.]), array([ 1., 0.]))" ] }, - "execution_count": 66, + "execution_count": 70, "metadata": {}, "output_type": "execute_result" } @@ -2596,10 +2291,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The initial pivot can be specified by `init_pivot`,\n", "which should be an integer $k$ such that $0 \\leq k \\leq n_1 + n_2 - 1$ (default to `0`),\n", @@ -2609,12 +2301,8 @@ }, { "cell_type": "code", - "execution_count": 67, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 71, + "metadata": {}, "outputs": [ { "data": { @@ -2622,7 +2310,7 @@ "(array([ 0., 1.]), array([ 0., 1.]))" ] }, - "execution_count": 67, + "execution_count": 71, "metadata": {}, "output_type": "execute_result" } @@ -2633,22 +2321,15 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "All-Pay Auction:" ] }, { "cell_type": "code", - "execution_count": 68, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 72, + "metadata": {}, "outputs": [ { "data": { @@ -2657,7 +2338,7 @@ " array([ 0. , 0.25, 0. , 0.25, 0. , 0.5 ]))" ] }, - "execution_count": 68, + "execution_count": 72, "metadata": {}, "output_type": "execute_result" } @@ -2668,12 +2349,8 @@ }, { "cell_type": "code", - "execution_count": 69, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 73, + "metadata": {}, "outputs": [ { "data": { @@ -2682,7 +2359,7 @@ " array([ 0.5 , 0. , 0.25, 0. , 0.25, 0. ]))" ] }, - "execution_count": 69, + "execution_count": 73, "metadata": {}, "output_type": "execute_result" } @@ -2693,22 +2370,15 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Additional information is returned if the option `full_output` is set `True`:" ] }, { "cell_type": "code", - "execution_count": 70, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 74, + "metadata": {}, "outputs": [ { "data": { @@ -2720,7 +2390,7 @@ " num_iter: 6" ] }, - "execution_count": 70, + "execution_count": 74, "metadata": {}, "output_type": "execute_result" } @@ -2732,10 +2402,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "`lemke_howson` runs fast,\n", "with a reasonable time amount for games with up to several hundreds actions.\n", @@ -2746,28 +2413,22 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 75, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ "N = 2\n", - "e = 200 # 201 actions\n", + "c = 200 # 201 actions\n", "r = 500\n", - "g_APA200 = all_pay_auction(r, e, N)" + "g_APA200 = all_pay_auction(r, c, N)" ] }, { "cell_type": "code", - "execution_count": 72, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 76, + "metadata": {}, "outputs": [ { "data": { @@ -2824,7 +2485,7 @@ " 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002, 0.6 ]))" ] }, - "execution_count": 72, + "execution_count": 76, "metadata": {}, "output_type": "execute_result" } @@ -2836,9 +2497,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "source": [ "#### McLennan-Tourky" @@ -2846,10 +2505,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "The routine [`mclennan_tourky`](http://quanteconpy.readthedocs.io/en/latest/game_theory/mclennan_tourky.html#quantecon.game_theory.mclennan_tourky.mclennan_tourky)\n", "computes one approximate Nash equilibrium of an $N$-player normal form game\n", @@ -2858,48 +2514,36 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Consider the symmetric All-Pay Auction with full dissipation as above, but this time with three players:" ] }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 77, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [ "N = 3\n", "r = 16\n", - "e = 5\n", - "g_APA3 = all_pay_auction(r, e, N)" + "c = 5\n", + "g_APA3 = all_pay_auction(r, c, N)" ] }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Run `mclennan_tourky`:" ] }, { "cell_type": "code", - "execution_count": 74, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 78, + "metadata": {}, "outputs": [ { "data": { @@ -2912,7 +2556,7 @@ " 0.44100792]))" ] }, - "execution_count": 74, + "execution_count": 78, "metadata": {}, "output_type": "execute_result" } @@ -2924,10 +2568,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "This output is an $\\varepsilon$-Nash equilibrium of the game,\n", "which is a profile of mixed actions $(x^*_0, \\ldots, x^*_{N-1})$ such that\n", @@ -2937,12 +2578,8 @@ }, { "cell_type": "code", - "execution_count": 75, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 79, + "metadata": {}, "outputs": [ { "data": { @@ -2950,7 +2587,7 @@ "True" ] }, - "execution_count": 75, + "execution_count": 79, "metadata": {}, "output_type": "execute_result" } @@ -2961,12 +2598,8 @@ }, { "cell_type": "code", - "execution_count": 76, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 80, + "metadata": {}, "outputs": [ { "data": { @@ -2979,7 +2612,7 @@ " 0.44097575]))" ] }, - "execution_count": 76, + "execution_count": 80, "metadata": {}, "output_type": "execute_result" } @@ -2992,12 +2625,8 @@ }, { "cell_type": "code", - "execution_count": 77, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 81, + "metadata": {}, "outputs": [ { "data": { @@ -3005,7 +2634,7 @@ "True" ] }, - "execution_count": 77, + "execution_count": 81, "metadata": {}, "output_type": "execute_result" } @@ -3016,21 +2645,15 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "Additional information is returned by setting the `full_output` option to `True`:" ] }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 82, "metadata": { - "collapsed": false, - "deletable": true, - "editable": true, "scrolled": true }, "outputs": [ @@ -3048,7 +2671,7 @@ " num_iter: 127" ] }, - "execution_count": 78, + "execution_count": 82, "metadata": {}, "output_type": "execute_result" } @@ -3060,10 +2683,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "For this game, `mclennan_tourky` returned a symmetric, totally mixed action profile\n", "(cf. Rapoport and Amaldoss 2004)\n", @@ -3074,12 +2694,8 @@ }, { "cell_type": "code", - "execution_count": 79, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 83, + "metadata": {}, "outputs": [ { "data": { @@ -3090,7 +2706,7 @@ " 0.73324079]))" ] }, - "execution_count": 79, + "execution_count": 83, "metadata": {}, "output_type": "execute_result" } @@ -3104,10 +2720,7 @@ }, { "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, + "metadata": {}, "source": [ "We obtained an asymetric \"alternating\" mixed action profile.\n", "While this is just an approximate Nash equilibrium,\n", @@ -3131,12 +2744,8 @@ }, { "cell_type": "code", - "execution_count": 80, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 84, + "metadata": {}, "outputs": [ { "data": { @@ -3146,7 +2755,7 @@ " [0, 0.14433756729740646, 0, 0.12292367461501794, 0, 0.7327387580875756])" ] }, - "execution_count": 80, + "execution_count": 84, "metadata": {}, "output_type": "execute_result" } @@ -3166,12 +2775,8 @@ }, { "cell_type": "code", - "execution_count": 81, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, + "execution_count": 85, + "metadata": {}, "outputs": [ { "data": { @@ -3179,7 +2784,7 @@ "True" ] }, - "execution_count": 81, + "execution_count": 85, "metadata": {}, "output_type": "execute_result" } @@ -3191,9 +2796,7 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "source": [ "## References\n", @@ -3218,7 +2821,7 @@ " \"[New Lower Bounds for the Number of Equilibria in Bimatrix Games](http://www.maths.lse.ac.uk/personal/stengel/TEXTE/264.pdf).\"\n", "\n", "* B. von Stengel (2007),\n", - " \"[Equilibrium Computation for Two-Player Games in Strategic and Extensive Form](http://www.maths.lse.ac.uk/personal/stengel/TEXTE/nashsurvey.pdf),\"\n", + " \"[Equilibrium Computation for Two-Player Games in Strategic and Extensive Form](http://www.maths.lse.ac.uk/personal/stengel/TEXTE/agt-stengel.pdf),\"\n", " Chapter 3, N. Nisan, T. Roughgarden, E. Tardos, and V. Vazirani eds., Algorithmic Game Theory." ] }, @@ -3226,9 +2829,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "collapsed": true, - "deletable": true, - "editable": true + "collapsed": true }, "outputs": [], "source": [] @@ -3251,9 +2852,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.0" + "version": "3.6.1" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 }