-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
renamed data.py into problems.py add tests/bruteforce.py to compute brute force solutions 3 more problems with 2, 9 and 16 solutions
- Loading branch information
1 parent
26d8435
commit 4faecc5
Showing
5 changed files
with
171 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
""" | ||
bruteforce algorithm to compute the expected solutions | ||
and help write tests | ||
""" | ||
|
||
from itertools import chain, combinations | ||
|
||
import numpy as np | ||
|
||
# from the itertools module documentation | ||
def powerset(iterable): | ||
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" | ||
s = list(iterable) | ||
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) | ||
|
||
|
||
def bruteforce(data): | ||
""" | ||
Brute-force generator of all exact cover solutions | ||
""" | ||
for subset in powerset(range(data.shape[0])): | ||
if np.all(data[list(subset)].sum(axis=0) == 1): | ||
yield subset |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import numpy as np | ||
|
||
from exact_cover.io import DTYPE_FOR_ARRAY | ||
|
||
# one specific problem that I had trouble with | ||
# originally based on solving the trivial problem | ||
# of arranging 2 identical triminos on a 3x3 board | ||
|
||
# +--+ | ||
# | | | ||
# +--+--+ | ||
# | | | | ||
# +--+--+ | ||
|
||
# +--+--+--+ | ||
# |xx| |xx| | ||
# +--+--+--+ | ||
# | | | | | ||
# +--+--+--+ | ||
# |xx| | | | ||
# +--+--+--+ | ||
|
||
# this problem has 2 solutions | ||
# (5, 13) and (6, 12) | ||
def small_trimino_problem(): | ||
to_cover = [ | ||
[1, 0, 0, 1, 1, 0, 1, 0], | ||
[1, 0, 0, 0, 1, 1, 0, 1], | ||
[1, 0, 0, 0, 1, 1, 1, 0], | ||
[1, 0, 1, 0, 1, 1, 0, 0], | ||
[1, 0, 0, 0, 1, 0, 1, 1], | ||
[1, 0, 1, 1, 1, 0, 0, 0], # <- 5 | ||
[1, 0, 0, 0, 0, 1, 1, 1], # <- 6 | ||
[0, 1, 0, 1, 1, 0, 1, 0], | ||
[0, 1, 0, 0, 1, 1, 0, 1], | ||
[0, 1, 0, 0, 1, 1, 1, 0], | ||
[0, 1, 1, 0, 1, 1, 0, 0], | ||
[0, 1, 0, 0, 1, 0, 1, 1], | ||
[0, 1, 1, 1, 1, 0, 0, 0], # <- 12 | ||
[0, 1, 0, 0, 0, 1, 1, 1], # <- 13 | ||
] | ||
return dict( | ||
data=np.array(to_cover, dtype=DTYPE_FOR_ARRAY), | ||
solution1=[5, 13], | ||
solution_count=2, | ||
) | ||
|
||
def small_trimino_problem_from_file(): | ||
return dict( | ||
data=np.load("tests/files/small_trimino_problem.npy"), | ||
solution1=[5, 13], | ||
solution_count=2, | ||
) | ||
|
||
# https://en.wikipedia.org/wiki/Exact_cover#Detailed_example | ||
def detailed_wikipedia_problem(): | ||
sets = [ | ||
{1, 4, 7}, | ||
{1, 4}, # <- 1 | ||
{4, 5, 7}, | ||
{3, 5, 6}, # <- 3 | ||
{2, 3, 6, 7}, | ||
{2, 7}, # <- 5 | ||
] | ||
return dict( | ||
data=np.array( | ||
[[1 if i in s else 0 for i in range(1, 8)] for s in sets], | ||
dtype=DTYPE_FOR_ARRAY), | ||
solution1=[1, 3, 5], | ||
solution_count=1, | ||
) | ||
|
||
def bruteforce_problem1(): | ||
to_cover = [ | ||
[1, 0, 0, 1, 0, 0, 1, 0], # <- sol1 | ||
[0, 1, 0, 0, 1, 0, 0, 1], # <- sol1 | ||
[0, 0, 1, 0, 0, 1, 0, 0], # <- sol1 | ||
[0, 0, 0, 1, 0, 0, 0, 0], # <- sol2 | ||
[1, 0, 1, 0, 1, 0, 0, 1], # <- sol2 | ||
[0, 1, 0, 0, 0, 1, 1, 0], # <- sol2 | ||
|
||
] | ||
return dict( | ||
data=np.array(to_cover, dtype=DTYPE_FOR_ARRAY), | ||
solution1=[0, 1, 2], | ||
solution_count=2, | ||
) | ||
|
||
def bruteforce_problem2(): | ||
to_cover = [ | ||
[1, 0, 0, 1, 0, 0, 1, 0], # <- sol1 | ||
[0, 1, 0, 0, 1, 0, 0, 1], # <- sol1 | ||
[0, 0, 1, 0, 0, 1, 0, 0], # <- sol1 | ||
[0, 0, 0, 1, 0, 0, 0, 0], # <- sol2 | ||
[1, 0, 1, 0, 1, 0, 0, 1], # <- sol2 | ||
[0, 1, 0, 0, 0, 1, 1, 0], # <- sol2 | ||
[1, 0, 0, 1, 0, 0, 1, 0], # <- sol1 | ||
[0, 1, 0, 0, 1, 0, 0, 1], # <- sol1 | ||
[0, 0, 1, 0, 0, 1, 0, 0], # <- sol1 | ||
] | ||
return dict( | ||
data=np.array(to_cover, dtype=DTYPE_FOR_ARRAY), | ||
solution1=[0, 1, 2], | ||
solution_count=9, | ||
) | ||
|
||
def bruteforce_problem3(): | ||
to_cover = [ | ||
[1, 0, 0, 1, 0, 0, 1, 0], # <- sol1 | ||
[0, 1, 0, 0, 1, 0, 0, 1], # <- sol1 | ||
[0, 0, 1, 0, 0, 1, 0, 0], # <- sol1 | ||
[0, 0, 0, 1, 0, 0, 0, 0], # <- sol2 | ||
[1, 0, 1, 0, 1, 0, 0, 1], # <- sol2 | ||
[0, 1, 0, 0, 0, 1, 1, 0], # <- sol2 | ||
[1, 0, 0, 1, 0, 0, 1, 0], # <- sol1 | ||
[0, 1, 0, 0, 1, 0, 0, 1], # <- sol1 | ||
[0, 0, 1, 0, 0, 1, 0, 0], # <- sol1 | ||
[0, 0, 0, 1, 0, 0, 0, 0], # <- sol2 | ||
[1, 0, 1, 0, 1, 0, 0, 1], # <- sol2 | ||
[0, 1, 0, 0, 0, 1, 1, 0], # <- sol2 | ||
] | ||
return dict( | ||
data=np.array(to_cover, dtype=DTYPE_FOR_ARRAY), | ||
solution1=[0, 1, 2], | ||
solution_count=16, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters