{"id":2558,"date":"2017-04-20T14:36:14","date_gmt":"2017-04-20T18:36:14","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=2558"},"modified":"2019-11-01T17:08:44","modified_gmt":"2019-11-01T21:08:44","slug":"the-eight-queens-problem","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2017\/04\/20\/the-eight-queens-problem\/","title":{"rendered":"The Eight Queens Problem"},"content":{"rendered":"<div class=\"content\"><p>Today I want to tackle a classic algorithm puzzle known as the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Eight_queens_puzzle\"><i>Eight Queens Problem<\/i><\/a>. In this problem, your task is to arrange eight queens on a chessboard so that none of the queens is attacking any of the others. Here is one solution.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/sample-solution-8.png\" alt=\"\"> <\/p><p>The problem is often restated as the <i>N Queens Problem<\/i>, which is placing N queens on an N-by-N board.<\/p><p>This is more of a general algorithm topic than an image processing topic, although some of the concepts and MATLAB techniques that I show might be useful to people doing image processing work. For some reason, this problem has been on my mind recently, so I decided to play with it a bit in MATLAB. I ended up with both a working algorithm and an interesting visualization. Here is the result for a 6x6 chessboard.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/queen-solver-animation-6.gif\" alt=\"\"> <\/p><p>Solving the eight queens problem was the first \"real\" and nontrivial program that I can recall writing. I wrote it in Basic for a math class project sometime around 1981. My school didn't actually have a computer at that point; I used a teletype terminal (no monitor!) and a dial-up modem to communicate with the county school system's mainframe, which was located some miles away. As I recall, the program used a pure brute-force solution, generating boards randomly and testing each one to see if it was a valid solution. I knew almost nothing about algorithms then.<\/p><p>When I revisited the problem this week, I used a <i>recursive divide-and-conquer technique with backtracking<\/i>. I'll explain that in two parts, starting with the <i>recursive divide-and-conquer<\/i> part. The most famous algorithm in signal processing, the fast Fourier transform (FFT) is based on this idea. The discrete Fourier transform of an $N$-point sequence can be written in terms of the discrete Fourier transforms of two different subsets of the original sequence.<\/p><p>Here is one way to use divide-and-conquer on the N queens problem. We'll write a routine that places N queens on an N-column board in two steps:<\/p><p>A. Place one queen on a safe square somewhere on the first column of the board.<\/p><p>B. Call the routine recursively to place N-1 queens on an (N-1)-column board.<\/p><p>The <i>backtracking<\/i> part is necessary because, unlike when computing the FFT, one of the substeps A or B might fail.<\/p><p>If step B fails, then we <i>backtrack<\/i>. That is, we undo step A, find a different safe square on the first column of the board, and then do the recursive step B call again. At any time, if there are no remaining safe squares on the first column to try, then the solution attempt has failed and the routine returns.<\/p><p>Here's some MATLAB code to implement this idea.<\/p><pre>function [board,succeeded] = placeQueens(board,col)<\/pre><pre>N = size(board,1);\r\nif col &gt; N\r\n    % There are no columns left. All the queens\r\n    % have been placed. Return with success.\r\n    succeeded = true;\r\n    return\r\nend<\/pre><pre>safe = false(1,N);\r\nfor row = 1:N\r\n    safe(row) = isSafe(board,row,col);\r\nend<\/pre><pre>if ~any(safe)\r\n    % There are no safe squares on this column.\r\n    % Return with failure.\r\n    succeeded = false;\r\n    return\r\nend<\/pre><pre>for row = 1:N\r\n    if safe(row)\r\n        board(row,col) = 1;\r\n        [board,succeeded] = placeQueens(board,col+1);\r\n        if succeeded\r\n            return\r\n        else\r\n            % Backtrack. Undo the placement of the queen\r\n            % on this column and keep looking.\r\n            board(row,col) = 0;\r\n        end\r\n    end\r\nend<\/pre><pre>% If we get here, we have checked every row on this column\r\n% without succeeding. Return with failure.\r\nsucceeded = false;<\/pre><p>While I was generating the animations for boards of different sizes, two things caught my eye. First, there's no solution for a 6x6 board that has a queen in any corner. Look at the animated solution above and see if you can convince yourself about that.<\/p><p>Second, I noticed that a solution for the 5x5 board can be found without any backtracking. Check out the animation:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/queen-solver-animation-5.gif\" alt=\"\"> <\/p><p>Next time, I'll write about the graphics programming and GIF and video file writing I did to do the algorithm visualization.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_626d026da19a4af1863559bea472bca6() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='626d026da19a4af1863559bea472bca6 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 626d026da19a4af1863559bea472bca6';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2017 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_626d026da19a4af1863559bea472bca6()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2017a<br><\/p><\/div><!--\r\n626d026da19a4af1863559bea472bca6 ##### SOURCE BEGIN #####\r\n%%\r\n% Today I want to tackle a classic algorithm puzzle known as the \r\n% <https:\/\/en.wikipedia.org\/wiki\/Eight_queens_puzzle _Eight Queens\r\n% Problem_>. In this problem, your task is to arrange eight queens on a\r\n% chessboard so that none of the queens is attacking any of the others.\r\n% Here is one solution.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/sample-solution-8.png>>\r\n%\r\n% The problem is often restated as the _N Queens Problem_, which is placing\r\n% N queens on an N-by-N board.\r\n%\r\n% This is more of a general algorithm topic than an image processing topic,\r\n% although some of the concepts and MATLAB techniques that I show might be\r\n% useful to people doing image processing work. For some reason, this\r\n% problem has been on my mind recently, so I decided to play with it a bit\r\n% in MATLAB. I ended up with both a working algorithm and an interesting\r\n% visualization. Here is the result for a 6x6 chessboard.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/queen-solver-animation-6.gif>>\r\n%\r\n% Solving the eight queens problem was the first \"real\" and nontrivial\r\n% program that I can recall writing. I wrote it in Basic for a math class\r\n% project sometime around 1981. My school didn't actually have a computer\r\n% at that point; I used a teletype terminal (no monitor!) and a dial-up\r\n% modem to communicate with the county school system's mainframe, which was\r\n% located some miles away. As I recall, the program used a pure brute-force\r\n% solution, generating boards randomly and testing each one to see if it\r\n% was a valid solution. I knew almost nothing about algorithms then.\r\n%\r\n% When I revisited the problem this week, I used a _recursive\r\n% divide-and-conquer technique with backtracking_. I'll explain that in two\r\n% parts, starting with the _recursive divide-and-conquer_ part. The most\r\n% famous algorithm in signal processing, the fast Fourier transform (FFT)\r\n% is based on this idea. The discrete Fourier transform of an $N$-point\r\n% sequence can be written in terms of the discrete Fourier transforms of\r\n% two different subsets of the original sequence.\r\n%\r\n% Here is one way to use divide-and-conquer on the N queens problem. We'll\r\n% write a routine that places N queens on an N-column board in two steps:\r\n%\r\n% A. Place one queen on a safe square somewhere on the first column\r\n% of the board.\r\n%\r\n% B. Call the routine recursively to place N-1 queens on an (N-1)-column\r\n% board.\r\n%\r\n% The _backtracking_ part is necessary because, unlike when computing the\r\n% FFT, one of the substeps A or B might fail.\r\n%\r\n% If step B fails, then we _backtrack_. That is, we undo step A, find a\r\n% different safe square on the first column of the board, and then do the\r\n% recursive step B call again. At any time, if there are no remaining safe\r\n% squares on the first column to try, then the solution attempt has failed\r\n% and the routine returns.\r\n%\r\n% Here's some MATLAB code to implement this idea.\r\n%\r\n%  function [board,succeeded] = placeQueens(board,col)\r\n%  \r\n%  N = size(board,1);\r\n%  if col > N\r\n%      % There are no columns left. All the queens\r\n%      % have been placed. Return with success.\r\n%      succeeded = true;\r\n%      return\r\n%  end\r\n%  \r\n%  safe = false(1,N);\r\n%  for row = 1:N\r\n%      safe(row) = isSafe(board,row,col);\r\n%  end\r\n%  \r\n%  if ~any(safe)\r\n%      % There are no safe squares on this column.\r\n%      % Return with failure.\r\n%      succeeded = false;\r\n%      return\r\n%  end\r\n%  \r\n%  for row = 1:N\r\n%      if safe(row)\r\n%          board(row,col) = 1;\r\n%          [board,succeeded] = placeQueens(board,col+1);\r\n%          if succeeded\r\n%              return\r\n%          else\r\n%              % Backtrack. Undo the placement of the queen\r\n%              % on this column and keep looking.\r\n%              board(row,col) = 0;\r\n%          end\r\n%      end\r\n%  end\r\n%\r\n%  % If we get here, we have checked every row on this column\r\n%  % without succeeding. Return with failure.\r\n%  succeeded = false;\r\n%\r\n% While I was generating the animations for boards of different sizes, two\r\n% things caught my eye. First, there's no solution for a 6x6 board that has\r\n% a queen in any corner. Look at the animated solution above and see if you\r\n% can convince yourself about that.\r\n%\r\n% Second, I noticed that a solution for the 5x5 board can be found without\r\n% any backtracking. Check out the animation:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/queen-solver-animation-5.gif>>\r\n%\r\n% Next time, I'll write about the graphics programming and GIF and video\r\n% file writing I did to do the algorithm visualization.\r\n##### SOURCE END ##### 626d026da19a4af1863559bea472bca6\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/sample-solution-8.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><p>Today I want to tackle a classic algorithm puzzle known as the Eight Queens Problem. In this problem, your task is to arrange eight queens on a chessboard so that none of the queens is attacking any... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2017\/04\/20\/the-eight-queens-problem\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":2552,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[102,190],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2558"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=2558"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2558\/revisions"}],"predecessor-version":[{"id":2559,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/2558\/revisions\/2559"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/2552"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=2558"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=2558"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=2558"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}