Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Finding Exact Covers in NumPy

PyPI version Deploy wheels to pypi Run Python tests

This is a Python 3 package to solve exact cover problems using Numpy. It is based on https://github.com/moygit/exact_cover_np by Moy Easwaran. Jack Grahl ported it to Python 3, fixed some bugs and made lots of small improvements to the packaging.

The original package by Moy was designed to solve sudoku. Now this package is only designed to solve exact cover problems given as boolean arrays. It can be used to solve sudoku and a variety of combinatorial problems. However the code to reduce a sudoku to an exact cover problem is no longer part of this project. It can be found at:

Another project, 'polyomino' by Jack Grahl uses this algorithm to solve polyomino tiling problems. It can be found at:

Summary

The exact cover problem is as follows: given a set X and a collection S of subsets of X, we want to find a subcollection S* of S that is an exact cover or partition of X. In other words, S* is a bunch of subsets of X whose union is X, and which have empty intersection with each other. (Example below; more details on wikipedia.)

This NumPy module uses Donald Knuth's Algorithm X (also known as Dancing Links) to find exact covers of sets. For details on Algorithm X please see either the Wikipedia page or Knuth's paper. Specifically, we use the Knuth/Hitotsumatsu/Noshita method of Dancing Links for efficient backtracking. Please see Knuth's paper for details.

How to Use It

Suppose X = {0,1,2,3,4}, and suppose S = {A,B,C,D}, where

A = {0, 3}
B = {0, 1, 2}
C = {1, 2}
D = {4}.

Here we can just eyeball these sets and conclude that S* = {A,C,D} forms an exact cover: each element of X is in one of these sets (i.e. is "covered" by one of these sets), and no element of X is in more than one.

We'd use exact_cover to solve the problem as follows: using 1 to denote that a particular member of X is in a subset and 0 to denote that it's not, we can represent the sets as

A = 1,0,0,1,0    # The 0th and 3rd entries are 1 since 0 and 3 are in A; the rest are 0.
B = 1,1,1,0,0    # The 0th, 1st, and 2nd entries are 1, and the rest are 0,
C = 0,1,1,0,0    # etc.
D = 0,0,0,0,1

Now we can call exact_cover:

>>> import numpy as np
>>> import exact_cover as ec
>>> S = np.array([[1,0,0,1,0],[1,1,1,0,0],[0,1,1,0,0],[0,0,0,0,1]], dtype=bool)
>>> ec.get_exact_cover(S)
array([0, 2, 3])

This is telling us that the 0th row (i.e. A), the 2nd row (i.e. C), and the 3rd row (i.e. D) together form an exact cover.

See the file examples.md for more detailed examples of use.

Implementation Overview

The NumPy module (exact_cover) is implemented in four pieces:

  • The lowest level is quad_linked_list, which implements a circular linked-list with left-, right-, up-, and down-links.
  • This is used in sparse_matrix to implement the type of sparse representation of matrices that Knuth describes in his paper (in brief, each column contains all its non-zero entries, and each non-zero cell also points to the (horizontally) next non-zero cell in either direction).
  • Sparse matrices are used in dlx to implement Knuth's Dancing Links version of his Algorithm X, which calculates exact covers.
  • exact_cover provides the glue code letting us invoke dlx on NumPy arrays.

The package now has some pure Python modules for helper functions, with the main algorithm in the C-only package exact_cover_impl.

How to develop

The package uses poetry and most of the setup for development uses that tool.

To install locally (as an editable package): poetry install

To build: poetry build

To run tests: poetry run test or poetry run doctest

To open a Python shell with the package available: poetry run python

The exception is running the C unit tests: make c_tests

Repository

  • build/ The location where files are built.
  • dist/ The location for fully prepared files.
  • exact_cover/ The Python code.
  • obj/ Where the compiled C code is going to be output.
  • src/ The C sources.
  • tests/ Tests for both the Python package and the C code.
  • tools/ Code used in analysing and working with the library. This is not distributed with the package.

Acknowledgements

Thanks very much to Moy Easwaran (https://github.com/moygit) for his inspiring work!

Munit aka µnit (https://nemequ.github.io/munit/) is a wonderful unit testing framework for C code.

Release files for exact-cover 1.1.0a0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for exact-cover 1.1.0a0
File Size Uploaded
exact_cover-1.1.0a0.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for exact-cover 1.1.0a0
File Interpreter ABI Platform
exact_cover-1.1.0a0-cp39-cp39-manylinux_2_31_armv7l.whl CPython 3.9 CPython 3.9 Linux glibc 2.31+ ARMv7l Details

Total release size: 56.1 kB

Release files / exact_cover-1.1.0a0.tar.gz

Download URL exact_cover-1.1.0a0.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
186a2d5dd6f6c704099fd3da4f649641481e55546d18d9d6f3a85c95140903a3
BLAKE2b-256 checksum
How to use checksums
59e68dd0284c91b93c6f50b3bd4137aace463d3cc96ccd1037364749e0d3a6f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.3.2 CPython/3.9.2 Linux/5.15.84-v7+

Release files / exact_cover-1.1.0a0-cp39-cp39-manylinux_2_31_armv7l.whl

Download URL exact_cover-1.1.0a0-cp39-cp39-manylinux_2_31_armv7l.whl
Size 37.0 kB
Tags CPython 3.9 Linux glibc 2.31+ ARMv7l
SHA-256 checksum
How to use checksums
379eb66d70a5afdd5d0abe02affab08e43d0102140073d7564b0f651f3c13efa
BLAKE2b-256 checksum
How to use checksums
152a411ba6274070da1a5c18a5f05e879c1b60802d786f232670c6b3d04f7559
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.3.2 CPython/3.9.2 Linux/5.15.84-v7+

Release history Release notifications | RSS feed

1.5.0

15 release files

1.4.0

16 release files

1.3.0

16 release files

1.2.2

16 release files

1.2.1

16 release files

1.2.0

16 release files

1.1.0

20 release files

This release

1.1.0a0 This release

2 release files

1.0.1

9 release files

1.0.0

5 release files

0.8.0

7 release files

0.7.2

7 release files

0.7.1

7 release files

0.7.0

7 release files

0.6.3

7 release files

0.6.2

7 release files

0.6.1

7 release files

0.6.0

7 release files

0.5.0

7 release files

0.4.2

7 release files

0.4.1

7 release files

0.4.0

7 release files

0.3.2

7 release files

0.3.1

7 release files

0.3.0

7 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

1 release file

0.2.1

2 release files

0.1.0

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page