SlideShare una empresa de Scribd logo
1 de 24
Descargar para leer sin conexión
Dancing Links
an educational pearl
Massimo Nocentini, PhD.
massimo.nocentini@gmail.com
ESUG2019 – August 28, 2019.
outline
^ LinkedList new
add: 'me and the core idea';
add: 'DoubleLink objs';
add: 'exact cover problem';
add: 'AlgorithmX';
add: 'covering and uncovering columns';
add: 'N-Queens and Sudoku problems';
yourself
Hi!
$ whoami
Massimo Nocentini, PhD
Mathematician (algebraic combinatorics, formal methods for algs)
Programmer (automated reasoning, logics and symbolic comp)
https://github.com/massimo-nocentini/dancinglinksst
In Donald’s words1
: Suppose x points to an element of a doubly linked
list; let L[x] and R[x] point to the predecessor and successor of that
element. Then:
L[R[x]] ← L[x], R[L[x]] ← R[x] (1)
remove x from the list; every programmer knows this. But comparatively
few programmers have realized that
L[R[x]] ← x, R[L[x]] ← x (2)
will put x back again, with no refs to the whole list at all.
1https://arxiv.org/abs/cs/0011047
Space for sketching
Main ideas
Operation (2) arises in backtrack programs, which enumerate all
solutions to a given set of constraints and it was introduced in 1979
by Hitotumatu and Noshita.
The beauty of (2) is that operation (1) can be undone by knowing
only the value of x.
We can apply (1) and (2) repeatedly in complex data structures that
involve large numbers of interacting doubly linked lists.
Knuth: “This process causes the pointer variables inside the global
data structure to execute an exquisitely choreographed dance; hence
I like to call (1) and (2) the technique of dancing links.”
Minato et al. 2
constructs a Zero-suppressed BDD (ZDD) that
represents the set of sols and it enables the efficient use of memo
cache to speed up the search.
2https://aaai.org/ocs/index.php/AAAI/AAAI17/paper/view/14907
DoubleLinks and DoubleLinkedLists
DoubleLink objects respond to messages
remove
nextLink ifNotNil: [ :next | next previousLink: previousLink ].
previousLink ifNotNil: [ :previous | previous nextLink: nextLink ]
and
restore
nextLink ifNotNil: [ :next | next previousLink: self ].
previousLink ifNotNil: [ :previous | previous nextLink: self ]
that implement operations (1) and (2), respectively; moreover, we extend
DoubleLinkedList objects with the message
makeCircular
head
ifNotNil: [
head previousLink: tail.
tail nextLink: head ]
to introduce circular, doubly connected, lists.
Exact Cover ∈ NP
Given a matrix of 0s and 1s, does it have a set of rows containing
exactly one symbol 1 in each column?
The problem with matrix






r1
r2
r3
r4
r5






T 





1 1 1 0 1 0
1 1 0 0 0 0
0 0 0 1 0 1
0 0 1 1 0 1
0 0 1 0 1 0






=








1
1
1
1
1
1








