{"id":2404,"date":"2018-08-19T11:57:35","date_gmt":"2018-08-19T16:57:35","guid":{"rendered":"https:\/\/laurentlessard.com\/bookproofs\/?p=2404"},"modified":"2018-08-19T20:50:12","modified_gmt":"2018-08-20T01:50:12","slug":"the-number-line-game","status":"publish","type":"post","link":"https:\/\/laurentlessard.com\/bookproofs\/the-number-line-game\/","title":{"rendered":"The number line game"},"content":{"rendered":"<body><p>This <a href=\"https:\/\/fivethirtyeight.com\/features\/step-1-game-theory-step-2-step-3-profit\/\">Riddler puzzle<\/a> is a game theory problem: how should each player play the game to maximize their own winnings?<\/p>\n<blockquote><p>\nAriel, Beatrice and Cassandra \u2014 three brilliant game theorists \u2014 were bored at a game theory conference (shocking, we know) and devised the following game to pass the time. They drew a number line and placed \\$1 on the 1, \\$2 on the 2, \\$3 on the 3 and so on to \\$10 on the 10.<\/p>\n<p>Each player has a personalized token. They take turns \u2014 Ariel first, Beatrice second and Cassandra third \u2014 placing their tokens on one of the money stacks (only one token is allowed per space). Once the tokens are all placed, each player gets to take every stack that her token is on or is closest to. If a stack is midway between two tokens, the players split that cash.<\/p>\n<p>How will this game play out? How much is it worth to go first?<\/p>\n<p>A grab bag of extra credits: What if the game were played not on a number line but on a clock, with values of \\$1 to \\$12? What if Desdemona, Eleanor and so on joined the original game? What if the tokens could be placed anywhere on the number line, not just the stacks?\n<\/p><\/blockquote>\n<p>Here are the details of how I approached the problem:<br>\n<a href=\"javascript:Solution('soln_number_line_game','toggle_number_line_game')\" id=\"toggle_number_line_game\">[Show Solution]<\/a><\/p>\n<div id=\"soln_number_line_game\" style=\"display: none\">\n<p>This problem is different from previous game theory problems I\u2019ve written about such as <a href=\"https:\/\/laurentlessard.com\/bookproofs\/the-war-game\/\">the war game<\/a> or <a href=\"https:\/\/laurentlessard.com\/bookproofs\/the-dodgeball-duel\/\">the dodgeball duel<\/a>, where all players in the game act simultaneously. In such games, you can assume a strategy for each player, and then look for the strategy that yields a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Nash_equilibrium\">Nash equilibrium<\/a>, which is a set of strategies such that no player has any incentive to change their actions. Sometimes, the optimal strategy is a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Strategy_(game_theory)#Mixed_strategy\">mixed strategy<\/a>, which means it involves randomness. This is the case in rock-paper-scissors, for example, where the Nash-optimal strategy is to choose randomly.<\/p>\n<p>What makes the present problem quite different is that it\u2019s a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Sequential_game\">sequential game<\/a> in which each player gets to see the previous players\u2019 moves when it comes their turn to play. This means that there can be no advantage to playing randomly. The standard way to solve such problems is via backward induction (also known as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dynamic_programming\">dynamic programming<\/a>). I will illustrate the approach for the basic version of the problem: 10 stacks and 3 players. A <em>strategy<\/em> is a set of moves $(a,b,c)$ where $a$ is Ariel\u2019s move, $b$ is Beatrice\u2019s move, and $c$ is Cassandra\u2019s move. We proceed by backward induction  as follows:<\/p>\n<ol>\n<li> Given a strategy $(a,b,c)$, let\u2019s call Ariel\u2019s payout $P_A(a,b,c)$. Similarly, we\u2019ll call Beatrice\u2019s and Cassandra\u2019s payouts $P_B$ and $P_C$, respectively.\n<\/li><li> Imagine it\u2019s Cassandra\u2019s turn. She observes Ariel and Beatrice\u2019s moves $a$ and $b$. For each potential choice of $c$, we can compute Cassandra\u2019s payout $P_C(a,b,c)$ and then select the most profitable choice of $c$. Let\u2019s call Cassandra\u2019s strategy $K_C(a,b)$. Mathematically, we\u2019re defining:<br>\n\\[<br>\nK_C(a,b) = \\arg\\max_{c} P_C(a,b,c)<br>\n\\]\n<\/li><li> Now imagine it\u2019s Beatrice\u2019s turn. She observes Ariel\u2019s move ($a$). She also knows that if she chooses $b$, then Cassandra will follow up with $K_C(a,b)$. So she must choose the best $b$ in anticipation of what Cassandra will do. If we call Beatrice\u2019s strategy $K_B(a)$, then we have:<br>\n\\[<br>\nK_B(a) = \\arg\\max_{b} P_B(a,b,K_C(a,b))<br>\n\\]\n<\/li><li> Finally, imagine it\u2019s Ariel\u2019s turn. Although she\u2019s the first to move, no matter which $a$ she picks, she can be assured Beatrice will choose $b = K_B(a)$ and Cassandra will follow-up with $c = K_C(a,b)$. So Ariel can examine all of her options and predict her payout. Ultimately, her decision will be $K_A$, which is given by:<br>\n\\[<br>\nK_A = \\arg\\max_{a} P_A(a,K_B(a),K_C(a,K_B(a)))<br>\n\\]\n<\/li><\/ol>\n<h3>Computational details<\/h3>\n<p>Writing code to implement the backward induction above was quite a challenge. I will include my finished code later so you can play with it, but for now I\u2019ll just highlight two of the major hurdles I had to overcome.<\/p>\n<ul>\n<li> A naive implementation of the above steps quickly becomes computationally intractable as we make the problem larger. If there are $N$ money stacks and $M$ players, the number of possible strategies is $N(N-1)\\cdots(N-M+1)$, which can be quite large. So if $N=12$ and $M=9$, the $K$ function for the last player will depend on how the first $8$ players moved, and there are about 20 million possibilities there. Things deteriorate rapidly as we further increase $N$ or $M$. I observed that the best move for any player does not depend on the order in which the previous players moved. So for the intent of making the functions $K_A$, $K_B$, etc., we may assume the inputs are sorted. This reduces the number of possible strategies to $\\binom{N}{M}$. So in the example above, the 20 million possibilities reduces to 500, a far more manageable number.\n<\/li><li> The optimal solution may not be unique. At each step, there may be several choices that produce identical payouts for the deciding player. Keeping track of all possibilities is tedious because it means that each $\\arg\\max$ can return many solutions, and each of those must be propagated back through the other functions. I implemented the recursion using lists of strategies, so at every step I was passing around lists of optimal strategies rather than just one strategy.\n<\/li><li> Extensions and bonus questions. After some thought, I was able to write the code in a way that solves the bonus questions with only minor modifications. Writing generic code in terms of $N$ and $M$ allows the easy addition of more stacks or more players. Writing the number line so it wraps around (on a clock) just amounts to redefining the function that computes the payouts for each strategy. Solving the continuous version amounts to adding extra slots in between the stacks and suitably redefining the payout function.\n<\/li><li> Bugs. So many bugs! This was the trickiest piece of code I\u2019ve written in awhile, and tracking down indexing errors in the recursion was a challenge to say the least. I think I got everything working in the end and I\u2019m quite please with it!\n<\/li><\/ul>\n<p>The results from my simulation are in the next section.\n<\/p><\/div>\n<p>And here are the answers:<br>\n<a href=\"javascript:Solution('soln_number_line_game2','toggle_number_line_game2')\" id=\"toggle_number_line_game2\">[Show Solution]<\/a><\/p>\n<div id=\"soln_number_line_game2\" style=\"display: none\">\n<h3>Adding more players<\/h3>\n<p>Let\u2019s call $N$ the number of money stacks and $M$ the number of players. Here is a table showing the case $N=10$ as we add more players.<\/p>\n<table style=\"width:105%;font-size:small;white-space:nowrap\">\n<tr>\n<th width=\"70\">Players<\/th>\n<th>Optimal strategies (number line)<\/th>\n<th>Optimal payouts (in dollars)<\/th>\n<\/tr>\n<tr>\n<td>$2$<\/td>\n<td>$(7,8)$<\/td>\n<td>$(28,27)$<\/td>\n<\/tr>\n<tr>\n<td>$3$<\/td>\n<td>$(5, 9, 8)$<\/td>\n<td>$(21, 19, 15)$<\/td>\n<\/tr>\n<tr>\n<td>$4$<\/td>\n<td>$(7, 4, 9, 10)$<\/td>\n<td>$(17, 15, 13, 10)$<\/td>\n<\/tr>\n<tr>\n<td>$5$<\/td>\n<td>$(4, 6, 8, 10, 9)$<\/td>\n<td>$(12.5, 12, 11.5, 10, 9)$<\/td>\n<\/tr>\n<tr>\n<td>$6$<\/td>\n<td>$(4, 10, 9, 6, 8, 7)$<\/td>\n<td>$(12.5, 10, 9, 8.5, 8, 7)$<\/td>\n<\/tr>\n<tr>\n<td>$7$<\/td>\n<td>$(10, 9, 3, 8, 5, 7, 6)$<br>\n$(10, 9, 3, 8, 7, 5, 6)$<br>\n$(10, 9, 8, 3, 5, 7, 6)$<br>\n$(10, 9, 8, 3, 7, 5, 6)$<\/td>\n<td>$(10, 9, 8, 8, 7, 7, 6)$<\/td>\n<\/tr>\n<tr>\n<td>$8$<\/td>\n<td>$(10, 9, 8, 7, 3, 6, 5, 4)$<br>\n$(10, 9, 8, 7, 6, 3, 5, 4)$<\/td>\n<td>$(10, 9, 8, 7, 6, 6, 5, 4)$<\/td>\n<\/tr>\n<tr>\n<td>$9$<\/td>\n<td>$(10, 9, 8, 7, 6, 5, 4, 2, 3)$<br>\n$(10, 9, 8, 7, 6, 5, 4, 3, 2)$<\/td>\n<td>$(10, 9, 8, 7, 6, 5, 4, 3, 3)$<\/td>\n<\/tr>\n<tr>\n<td>$10$<\/td>\n<td>$(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)$<\/td>\n<td>$(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)$<\/td>\n<\/tr>\n<\/table>\n<p>At the onset, it wasn\u2019t clear whether it would be best to move first in order to stake claim to the best spots or to move later on and have the advantage of playing reactively. As we can see from the table above, the first player always has the highest payout and it gets worse for subsequent players. Some of the rows contain multiple strategies. These are cases with multiple Nash equilibria. All produce identical payoffs.<\/p>\n<p>In the original problem with $M=3$ players, it\u2019s worth \\$21 to go first. Of course, this assumes everybody is playing in a greedy fashion and trying to maximize their own payoffs. If Beatrice and Cassandra conspired to ruin Ariel\u2019s day, they could reduce Ariel\u2019s winnings to \\$5 (by placing tokens at 4 and 6) but they would have to trust each other enough to split their \\$50 winnings evenly after the game is over!<\/p>\n<h3>Playing around the clock<\/h3>\n<p>If we wrap the number line around a clock, the game changes slightly, but the code only requires minor modification. All we need to do is define how payoffs are computed, since the \u201cclosest\u201d token may be either clockwise or counterclockwise from a given stack. Here are the results with $N=12$ as we add more players.<\/p>\n<table style=\"width:110%;font-size:small;white-space:nowrap\">\n<tr>\n<th width=\"70\">Players<\/th>\n<th>Optimal strategies (clock)<\/th>\n<th>Optimal payouts (in dollars)<\/th>\n<\/tr>\n<tr>\n<td>$2$<\/td>\n<td>$(9, 10)$<br>\n$(10, 9)$<\/td>\n<td>$(39, 39)$<\/td>\n<\/tr>\n<tr>\n<td>$3$<\/td>\n<td>$(7, 11, 10)$<\/td>\n<td>$(31.5, 27.5, 19)$<\/td>\n<\/tr>\n<tr>\n<td>$4$<\/td>\n<td>$(6, 9, 12, 11)$<\/td>\n<td>$(23.5, 22, 16.5, 16)$<\/td>\n<\/tr>\n<tr>\n<td>$5$<\/td>\n<td>$(8, 5, 12, 10, 11)$<\/td>\n<td>$(19.5, 18, 15, 14.5, 11)$<\/td>\n<\/tr>\n<tr>\n<td>$6$<\/td>\n<td>$(5, 12, 7, 9, 11, 10)$<br>\n$(12, 5, 7, 9, 11, 10)$<\/td>\n<td>$(15, 15, 14, 13, 11, 10)$<\/td>\n<\/tr>\n<tr>\n<td>$7$<\/td>\n<td>$(12, 9, 7, 11, 4, 10, 6)$<br>\n$(12, 9, 11, 7, 4, 10, 6)$<\/td>\n<td>$(14, 13, 11, 11, 10.5, 10, 8.5)$<\/td>\n<\/tr>\n<tr>\n<td>$8$<\/td>\n<td>$(12, 11, 4, 10, 9, 6, 8, 7)$<\/td>\n<td>$(14, 11, 10.5, 10, 9, 8.5, 8, 7)$<\/td>\n<\/tr>\n<tr>\n<td>$9$<\/td>\n<td>$(12, 11, 10, 9, 8, 3, 5, 7, 6)$<br>\n$(12, 11, 10, 9, 8, 3, 7, 5, 6)$<br>\n$(12, 11, 10, 9, 8, 7, 3, 5, 6)$<\/td>\n<td>$(13, 11, 10, 9, 8, 7, 7, 7, 6)$<\/td>\n<\/tr>\n<tr>\n<td>$10$<\/td>\n<td>$(12, 11, 10, 9, 8, 7, 6, 3, 5, 4)$<br>\n$(12, 11, 10, 9, 8, 7, 6, 5, 3, 4)$<\/td>\n<td>$(13, 11, 10, 9, 8, 7, 6, 5, 5, 4)$<\/td>\n<\/tr>\n<tr>\n<td>$11$<\/td>\n<td>$(12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2)$<\/td>\n<td>$(12.5, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2.5)$<\/td>\n<\/tr>\n<tr>\n<td>$12$<\/td>\n<td>$(12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)$<\/td>\n<td>$(12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)$<\/td>\n<\/tr>\n<\/table>\n<p>As in the number line case, there are many instances with multiple Nash equilibria and each case leads to the same payoff.<\/p>\n<h3>Continuous number line<\/h3>\n<p>I adapted my code to handle the continuous case by adding intermediate slots in between each stack. This allows players to play \u201cin between\u201d the stacks if they so choose. If I return to $N=10$ on the number line add 4 slots between each stack for $M=2$ and $M=3$. Here are the results:<\/p>\n<table style=\"width:110%;font-size:small;white-space:nowrap\">\n<tr>\n<th width=\"70\">Players<\/th>\n<th>Optimal strategies (continuous)<\/th>\n<th>Optimal payouts (in dollars)<\/th>\n<\/tr>\n<tr>\n<td>$2$<\/td>\n<td>$(7.0, 7.2)$<br>\n$(7.0, 7.4)$<br>\n$(7.0, 7.6)$<br>\n$(7.0, 7.8)$<br>\n$(7.0, 8.0)$<br>\n$(7.0, 8.2)$<br>\n$(7.0, 8.4)$<br>\n$(7.0, 8.6)$<br>\n$(7.0, 8.8)$<\/td>\n<td>$(28, 27)$<\/td>\n<\/tr>\n<tr>\n<td>$3$<\/td>\n<td>$(5.0, 9.0, 7.2)$<br>\n$(5.0, 9.0, 7.4)$<br>\n$(5.0, 9.0, 7.6)$<br>\n$(5.0, 9.0, 7.8)$<br>\n$(5.0, 9.0, 8.0)$<br>\n$(5.0, 9.0, 8.2)$<br>\n$(5.0, 9.0, 8.4)$<br>\n$(5.0, 9.0, 8.6)$<br>\n$(5.0, 9.0, 8.8)$<\/td>\n<td>$(21, 19, 15)$<\/td>\n<\/tr>\n<\/table>\n<p>Here it\u2019s clear what\u2019s going on; given the option, the first players do not choose to deviate. Ultimately, the last player has freedom to move their token in the range $7 \\lt c \\lt 9$ and the payoff doesn\u2019t change, and it matches the solution in the integer case (where $c=8$ is optimal). So at least in these cases, making the problem continuous doesn\u2019t change a thing.<\/p>\n<p>This isn\u2019t always true. The solution gets more complex if we examine the case $M=4$. Here, I tried solving the problem with different discretizations and I found the following:<\/p>\n<table style=\"width:110%;font-size:small;white-space:nowrap\">\n<tr>\n<th width=\"70\">Players<\/th>\n<th width=\"320\">Optimal strategies (continuous)<\/th>\n<th>Optimal payouts (in dollars)<\/th>\n<\/tr>\n<tr>\n<td>$4$<\/td>\n<td>Steps of $0.50$: $(9.00, 3.50, 6.50, 7.50)$<br>\nSteps of $0.25$: $(9.00, 3.25, 6.75, 7.25)$<br>\nSteps of $0.20$: $(9.00, 3.20, 6.80, 7.20)$<br>\nSteps of $0.10$: $(9.00, 3.10, 6.90, 7.10)$<\/td>\n<td>$(19, 12.5, 12, 11.5)$<\/td>\n<\/tr>\n<\/table>\n<p>This case highlights when using a discretization breaks down. We would never expect any stacks to be evenly split in the continuous case because you can always nudge your token a little bit in order to be a little closer to either stack and win it all. It also appears that as we reduce the discretization to $\\epsilon$, the unique optimal strategy is $(9, 3+\\epsilon, 7-\\epsilon, 7+\\epsilon)$. This solution is an artifact of our discretization. Indeed, the last player could do better by picking $7+\\tfrac{1}{2}\\epsilon$.<\/p>\n<p>One way around this would be to give each successive player a finer discretization to choose from. This would prevent the case above from occurring. I didn\u2019t code this up so I didn\u2019t verify that the Nash-optimal solution for the discrete case is the same in the continuous case. Future work!<\/p>\n<h3>My code<\/h3>\n<p>I wrote my code in <a href=\"https:\/\/julialang.org\/\">Julia<\/a> (version 0.6.2.1). For those that don\u2019t know about Julia, it\u2019s a fast language for scientific computing that is syntactically similar to Matlab and Python. If you are interested in seeing my code, <a href=\"http:\/\/nbviewer.jupyter.org\/urls\/laurentlessard.com\/bookproofs\/code\/numberline_game.ipynb\">here is my Jupyter notebook<\/a>.<\/p>\n<\/div>\n<\/body>","protected":false},"excerpt":{"rendered":"<p>This Riddler puzzle is a game theory problem: how should each player play the game to maximize their own winnings? Ariel, Beatrice and Cassandra \u2014 three brilliant game theorists \u2014 were bored at a game theory conference (shocking, we know) and devised the following game to pass the time. They drew a number line and &hellip; <a href=\"https:\/\/laurentlessard.com\/bookproofs\/the-number-line-game\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;The number line game&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[7],"tags":[37,16,33,15,2],"class_list":["post-2404","post","type-post","status-publish","format-standard","hentry","category-riddler","tag-coding","tag-dynamic-programming","tag-game-theory","tag-recursion","tag-riddler"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts\/2404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/comments?post=2404"}],"version-history":[{"count":12,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts\/2404\/revisions"}],"predecessor-version":[{"id":2417,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts\/2404\/revisions\/2417"}],"wp:attachment":[{"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/media?parent=2404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/categories?post=2404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/tags?post=2404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}