Skip to content

Instantly share code, notes, and snippets.

@marekyggdrasil
Created September 28, 2018 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marekyggdrasil/0b75ebe8c0c477a96c7b2e8d730b5d38 to your computer and use it in GitHub Desktop.
Save marekyggdrasil/0b75ebe8c0c477a96c7b2e8d730b5d38 to your computer and use it in GitHub Desktop.
There is a publicly available library for DLX algorithm (also known as 'Algorithm X' or 'Dancing Links' algorithm) available at https://pypi.org/project/dlx/
from dlx import DLX
def genInstance(labels, rows) :
columns = []
indices_l = {}
for i in range(len(labels)) :
label = labels[i]
indices_l[label] = i
columns.append(tuple([label,0]))
return labels, rows, columns, indices_l
def solveInstance(instance) :
labels, rows, columns, indices_l = instance
instance = DLX(columns)
indices = {}
for l, i in zip(rows, range(len(rows))) :
h = instance.appendRow(l, 'r'+str(i))
indices[str(hash(tuple(sorted(l))))] = i
sol = instance.solve()
lst = list(sol)
selected = []
for i in lst[0] :
l = instance.getRowList(i)
l2 = [indices_l[label] for label in l]
idx = indices[str(hash(tuple(sorted(l2))))]
selected.append(idx)
return selected
def printColumnsPerRow(instance, selected) :
labels, rows, columns, indices_l = instance
print 'covered columns per selected row'
for s in selected :
A = []
for z in rows[s-1] :
c, _ = columns[z]
A.append(c)
print s, A
def printInstance(instance) :
labels, rows, columns, indices_l = instance
print 'columns'
print labels
print 'rows'
print rows
'''
example instance #1
source: https://www.cs.mcgill.ca/~aassaf9/python/algorithm_x.html
A B C D E F G
0 1 0 0 1 0 0 1 (0, 3, 6)
1 1 0 0 1 0 0 0 (0, 3)
2 0 0 0 1 1 0 1 (3, 4, 6)
3 0 0 1 0 1 1 0 (2, 4, 5)
4 0 1 1 0 0 1 1 (1, 2, 5, 6)
5 0 1 0 0 0 0 1 (1, 6)
expected solution: 1, 3, 5
A B C D E F G
1 1 _ _ 1 _ _ _ (0, 3)
3 _ _ 1 _ 1 1 _ (2, 4, 5)
5 _ 1 _ _ _ _ 1 (1, 6)
'''
labels = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
print 'instance #1'
rows = [[0,3,6],[0,3],[3,4,6],[2,4,5],[1,2,5,6],[1,6]]
instance = genInstance(labels, rows)
selected = solveInstance(instance)
printInstance(instance)
printColumnsPerRow(instance, selected)
print ''
'''
example instance #2
source: https://lanl.arxiv.org/pdf/cs/0011047
A B C D E F G
0 0 0 1 0 1 1 0 (2, 4, 5)
1 1 0 0 1 0 0 1 (0, 3, 6)
2 0 1 1 0 0 1 0 (1, 2, 5)
3 1 0 0 1 0 0 0 (0, 3)
4 0 1 0 0 0 0 1 (1, 6)
5 0 0 0 1 1 0 1 (3, 4, 6)
expected solution: 0, 3, 4
A B C D E F G
0 _ _ 1 _ 1 1 _ (2, 4, 5)
3 1 _ _ 1 _ _ _ (0, 3)
4 _ 1 _ _ _ _ 1 (1, 6)
'''
print 'instance #2'
rows = [[2, 4, 5], [0, 3, 6], [1, 2, 5], [0, 3], [1, 6], [3, 4, 6]]
instance = genInstance(labels, rows)
selected = solveInstance(instance)
printInstance(instance)
printColumnsPerRow(instance, selected)
instance #1
columns
['A', 'B', 'C', 'D', 'E', 'F', 'G']
rows
[[0, 3, 6], [0, 3], [3, 4, 6], [2, 4, 5], [1, 2, 5, 6], [1, 6]]
covered columns per selected row
1 ['A', 'D', 'G']
3 ['D', 'E', 'G']
5 ['B', 'C', 'F', 'G']
instance #2
columns
['A', 'B', 'C', 'D', 'E', 'F', 'G']
rows
[[2, 4, 5], [0, 3, 6], [1, 2, 5], [0, 3], [1, 6], [3, 4, 6]]
covered columns per selected row
3 ['B', 'C', 'F']
0 ['D', 'E', 'G']
4 ['A', 'D']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment