Use only 30 lines of Python code to show the x algorithm

Source: Internet
Author: User
If you are interested in a logarithmic solution, you may have heard of accurate coverage. Given the set Y of a subset of complete x and X, there is a subset of Y y*, which makes y* a division of X.

Here is an example of Python writing.

X = {1, 2, 3, 4, 5, 6, 7}y = {  ' A ': [1, 4, 7],  ' B ': [1, 4],  ' C ': [4, 5, 7],  ' D ': [3, 5, 6],  ' E ': [2, 3 , 6, 7],  ' F ': [2, 7]}

The only solution to this example is [' B ', ' D ', ' F '].

The exact coverage problem is NP-complete: There is no one fast enough way to find the answer within a reasonable time, meaning polynomial time. The x algorithm is invented and implemented by Gaudena. He proposed an efficient implementation technique called the dance chain, which uses a doubly linked list to represent the matrix of the problem.

However, the dance chain can be quite cumbersome to implement and not easy to write correctly. The next step is to show the magic of Python! One day I decided to use Python to write the x algorithm, and I came up with an interesting dance chain variant.
Algorithm

The main idea is to use a dictionary instead of a doubly linked list to represent a matrix. We've got Y. From it we can quickly access the column elements of each row. Now we also need to generate a reverse table of rows, in other words, to quickly access row elements from a column. For this purpose, we convert x into a dictionary. In the above example, it should be written as

X = {  1: {' A ', ' B '},  2: {' E ', ' F '},  3: {' d ', ' e '},  4: {' A ', ' B ', ' C '},  5: {' C ', ' d '},  6: {' d ', ' E '},  7: {' A ', ' C ', ' e ', ' F '}}

Sharp-eyed readers can note that this is slightly different from the representation of Y. In fact, we need to be able to quickly delete and add rows to each column, which is why we use collections. On the other hand, Gartner does not mention this, and virtually all the lines in the algorithm remain unchanged.

The following is the code for the algorithm.

def solve (x, Y, solution=[]):  if not X:    yield list (solution)  else:    c = min (x, Key=lambda C:len (X[c])) 
  for r in List (X[c]):      solution.append (r)      cols = select (x, Y, R) for      s in solve (x, Y, solution):        yield s
  deselect (x, Y, R, cols)      solution.pop () def select (x, Y, R):  cols = [] for  J in Y[r]: for    i in X[j]: For      K in y[i]:        if k! = J:          x[k].remove (i)    Cols.append (X.pop (j))  return cols def deselect (X, Y, R , cols): for  J in reversed (Y[r]):    x[j] = Cols.pop () for    I in X[j]: for K in      Y[i]:        if k! = j:
  
   x[k].add (i)
  

It's really only 30 lines!
Format input

Before we solve the actual problem, we need to convert the input to the format described above. Can be handled as simple as this

x = {J:set (filter (lambda i:j in y[i], Y)) for J in X}

But it's too slow. If the size of X size is M,y is n, then the iteration count is m*n. In this example the Sudoku lattice size is N, which takes n^5 times. We have a better way.

X = {J:set () for J in X}for I in Y: for  J in Y[i]:    x[j].add (i)

This is still the complexity of O (m*n), but it is the worst case scenario. On average, it performs much better because it does not need to traverse all of the space bits. In the case of Sudoku, there are exactly 4 entries per line in the matrix, regardless of size, so it has n^3 complexity.
Advantages

    • Simple: There is no need to construct complex data structures, all of which are available in the structure Python.
    • Readability: The first example above is directly transcribed from the Wikipedia paradigm!
    • Flexibility: It can be easily extended to solve Sudoku.

Solving Sudoku

What we need to do is to describe Sudoku as an accurate coverage problem. Here is the complete Sudoku code, which can handle any size, 3x3,5x5, even 2x3, all code less than 100 lines, and contains doctest! (Thanks to Winfried Plappert and David Goodger's comments and suggestions)

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.