Dancing links
In computer science, dancing links is a technique for adding and deleting a node from a circular doubly linked list. It is particularly useful for efficiently implementing backtracking algorithms, such as Knuth's Algorithm X for the exact cover problem. Algorithm X is a recursive, nondeterministic, depth-first, backtracking algorithm that finds all solutions to the exact cover problem. Some of the better-known exact cover problems include tiling, the n queens problem, and Sudoku.
The name dancing links, which was suggested by Donald Knuth, stems from the way the algorithm works, as iterations of the algorithm cause the links to "dance" with partner links so as to resemble an "exquisitely choreographed dance." Knuth credits Hiroshi Hitotsumatsu and Kōhei Noshita with having invented the idea in 1979, but it is his paper which has popularized it.
Implementation
Main ideas
The idea of DLX is based on the observation that in a circular doubly linked list of nodes,x.left.right ← x.right;
x.right.left ← x.left;
will remove node x from the list, while
x.left.right ← x;
x.right.left ← x;
will restore x's position in the list, assuming that x.right and x.left have been left unmodified. This works regardless of the number of elements in the list, even if that number is 1.
Knuth observed that a naive implementation of his Algorithm X would spend an inordinate amount of time searching for 1's. When selecting a column, the entire matrix had to be searched for 1's. When selecting a row, an entire column had to be searched for 1's. After selecting a row, that row and a number of columns had to be searched for 1's. To improve this search time from complexity O to O, Knuth implemented a sparse matrix where only 1's are stored.
At all times, each node in the matrix will point to the adjacent nodes to the left and right, above and below, and the header for its column. Each row and column in the matrix will consist of a circular doubly-linked list of nodes.
Header
Each column will have a special node known as the "column header," which will be included in the column list, and will form a special row consisting of all the columns which still exist in the matrix.Finally, each column header may optionally track the number of nodes in its column, so that locating a column with the lowest number of nodes is of complexity O rather than O where n is the number of columns and m is the number of rows. Selecting a column with a low node count is a heuristic which improves performance in some cases, but is not essential to the algorithm.