-
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.
Merge pull request #73 from parmentelat/all_solutions
test solution_count on small_trimino problem
- Loading branch information
Showing
4 changed files
with
193 additions
and
50 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 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