T
is solved by two sets of rows, namely
{r1 = 1, r3 = 1} and {r2 = 1, r5 = 1, r3 = 1}.
We can think of the columns as elements of a universe, and the rows as
subsets of the universe; then the problem is to cover the universe with
disjoint subsets, NP-complete even when each row contains exactly
three 1s.
Space for sketching
AlgorithmX instance side
searchDepth: k forDLRootObject: h partialSelection: cont
^ (h isFixPointOf: [ :ro | ro right ])
ifTrue: [ self yieldNode: top onBlock: cont ]
ifFalse: [
memo
at: h columns
ifPresent: [ :tree | self yieldNode: tree onBlock: cont ]
ifAbsentPut: [
self
searchDepth: k
forDLColumnObject: h chooseColumn
partialSelection: cont ] ]
AlgorithmX instance side
searchDepth: k forDLColumnObject: c partialSelection: sel
^ self
onEnter: [ c cover ]
do: [
c
untilFixPointOf: [ :co | co up ]
foldr: [ :r :x |
| y |
y := self searchDepth: k
forDLDataObject: r
partialSelection: sel.
y isZDDBottom
ifTrue: [ x ]
ifFalse: [
self
uniqueNodeWithDLDataObject: r
withLowerNode: x
withHigherNode: y ] ]
init: bottom ]
onExit: [ c uncover ]
AlgorithmX instance side
searchDepth: k forDLDataObject: r partialSelection: cont
^ self
onEnter: [ r untilFixPointOf: [ :ro | ro right ]
do: [ :j | j column cover ] ]
do: [ self
searchDepth: k + 1
forDLRootObject: r column root
partialSelection: [ :sel |
cont
value:
(ValueLink new
value: r model;
nextLink: sel;
yourself) ] ]
onExit: [ r untilFixPointOf: [ :ro | ro left ]
do: [ :j | j column uncover ] ]
AlgorithmX instance side
The entry point is the message
searchDLRootObject: h onSolutionDo: aBlock
^ self
searchDepth: 0
forDLRootObject: h
partialSelection: [ :selLink |
aBlock value: (LinkedList new add: selLink; asSet) ]
Knuth advices to use the heuristic (provided by DLRootObject objs)
chooseColumn
^ self chooseColumnWithWeight: #size withOpt: #<
chooseColumnWithWeight: weightBlock withOpt: optBlock
^ self
untilFixPointOf: [ :ro | ro left ]
foldr: [ :j :r |
(optBlock value: (weightBlock value: j) value: (weightBlock value: r))
ifTrue: [ j ]
ifFalse: [ r ] ]
init: self right
that minimizes the search tree’s branching factor.
DLColumnObject instance side
The operation of covering column c removes c from the header list and
removes all rows in c’s own list from the other column lists they are in.
cover
we remove.
self
untilFixPointOf: [ :co | co down ]
do: [ :i |
i
untilFixPointOf: [ :do | do right ]
do: [ :j |
j nsLink remove.
j column updateSize: [ :s | s - 1 ] ] ]
Operation (1) is used here to remove objects in both the horizontal and
vertical directions.
DLColumnObject instance side
Finally, we get to the operation of uncovering a given column c. Here is
where the links do their dance:
uncover
self
untilFixPointOf: [ :co | co up ]
do: [ :i |
i
untilFixPointOf: [ :do | do left ]
do: [ :j |
j nsLink restore.
j column updateSize: [ :s | s + 1 ] ] ].
we restore
Notice that uncovering takes place in precisely the reverse order of the
covering operation, using the fact that (2) undoes (1).
Sudoku to Exact Cover reduction
emptySudokuIndicators
| ones start end |
start := 0. end := 8. ones := LinkedList new.
start to: end do: [ :row |
start to: end do: [ :column |
start to: end do: [ :value |
| rowIndex cellConstraint rowConstraint
columnConstraint boxConstraint model |
model := {(#x -> row). (#y -> column). (#v -> value)} asDictionary.
rowIndex := 81 * row + (9 * column) + value.
cellConstraint := rowIndex @ ((end + 1) * row + column).
rowConstraint := rowIndex @ (9 * row + value + 81).
columnConstraint := rowIndex @ (9 * column + value + (81 * 2)).
boxConstraint := rowIndex
@ (27 * (row // 3) + (9 * (column // 3)) + value + (81 * 3)).
ones
add: ((cellConstraint + 1) asDLPoint primary: true) -> model;
add: ((rowConstraint + 1) asDLPoint primary: true) -> model;
add: ((columnConstraint + 1) asDLPoint primary: true) -> model;
add: ((boxConstraint + 1) asDLPoint primary: true) -> model ] ] ].
^ ones
Soduku solutions
testDLXonSudoku
| grid sols chain matrices |
grid := DLDataObject gridOn: DLDataObjectTest new emptySudokuIndicators.
chain := Generator
on: [ :g | AlgorithmX new
searchDLRootObject: (grid at: #root)
onSolutionDo: [ :sel | g yield: sel ] ].
sols := (chain next: 2) contents.
matrices := sols collect: [ :sol | "build the corresponding matrix" ].
self
assert: matrices first printString
equals:
'(9 8 7 6 5 4 3 2 1
6 5 4 3 2 1 9 8 7
3 2 1 9 8 7 6 5 4
8 9 6 7 4 5 2 1 3
7 4 5 2 1 3 8 9 6
2 1 3 8 9 6 7 4 5
5 7 9 4 6 8 1 3 2
4 6 8 1 3 2 5 7 9
1 3 2 5 7 9 4 6 8 )'.
N-Queens to Exact Cover reduction
NQueensIndicators: n
| ones |
ones := LinkedList new.
0 to: n - 1 do: [ :row |
0 to: n - 1 do: [ :column |
| rowIndex rowConstraint columnConstraint
diagonalConstraint antiDiagonalConstraint model |
model := Dictionary new at: #x put: row; at: #y put: column; yourself.
rowIndex := n * row + column.
rowConstraint := rowIndex @ row.
columnConstraint := rowIndex @ (n + column).
diagonalConstraint := rowIndex @ (2 * n + (row + column)).
antiDiagonalConstraint := rowIndex
@ (2 * n + (2 * n) - 1 + (n - 1 - row + column)).
ones
add: ((rowConstraint + 1) asDLPoint primary: true) -> model;
add: ((columnConstraint + 1) asDLPoint primary: true) -> model;
add: ((diagonalConstraint + 1) asDLPoint primary: false) -> model;
add: ((antiDiagonalConstraint + 1) asDLPoint primary: false) -> model
^ ones
N-Queens solutions
testDLXon_NQueens_sequence
| seq elapsedTime |
elapsedTime := [ seq := (1 to: 10)
collect: [ :i | (self runDLXonNQueens: i next: nil) size ] ] timeToRun.
self assert: elapsedTime < 2 asSeconds.
self assert: seq "also known as https://oeis.org/A000170"
equals: {1 . 0 . 0 . 2 . 10 . 4 . 40 . 92 . 352 . 724}
testDLXon_8Queens
| matrices |
matrices := self runDLXonNQueens: 8 next: 1.
self
assert: matrices first printString
equals:
'(0 0 0 0 0 0 0 1
0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 )'.
Final remarks
We presented a vanilla implementation of DLX with the ZDD
extension in pure Smalltalk, with an educational savor.
It is designed to be easy to understand and to play with still
remaining efficient and robust.
Dancing links are considered the state-of-the-art heuristic for EC
:) Knuth is still actively working on this (a new fascicle is in prep 3
)
:( Constraints are verbose and rigid to express (currently we use
Point objs), looking for a DSL that makes coding constraints easier
TODO
Group column objects using different colours to gain expressivity
Write reductions to Exact Cover (from 3SAT, Knapsack, TSP, ...)
3https://cs.stanford.edu/~knuth/fasc5c.ps.gz
Thanks!
yieldNode: tree onBlock: cont
tree sets
collect: [ :each | (each collect: #model) as: LinkedList ]
thenDo: [ :sel |
| link |
link := sel isEmpty ifTrue: [ nil ] ifFalse: [ sel firstLink ].
cont value: link ].
^ tree
uniqueNodeWithDLDataObject: r withLowerNode: x withHigherNode: y
| key |
key := Array with: r with: x with: y.
^ zDDTree
at: key
ifAbsentPut: [ | z |
z := ZDDNode new model: r; lower: x; higher: y; yourself.
x parent: z.
y parent: z.
z ]
DLDataObject class side
gridOn: aCollection
| rootObj columns rows headers allObjs |
aCollection
sort: [ :vAssoc :wAssoc |
| v w |
v := vAssoc key.
w := wAssoc key.
v y <= w y and: [ v x <= w x ] ].
allObjs := Dictionary new.
headers := DoubleLinkedList new.
columns := Dictionary new.
rows := Dictionary new.
rootObj := DLRootObject new
addInDoubleLinkedList: headers direction: #we;
yourself.
allObjs at: #root put: rootObj.
"to be contd..."
DLDataObject class side
gridOn: aCollection
"...contd..."
aCollection
do: [ :anAssociation |
| aPoint columnObj dataObj column row |
aPoint := anAssociation key.
column := columns
at: aPoint y
ifAbsentPut: [ | headerObj newColumn |
headerObj := DLColumnObject new size: 0; root: rootObj; yourself.
aPoint primary
ifTrue: [ headerObj addInDoubleLinkedList: headers
direction: #we ]
ifFalse: [ DoubleLinkedList
circular: [ :dll | headerObj addInDoubleLinkedList: dll
direction: #we ] ].
newColumn := DoubleLinkedList new.
headerObj addInDoubleLinkedList: newColumn direction: #ns.
allObjs at: aPoint y put: headerObj.
newColumn ].
"..to be contd further..."
DLDataObject class side
gridOn: aCollection
"...contd"
columnObj := column first.
dataObj := DLDataObject new
column: columnObj;
point: aPoint;
model: anAssociation value;
yourself.
row := rows at: aPoint x ifAbsentPut: [ DoubleLinkedList new ].
dataObj
addInDoubleLinkedList: column direction: #ns;
addInDoubleLinkedList: row direction: #we.
columnObj updateSize: [ :s | s + 1 ].
allObjs at: aPoint put: dataObj ].
headers makeCircular.
columns valuesDo: #makeCircular.
rows valuesDo: #makeCircular.
^ allObjs

Más contenido relacionado

La actualidad más candente

Introduction to haskell
Introduction to haskellIntroduction to haskell
Introduction to haskellLuca Molteni
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Bryan O'Sullivan
 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsPhilip Schwarz
 
Introducing: A Complete Algebra of Data
Introducing: A Complete Algebra of DataIntroducing: A Complete Algebra of Data
Introducing: A Complete Algebra of DataInside Analysis
 
Review session2
Review session2Review session2
Review session2NEEDY12345
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Philip Schwarz
 
Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1Philip Schwarz
 
Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]Palak Sanghani
 
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...Amrinder Arora
 
The Functional Programming Triad of fold, scan and iterate
The Functional Programming Triad of fold, scan and iterateThe Functional Programming Triad of fold, scan and iterate
The Functional Programming Triad of fold, scan and iteratePhilip Schwarz
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellMichel Rijnders
 
Scilab - Piecewise Functions
Scilab - Piecewise FunctionsScilab - Piecewise Functions
Scilab - Piecewise FunctionsJorge Jasso
 
Chapter 7.3
Chapter 7.3Chapter 7.3
Chapter 7.3sotlsoc
 

La actualidad más candente (20)

Introduction to haskell
Introduction to haskellIntroduction to haskell
Introduction to haskell
 
Real World Haskell: Lecture 4
Real World Haskell: Lecture 4Real World Haskell: Lecture 4
Real World Haskell: Lecture 4
 
Abstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generatorsAbstracting over the Monad yielded by a for comprehension and its generators
Abstracting over the Monad yielded by a for comprehension and its generators
 
Introducing: A Complete Algebra of Data
Introducing: A Complete Algebra of DataIntroducing: A Complete Algebra of Data
Introducing: A Complete Algebra of Data
 
Dijkstra c
Dijkstra cDijkstra c
Dijkstra c
 
Review session2
Review session2Review session2
Review session2
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
 
Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1Computer Graphics in Java and Scala - Part 1
Computer Graphics in Java and Scala - Part 1
 
Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]Lec 9 05_sept [compatibility mode]
Lec 9 05_sept [compatibility mode]
 
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
Proof of O(log *n) time complexity of Union find (Presentation by Wei Li, Zeh...
 
Matlab algebra
Matlab algebraMatlab algebra
Matlab algebra
 
Data Structures- Hashing
Data Structures- Hashing Data Structures- Hashing
Data Structures- Hashing
 
The Functional Programming Triad of fold, scan and iterate
The Functional Programming Triad of fold, scan and iterateThe Functional Programming Triad of fold, scan and iterate
The Functional Programming Triad of fold, scan and iterate
 
Machnical Engineering Assignment Help
Machnical Engineering Assignment HelpMachnical Engineering Assignment Help
Machnical Engineering Assignment Help
 
Algorithm Homework Help
Algorithm Homework HelpAlgorithm Homework Help
Algorithm Homework Help
 
Soft Heaps
Soft HeapsSoft Heaps
Soft Heaps
 
An Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using HaskellAn Introduction to Functional Programming using Haskell
An Introduction to Functional Programming using Haskell
 
Lec23
Lec23Lec23
Lec23
 
Scilab - Piecewise Functions
Scilab - Piecewise FunctionsScilab - Piecewise Functions
Scilab - Piecewise Functions
 
Chapter 7.3
Chapter 7.3Chapter 7.3
Chapter 7.3
 

Similar a Dancing Links: an educational pearl

Deep Learning, Keras, and TensorFlow
Deep Learning, Keras, and TensorFlowDeep Learning, Keras, and TensorFlow
Deep Learning, Keras, and TensorFlowOswald Campesato
 
Deep Learning: R with Keras and TensorFlow
Deep Learning: R with Keras and TensorFlowDeep Learning: R with Keras and TensorFlow
Deep Learning: R with Keras and TensorFlowOswald Campesato
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance HaskellJohan Tibell
 
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxSAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxagnesdcarey33086
 
CE344L-200365-Lab2.pdf
CE344L-200365-Lab2.pdfCE344L-200365-Lab2.pdf
CE344L-200365-Lab2.pdfUmarMustafa13
 
Vectorise all the things - long version.pptx
Vectorise all the things - long version.pptxVectorise all the things - long version.pptx
Vectorise all the things - long version.pptxJodieBurchell1
 
Fundamentals of data structures
Fundamentals of data structuresFundamentals of data structures
Fundamentals of data structuresNiraj Agarwal
 
Reasoning about laziness
Reasoning about lazinessReasoning about laziness
Reasoning about lazinessJohan Tibell
 
Introduction to Matlab - Basic Functions
Introduction to Matlab - Basic FunctionsIntroduction to Matlab - Basic Functions
Introduction to Matlab - Basic Functionsjoellivz
 
MATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulink
MATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulinkMATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulink
MATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulinkreddyprasad reddyvari
 
Real World Haskell: Lecture 2
Real World Haskell: Lecture 2Real World Haskell: Lecture 2
Real World Haskell: Lecture 2Bryan O'Sullivan
 
CS 354 More Graphics Pipeline
CS 354 More Graphics PipelineCS 354 More Graphics Pipeline
CS 354 More Graphics PipelineMark Kilgard
 
C++ STL (quickest way to learn, even for absolute beginners).pptx
C++ STL (quickest way to learn, even for absolute beginners).pptxC++ STL (quickest way to learn, even for absolute beginners).pptx
C++ STL (quickest way to learn, even for absolute beginners).pptxAbhishek Tirkey
 

Similar a Dancing Links: an educational pearl (20)

Statistics lab 1
Statistics lab 1Statistics lab 1
Statistics lab 1
 
Q
QQ
Q
 
Introduction to R
Introduction to RIntroduction to R
Introduction to R
 
Deep Learning, Keras, and TensorFlow
Deep Learning, Keras, and TensorFlowDeep Learning, Keras, and TensorFlow
Deep Learning, Keras, and TensorFlow
 
Deep Learning: R with Keras and TensorFlow
Deep Learning: R with Keras and TensorFlowDeep Learning: R with Keras and TensorFlow
Deep Learning: R with Keras and TensorFlow
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
 
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docxSAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
SAMPLE QUESTIONExercise 1 Consider the functionf (x,C).docx
 
CE344L-200365-Lab2.pdf
CE344L-200365-Lab2.pdfCE344L-200365-Lab2.pdf
CE344L-200365-Lab2.pdf
 
Matlab1
Matlab1Matlab1
Matlab1
 
MATLABgraphPlotting.pptx
MATLABgraphPlotting.pptxMATLABgraphPlotting.pptx
MATLABgraphPlotting.pptx
 
Vectorise all the things - long version.pptx
Vectorise all the things - long version.pptxVectorise all the things - long version.pptx
Vectorise all the things - long version.pptx
 
Fundamentals of data structures
Fundamentals of data structuresFundamentals of data structures
Fundamentals of data structures
 
Reasoning about laziness
Reasoning about lazinessReasoning about laziness
Reasoning about laziness
 
Introduction to Matlab - Basic Functions
Introduction to Matlab - Basic FunctionsIntroduction to Matlab - Basic Functions
Introduction to Matlab - Basic Functions
 
MATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulink
MATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulinkMATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulink
MATLAB/SIMULINK for Engineering Applications day 2:Introduction to simulink
 
Tutorial 2
Tutorial     2Tutorial     2
Tutorial 2
 
Real World Haskell: Lecture 2
Real World Haskell: Lecture 2Real World Haskell: Lecture 2
Real World Haskell: Lecture 2
 
CS 354 More Graphics Pipeline
CS 354 More Graphics PipelineCS 354 More Graphics Pipeline
CS 354 More Graphics Pipeline
 
Linked list
Linked listLinked list
Linked list
 
C++ STL (quickest way to learn, even for absolute beginners).pptx
C++ STL (quickest way to learn, even for absolute beginners).pptxC++ STL (quickest way to learn, even for absolute beginners).pptx
C++ STL (quickest way to learn, even for absolute beginners).pptx
 

Más de ESUG

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingESUG
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in PharoESUG
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapESUG
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoESUG
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...ESUG
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsESUG
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6ESUG
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationESUG
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingESUG
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesESUG
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportESUG
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsESUG
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector TuningESUG
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseESUG
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FutureESUG
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the DebuggerESUG
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing ScoreESUG
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptESUG
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocESUG
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsESUG
 

Más de ESUG (20)

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in Pharo
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in Pharo
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector Tuning
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the Debugger
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing Score
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design Mooc
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and Transformations
 

Último

%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 

Último (20)

%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 

Dancing Links: an educational pearl

  • 1. Dancing Links an educational pearl Massimo Nocentini, PhD. massimo.nocentini@gmail.com ESUG2019 – August 28, 2019.
  • 2. outline ^ LinkedList new add: 'me and the core idea'; add: 'DoubleLink objs'; add: 'exact cover problem'; add: 'AlgorithmX'; add: 'covering and uncovering columns'; add: 'N-Queens and Sudoku problems'; yourself
  • 3. Hi! $ whoami Massimo Nocentini, PhD Mathematician (algebraic combinatorics, formal methods for algs) Programmer (automated reasoning, logics and symbolic comp) https://github.com/massimo-nocentini/dancinglinksst In Donald’s words1 : Suppose x points to an element of a doubly linked list; let L[x] and R[x] point to the predecessor and successor of that element. Then: L[R[x]] ← L[x], R[L[x]] ← R[x] (1) remove x from the list; every programmer knows this. But comparatively few programmers have realized that L[R[x]] ← x, R[L[x]] ← x (2) will put x back again, with no refs to the whole list at all. 1https://arxiv.org/abs/cs/0011047
  • 5. Main ideas Operation (2) arises in backtrack programs, which enumerate all solutions to a given set of constraints and it was introduced in 1979 by Hitotumatu and Noshita. The beauty of (2) is that operation (1) can be undone by knowing only the value of x. We can apply (1) and (2) repeatedly in complex data structures that involve large numbers of interacting doubly linked lists. Knuth: “This process causes the pointer variables inside the global data structure to execute an exquisitely choreographed dance; hence I like to call (1) and (2) the technique of dancing links.” Minato et al. 2 constructs a Zero-suppressed BDD (ZDD) that represents the set of sols and it enables the efficient use of memo cache to speed up the search. 2https://aaai.org/ocs/index.php/AAAI/AAAI17/paper/view/14907
  • 6. DoubleLinks and DoubleLinkedLists DoubleLink objects respond to messages remove nextLink ifNotNil: [ :next | next previousLink: previousLink ]. previousLink ifNotNil: [ :previous | previous nextLink: nextLink ] and restore nextLink ifNotNil: [ :next | next previousLink: self ]. previousLink ifNotNil: [ :previous | previous nextLink: self ] that implement operations (1) and (2), respectively; moreover, we extend DoubleLinkedList objects with the message makeCircular head ifNotNil: [ head previousLink: tail. tail nextLink: head ] to introduce circular, doubly connected, lists.
  • 7. Exact Cover ∈ NP Given a matrix of 0s and 1s, does it have a set of rows containing exactly one symbol 1 in each column? The problem with matrix       r1 r2 r3 r4 r5       T       1 1 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 1 0 1 0       =         1 1 1 1 1 1         T is solved by two sets of rows, namely {r1 = 1, r3 = 1} and {r2 = 1, r5 = 1, r3 = 1}. We can think of the columns as elements of a universe, and the rows as subsets of the universe; then the problem is to cover the universe with disjoint subsets, NP-complete even when each row contains exactly three 1s.
  • 9. AlgorithmX instance side searchDepth: k forDLRootObject: h partialSelection: cont ^ (h isFixPointOf: [ :ro | ro right ]) ifTrue: [ self yieldNode: top onBlock: cont ] ifFalse: [ memo at: h columns ifPresent: [ :tree | self yieldNode: tree onBlock: cont ] ifAbsentPut: [ self searchDepth: k forDLColumnObject: h chooseColumn partialSelection: cont ] ]
  • 10. AlgorithmX instance side searchDepth: k forDLColumnObject: c partialSelection: sel ^ self onEnter: [ c cover ] do: [ c untilFixPointOf: [ :co | co up ] foldr: [ :r :x | | y | y := self searchDepth: k forDLDataObject: r partialSelection: sel. y isZDDBottom ifTrue: [ x ] ifFalse: [ self uniqueNodeWithDLDataObject: r withLowerNode: x withHigherNode: y ] ] init: bottom ] onExit: [ c uncover ]
  • 11. AlgorithmX instance side searchDepth: k forDLDataObject: r partialSelection: cont ^ self onEnter: [ r untilFixPointOf: [ :ro | ro right ] do: [ :j | j column cover ] ] do: [ self searchDepth: k + 1 forDLRootObject: r column root partialSelection: [ :sel | cont value: (ValueLink new value: r model; nextLink: sel; yourself) ] ] onExit: [ r untilFixPointOf: [ :ro | ro left ] do: [ :j | j column uncover ] ]
  • 12. AlgorithmX instance side The entry point is the message searchDLRootObject: h onSolutionDo: aBlock ^ self searchDepth: 0 forDLRootObject: h partialSelection: [ :selLink | aBlock value: (LinkedList new add: selLink; asSet) ] Knuth advices to use the heuristic (provided by DLRootObject objs) chooseColumn ^ self chooseColumnWithWeight: #size withOpt: #< chooseColumnWithWeight: weightBlock withOpt: optBlock ^ self untilFixPointOf: [ :ro | ro left ] foldr: [ :j :r | (optBlock value: (weightBlock value: j) value: (weightBlock value: r)) ifTrue: [ j ] ifFalse: [ r ] ] init: self right that minimizes the search tree’s branching factor.
  • 13. DLColumnObject instance side The operation of covering column c removes c from the header list and removes all rows in c’s own list from the other column lists they are in. cover we remove. self untilFixPointOf: [ :co | co down ] do: [ :i | i untilFixPointOf: [ :do | do right ] do: [ :j | j nsLink remove. j column updateSize: [ :s | s - 1 ] ] ] Operation (1) is used here to remove objects in both the horizontal and vertical directions.
  • 14. DLColumnObject instance side Finally, we get to the operation of uncovering a given column c. Here is where the links do their dance: uncover self untilFixPointOf: [ :co | co up ] do: [ :i | i untilFixPointOf: [ :do | do left ] do: [ :j | j nsLink restore. j column updateSize: [ :s | s + 1 ] ] ]. we restore Notice that uncovering takes place in precisely the reverse order of the covering operation, using the fact that (2) undoes (1).
  • 15. Sudoku to Exact Cover reduction emptySudokuIndicators | ones start end | start := 0. end := 8. ones := LinkedList new. start to: end do: [ :row | start to: end do: [ :column | start to: end do: [ :value | | rowIndex cellConstraint rowConstraint columnConstraint boxConstraint model | model := {(#x -> row). (#y -> column). (#v -> value)} asDictionary. rowIndex := 81 * row + (9 * column) + value. cellConstraint := rowIndex @ ((end + 1) * row + column). rowConstraint := rowIndex @ (9 * row + value + 81). columnConstraint := rowIndex @ (9 * column + value + (81 * 2)). boxConstraint := rowIndex @ (27 * (row // 3) + (9 * (column // 3)) + value + (81 * 3)). ones add: ((cellConstraint + 1) asDLPoint primary: true) -> model; add: ((rowConstraint + 1) asDLPoint primary: true) -> model; add: ((columnConstraint + 1) asDLPoint primary: true) -> model; add: ((boxConstraint + 1) asDLPoint primary: true) -> model ] ] ]. ^ ones
  • 16. Soduku solutions testDLXonSudoku | grid sols chain matrices | grid := DLDataObject gridOn: DLDataObjectTest new emptySudokuIndicators. chain := Generator on: [ :g | AlgorithmX new searchDLRootObject: (grid at: #root) onSolutionDo: [ :sel | g yield: sel ] ]. sols := (chain next: 2) contents. matrices := sols collect: [ :sol | "build the corresponding matrix" ]. self assert: matrices first printString equals: '(9 8 7 6 5 4 3 2 1 6 5 4 3 2 1 9 8 7 3 2 1 9 8 7 6 5 4 8 9 6 7 4 5 2 1 3 7 4 5 2 1 3 8 9 6 2 1 3 8 9 6 7 4 5 5 7 9 4 6 8 1 3 2 4 6 8 1 3 2 5 7 9 1 3 2 5 7 9 4 6 8 )'.
  • 17. N-Queens to Exact Cover reduction NQueensIndicators: n | ones | ones := LinkedList new. 0 to: n - 1 do: [ :row | 0 to: n - 1 do: [ :column | | rowIndex rowConstraint columnConstraint diagonalConstraint antiDiagonalConstraint model | model := Dictionary new at: #x put: row; at: #y put: column; yourself. rowIndex := n * row + column. rowConstraint := rowIndex @ row. columnConstraint := rowIndex @ (n + column). diagonalConstraint := rowIndex @ (2 * n + (row + column)). antiDiagonalConstraint := rowIndex @ (2 * n + (2 * n) - 1 + (n - 1 - row + column)). ones add: ((rowConstraint + 1) asDLPoint primary: true) -> model; add: ((columnConstraint + 1) asDLPoint primary: true) -> model; add: ((diagonalConstraint + 1) asDLPoint primary: false) -> model; add: ((antiDiagonalConstraint + 1) asDLPoint primary: false) -> model ^ ones
  • 18. N-Queens solutions testDLXon_NQueens_sequence | seq elapsedTime | elapsedTime := [ seq := (1 to: 10) collect: [ :i | (self runDLXonNQueens: i next: nil) size ] ] timeToRun. self assert: elapsedTime < 2 asSeconds. self assert: seq "also known as https://oeis.org/A000170" equals: {1 . 0 . 0 . 2 . 10 . 4 . 40 . 92 . 352 . 724} testDLXon_8Queens | matrices | matrices := self runDLXonNQueens: 8 next: 1. self assert: matrices first printString equals: '(0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 )'.
  • 19. Final remarks We presented a vanilla implementation of DLX with the ZDD extension in pure Smalltalk, with an educational savor. It is designed to be easy to understand and to play with still remaining efficient and robust. Dancing links are considered the state-of-the-art heuristic for EC :) Knuth is still actively working on this (a new fascicle is in prep 3 ) :( Constraints are verbose and rigid to express (currently we use Point objs), looking for a DSL that makes coding constraints easier TODO Group column objects using different colours to gain expressivity Write reductions to Exact Cover (from 3SAT, Knapsack, TSP, ...) 3https://cs.stanford.edu/~knuth/fasc5c.ps.gz
  • 21. yieldNode: tree onBlock: cont tree sets collect: [ :each | (each collect: #model) as: LinkedList ] thenDo: [ :sel | | link | link := sel isEmpty ifTrue: [ nil ] ifFalse: [ sel firstLink ]. cont value: link ]. ^ tree uniqueNodeWithDLDataObject: r withLowerNode: x withHigherNode: y | key | key := Array with: r with: x with: y. ^ zDDTree at: key ifAbsentPut: [ | z | z := ZDDNode new model: r; lower: x; higher: y; yourself. x parent: z. y parent: z. z ]
  • 22. DLDataObject class side gridOn: aCollection | rootObj columns rows headers allObjs | aCollection sort: [ :vAssoc :wAssoc | | v w | v := vAssoc key. w := wAssoc key. v y <= w y and: [ v x <= w x ] ]. allObjs := Dictionary new. headers := DoubleLinkedList new. columns := Dictionary new. rows := Dictionary new. rootObj := DLRootObject new addInDoubleLinkedList: headers direction: #we; yourself. allObjs at: #root put: rootObj. "to be contd..."
  • 23. DLDataObject class side gridOn: aCollection "...contd..." aCollection do: [ :anAssociation | | aPoint columnObj dataObj column row | aPoint := anAssociation key. column := columns at: aPoint y ifAbsentPut: [ | headerObj newColumn | headerObj := DLColumnObject new size: 0; root: rootObj; yourself. aPoint primary ifTrue: [ headerObj addInDoubleLinkedList: headers direction: #we ] ifFalse: [ DoubleLinkedList circular: [ :dll | headerObj addInDoubleLinkedList: dll direction: #we ] ]. newColumn := DoubleLinkedList new. headerObj addInDoubleLinkedList: newColumn direction: #ns. allObjs at: aPoint y put: headerObj. newColumn ]. "..to be contd further..."
  • 24. DLDataObject class side gridOn: aCollection "...contd" columnObj := column first. dataObj := DLDataObject new column: columnObj; point: aPoint; model: anAssociation value; yourself. row := rows at: aPoint x ifAbsentPut: [ DoubleLinkedList new ]. dataObj addInDoubleLinkedList: column direction: #ns; addInDoubleLinkedList: row direction: #we. columnObj updateSize: [ :s | s + 1 ]. allObjs at: aPoint put: dataObj ]. headers makeCircular. columns valuesDo: #makeCircular. rows valuesDo: #makeCircular. ^ allObjs