{"id":1376,"date":"2016-10-08T13:39:58","date_gmt":"2016-10-08T18:39:58","guid":{"rendered":"http:\/\/www.laurentlessard.com\/bookproofs\/?p=1376"},"modified":"2018-10-29T01:35:40","modified_gmt":"2018-10-29T06:35:40","slug":"non-intersecting-chessboard-paths","status":"publish","type":"post","link":"https:\/\/laurentlessard.com\/bookproofs\/non-intersecting-chessboard-paths\/","title":{"rendered":"Non-intersecting chessboard paths"},"content":{"rendered":"<p>This <a href=\"http:\/\/fivethirtyeight.com\/features\/how-about-a-nice-game-of-chess\/\">Riddler classic puzzle<\/a> is about finding non-intersecting paths on a chessboard:<\/p>\n<blockquote><p>\nFirst, how long is the longest path a knight can travel on a standard 8-by-8 board without letting the path intersect itself?<\/p>\n<p>Second, there are unorthodox chess pieces that don\u2019t exist in the standard game, which are known as fairy chess pieces. What are the longest nonintersecting paths that can be taken by the camel (which moves like a knight, except 3 squares by 1 square), the zebra (3 by 2), and the giraffe (4 by 1)?\n<\/p><\/blockquote>\n<p>This is a very challenging problem, and there doesn&#8217;t appear to be any way to solve it via some clever observation or simplification. Of course, we can try to come up with ever longer tours by hand, but we&#8217;ll never know for sure that we have found the longest one.<\/p>\n<p>Much like the recent <a href=\"https:\/\/laurentlessard.com\/bookproofs\/pokemon-go-efficiency\/\">Pokemon Go problem<\/a>, we must resort to computational means to obtain a solution. In this case, however, the problem is &#8220;small enough&#8221; that we can find exact solutions!<\/p>\n<p>Here are some optimal tours:<br \/>\n<a href=\"javascript:Solution('soln_knight_tour2','toggle_knight_tour2')\" id=\"toggle_knight_tour2\">[Show Solution]<\/a><\/p>\n<div id=\"soln_knight_tour2\" style=\"display: none\">\n<p>Here are optimal-length knight paths computed for various board sizes:<br \/>\n<a href=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_knight_paths.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_knight_paths.png\" alt=\"nonintersecting_knight_paths\" width=\"800\" height=\"800\" class=\"aligncenter size-full wp-image-1403\" srcset=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_knight_paths.png 800w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_knight_paths-150x150.png 150w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_knight_paths-300x300.png 300w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_knight_paths-768x768.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><br \/>\nOf course, we aren&#8217;t restricted to square boards. It&#8217;s just as easy to compute for example a max-length knight path on a 12&#215;4 board:<br \/>\n<a href=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_rect_path.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_rect_path.png\" alt=\"nonintersecting_rect_path\" width=\"800\" height=\"300\" class=\"aligncenter size-full wp-image-1405\" srcset=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_rect_path.png 800w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_rect_path-300x113.png 300w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_rect_path-768x288.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><br \/>\nFor the alternate chess pieces mentioned in the problem statement, the code only requires slight modifications; i.e. there are more ways for paths to cross when a giraffe moves vs when a knight moves. But otherwise, the structure of the optimization problem is identical. Here are some optimal-length paths for the four different pieces:<br \/>\n<a href=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_fairy_paths.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_fairy_paths.png\" alt=\"nonintersecting_fairy_paths\" width=\"800\" height=\"800\" class=\"aligncenter size-full wp-image-1401\" srcset=\"https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_fairy_paths.png 800w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_fairy_paths-150x150.png 150w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_fairy_paths-300x300.png 300w, https:\/\/laurentlessard.com\/bookproofs\/wp-content\/uploads\/2016\/10\/nonintersecting_fairy_paths-768x768.png 768w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><br \/>\nFor the camel path, we can take advantage of the fact that the camel always remains on squares of the same color, so we are effectively solving the problem on a board with half as many squares! As we can see, there are no patterns in the solutions; this is truly a difficult problem and without powerful computational tools, we would be hard pressed to find these solutions by hand. In the next section, I go into detail about how I solved the problem and I also include my code if you&#8217;re interested in solving it yourself!\n<\/div>\n<p>If you&#8217;re interested in the details of how I found my solutions, read on:<br \/>\n<a href=\"javascript:Solution('soln_knight_tour','toggle_knight_tour')\" id=\"toggle_knight_tour\">[Show Solution]<\/a><\/p>\n<div id=\"soln_knight_tour\" style=\"display: none\">\n<p>Even though we&#8217;re resorting to a numerical solution, we must still be careful about how we proceed. There is an astronomical number of possible paths on a chessboard, so simply enumerating and checking each path is out of the question! Instead, we&#8217;ll think about the problem as a visiting nodes on a graph. Here, each node is a cell and edges connect pairs of cells between which a knight can move.<\/p>\n<p>Let&#8217;s define the following matrices:<\/p>\n<ul>\n<li> <strong>Adjacency matrix:<\/strong> Suppose there are $N$ total cells and we enumerate them $1,2,\\dots,N$. $A \\in \\{0,1\\}^{N\\times N}$ encodes which cells are reachable from which other cells. $A_{ij} = 1$ if you can move from cell $i$ to cell $j$.\n<li> <strong>Incidence matrix:<\/strong> Suppose there are $M$ total edges (nonzero entries in $A$) and we enumerate them $1,2,\\dots,M$. $B \\in \\{0,1\\}^{N\\times M}$ encodes which cells are connected by each edge. $B_{ij} = 1$ if edge $j$ involves cell $i$.\n<li> <strong>Conflict matrix:<\/strong> The matrix $C\\in\\{0,1\\}^{M\\times M}$ indicates which edges cross. $C_{ij} = 1$ if edges $i$ and $j$, excluding the case where the edges share one cell in common.\n<\/ul>\n<p>It&#8217;s a bit tedious to figure out what $A$, $B$, and $C$ are, but it&#8217;s relatively straightforward to do in code by looping through all nodes or edges as necessary. We now define the following variables for our optimization model:<br \/>\n\\begin{align*}<br \/>\nx_1,\\dots,x_M &#038;: \\text{ variables indicating which edges are used} \\\\<br \/>\nz_1,\\dots,z_N &#038;: \\text{ variables indicating which cells are used} \\\\<br \/>\nw_1,\\dots,w_N &#038;: \\text{ variables indicating endpoint cells}<br \/>\n\\end{align*}We then have three main constraints:<br \/>\n\\begin{align*}<br \/>\n\\sum_{i=1}^N w_i &#038;\\le 2 &#038; &#038; \\text{(we have at most two endpoints)}\\\\<br \/>\nB x &#038;= 2z-w &#038; &#038; \\text{(two edges per cell, one per endpoint)}\\\\<br \/>\nC x &#038;\\le H(1-x) &#038; &#038; \\text{(no self-intersecting paths)}<br \/>\n\\end{align*}<br \/>\nIn the last constraint, $H$ is a constant that upper-bounds the number of paths that can intersect any given path. Generally, we can set $H$ to be equal to the maximum row sum of $C$. In the case of a knight tour, $H = 9$. This is an example of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Big_M_method#Other_usage\">M-trick<\/a> in integer programming.<\/p>\n<p>Of course, our goal here is to maximize $\\sum_{i=1}^M x_i$, the total length of the path. As formulated, this is an <a href=\"https:\/\/en.wikipedia.org\/wiki\/Integer_programming\">integer program<\/a> that is a version of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Travelling_salesman_problem\">Traveling Salesman Problem<\/a> (TSP) with additional constraints. Unfortunately, the formulation above doesn&#8217;t always give a valid solution, since it doesn&#8217;t explicitly forbid disjoint paths, e.g. paths with separate closed loops. These are known as <em>subtours<\/em>.<\/p>\n<p>To get rid of subtours, I used a standard heuristic:<\/p>\n<ol>\n<li> Solve the problem as-is\n<li> See if the solution has any subtours. If not, we&#8217;re done!\n<li> If $\\{x_{k_1},\\dots,x_{k_\\ell}\\}$ is a subtour, add the constraint: $\\sum_{i=1}^\\ell x_{k_i} \\le \\ell-1$ to explicitly forbid this subtour from occurring in the solution.\n<li> Re-solve the problem and return to step 2.\n<\/ol>\n<p>This heuristic always eventually yields an optimal solution, but it may take awhile. For this problem, I only had to re-solve about 10 times before finding a subtour-free (and hence optimal) path.<\/p>\n<p>I used <a href=\"http:\/\/julialang.org\/\">IJulia<\/a>, <a href=\"https:\/\/jump.readthedocs.io\/en\/latest\/\" class=\"broken_link\">JuMP<\/a>, and <a href=\"http:\/\/www.gurobi.com\/\" class=\"broken_link\">Gurobi<\/a> to solve the integer programs, and on my laptop it took about 30 seconds for 6&#215;6, 1 minute for 7&#215;7 and 5-10 minutes for 8&#215;8. These times only account for a single solve. Subtour eliminations required up to 10 solves per case to find an optimal path.<\/p>\n<p>If you&#8217;re interested in seeing my code in full detail, you can view\/download my notebook <a href=\"http:\/\/nbviewer.jupyter.org\/urls\/laurentlessard.com\/bookproofs\/code\/knight_path_general.ipynb\">here<\/a>.<\/p>\n<p>I should also point out that this is a well-studied problem. Some references include: <a href=\"https:\/\/oeis.org\/A003192\">the encyclopedia of integer sequences<\/a>, <a href=\"http:\/\/euler.free.fr\/knight\/index.htm\">non-crossing knight tours<\/a>, and <a href=\"http:\/\/www.mayhematics.com\/t\/2n.htm\">non-intersecting paths<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This Riddler classic puzzle is about finding non-intersecting paths on a chessboard: First, how long is the longest path a knight can travel on a standard 8-by-8 board without letting the path intersect itself? Second, there are unorthodox chess pieces that don\u2019t exist in the standard game, which are known as fairy chess pieces. What &hellip; <a href=\"https:\/\/laurentlessard.com\/bookproofs\/non-intersecting-chessboard-paths\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Non-intersecting chessboard paths&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1403,"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":[30,27,31,26,2,32],"class_list":["post-1376","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-riddler","tag-integer-programming","tag-linear-programming","tag-modeling","tag-optimization","tag-riddler","tag-traveling-salesman"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts\/1376","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=1376"}],"version-history":[{"count":31,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts\/1376\/revisions"}],"predecessor-version":[{"id":2521,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/posts\/1376\/revisions\/2521"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/media\/1403"}],"wp:attachment":[{"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/media?parent=1376"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/categories?post=1376"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/laurentlessard.com\/bookproofs\/wp-json\/wp\/v2\/tags?post=1376"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}