<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Flying memes &#187; Dancing Links</title>
	<atom:link href="http://sandropaganotti.com/tag/dancing-links/feed/" rel="self" type="application/rss+xml" />
	<link>http://sandropaganotti.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sun, 08 Jan 2012 16:00:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Ruby-dlx, le otto regine e le colonne secondarie</title>
		<link>http://sandropaganotti.com/2008/12/16/ruby-dlx-le-otto-regine-e-le-colonne-secondarie/</link>
		<comments>http://sandropaganotti.com/2008/12/16/ruby-dlx-le-otto-regine-e-le-colonne-secondarie/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 21:39:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[8 regine]]></category>
		<category><![CDATA[Dancing Links]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ruby-dlx]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=73</guid>
		<description><![CDATA[Eravamo rimasti al seguente quesito: &#8220;Come implementiamo l&#8217;insieme di costrizioni che abbiamo evinto in modo da risolvere il problema delle 8 regine con i Dancing Links ?&#8221; Guardiamo insieme il codice di &#8216;dancing_links_queens.rb&#8216;: def initialize() labels = (1..42).to_a @dla = DancingLinksArena.new(labels,[false]*16 + [true]*26) given_list = [] row_data = [] 8.times do &#124;x&#124; 8.times do &#124;y&#124; [...]]]></description>
			<content:encoded><![CDATA[<p>Eravamo rimasti al seguente quesito: &#8220;Come implementiamo l&#8217;insieme di costrizioni che abbiamo evinto in modo da risolvere il problema delle 8 regine con i Dancing Links ?&#8221;</p>
<p><span id="more-73"></span><br />
Guardiamo insieme il codice di &#8216;<a href="http://github.com/sandropaganotti/ruby-dlx/tree/master/examples/8queens/dancing_links_queens.rb">dancing_links_queens.rb</a>&#8216;:</p>
<pre><code class="ruby">def initialize()
    labels = (1..42).to_a
    @dla = DancingLinksArena.new(labels,[false]*16 + [true]*26)
    given_list = []
    row_data = []

    8.times do |x|
      8.times do |y|
        row_data[0] = x+1
        row_data[1] = y+1 + 8
        row_data &lt;&lt;  ((y+1) - (x+1)) + 7  + 16  unless [-7,7].include?(y - x)
        row_data &lt;&lt;  (x + y + 2) - 2 + 13 + 16  unless [0,14].include?(x + y)
        new_row = @dla.add_initial_row(row_data)
        row_data = []
      end
    end
  end
</code></pre>
<p>Nella prima riga creo un array di 42 elementi ( 8 righe + 8 colonne + 13 diagonali da sx a dx + 13 diagonali da dx a sx ), da notare che considero solo 13 diagonali per direzione ( e non 15 ) perchè 2 contengono un solo elemento. Ognuno di questi 42 elementi diverrà una colonna nella matrice DLX.</p>
<p>Nella seconda riga creo un oggetto &#8216;Dancing Links&#8217; al quale passo l&#8217;array di etichette e un array di 16 &#8216;true&#8217; e 26 &#8216;false&#8217;, questo perchè le prime 16 colonne sono primarie (cioè dovranno contenere esattamente un 1) mentre le ultime 26 sono secondarie (cioè possono contenere o 0 o 1 elemento). Questa scelta è stata dettata dal fatto che mentre per ogni riga e ogni colonna della scacchiera dovrà necessariamente essere presente una regina, lo stesso non è valido per ogni diagonale ( abbiamo solo 8 regine e 26 diagonali&#8230; ).</p>
<p>Ora mi resta solo da impostare per ognuna delle 64 caselle della scacchiera le relative costrizioni ed aggiungerle alla DLA, nel dettaglio per ogni casella devo specificare il &#8216;nome&#8217; (da 1 a 42) dei label corrispondenti alla costrazione che definisce tale casella; facciamo un esempio, per la casella 1-1 questi sono i label interessati:</p>
<ul>
<li>il label 1 che corrisponde alla riga 1</li>
<li>il label 9 che corrisponde alla colonna 1</li>
<li>il label 36 che identifica la diagonale che interessa la casella 1-1</li>
</ul>
<p>Potete visionare e testare l&#8217;esempio completo sul <a href="http://github.com/sandropaganotti/ruby-dlx/tree/master/examples/8queens/dancing_links_queens.rb">mio account di github</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2008/12/16/ruby-dlx-le-otto-regine-e-le-colonne-secondarie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Risolvere i Sudoku in Ruby con i Dancing Links: ruby-dlx</title>
		<link>http://sandropaganotti.com/2008/12/02/risolvere-i-sudoku-in-ruby-con-i-dancing-links-ruby-dlx/</link>
		<comments>http://sandropaganotti.com/2008/12/02/risolvere-i-sudoku-in-ruby-con-i-dancing-links-ruby-dlx/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 21:40:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Librerie]]></category>
		<category><![CDATA[Dancing Links]]></category>
		<category><![CDATA[Library]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=57</guid>
		<description><![CDATA[Ho appena effettuato il commit della prima release funzionante di ruby-dlx. Ruby dlx è una piccola libreria che implementa in Ruby l&#8217;algoritmo dei Dancing Links descritto nel post di settimana scorsa. Per rendere il tutto più utilizzabile ho inoltre allegato alla libreria anche un esempio: un piccolo programma che usando la matrice di costrizione spiegata [...]]]></description>
			<content:encoded><![CDATA[<p>Ho appena effettuato il commit della prima release funzionante di <a href="http://github.com/sandropaganotti/ruby-dlx/tree/master">ruby-dlx</a>. Ruby dlx è una piccola libreria che implementa in Ruby l&#8217;algoritmo dei Dancing Links descritto nel <a href="http://sandropaganotti.com/2008/11/23/knuth-e-i-dancing-links/">post di settimana scorsa</a>.</p>
<p><span id="more-57"></span></p>
<p>Per rendere il tutto più utilizzabile ho inoltre allegato alla libreria anche un esempio: un piccolo programma che usando la matrice di costrizione spiegata <a href="http://sandropaganotti.com/2008/11/14/un-algoritmo-per-creare-sudoku/">nell&#8217;articolo di due settimane fa</a> è capace di risolvere un Sudoku.</p>
<p>Potete trovare questo programma all&#8217;interno del mio repository di GitHub, nella sottocartella <a href="http://github.com/sandropaganotti/ruby-dlx/tree/master/examples/sudoku">examples/sudoku</a>; per eseguirlo lanciate il file sudoku.rb.</p>
<p>La settimana prossima proporrò un tutorial nel quale utilizzeremo questa libreria per risolvere  il famosissimo <a href="http://it.wikipedia.org/wiki/Rompicapo_delle_otto_regine">problema delle otto regine</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2008/12/02/risolvere-i-sudoku-in-ruby-con-i-dancing-links-ruby-dlx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Knuth e i dancing links</title>
		<link>http://sandropaganotti.com/2008/11/23/knuth-e-i-dancing-links/</link>
		<comments>http://sandropaganotti.com/2008/11/23/knuth-e-i-dancing-links/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 21:20:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Algorithm X]]></category>
		<category><![CDATA[Dancing Links]]></category>
		<category><![CDATA[DLX]]></category>
		<category><![CDATA[Knuth]]></category>
		<category><![CDATA[ruby-dlx]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=49</guid>
		<description><![CDATA[Nel post precedente cercando di trovare un algoritmo interessante per la generazione di Sudoku mi sono imbattuto nei Dancing Links. L&#8217;algoritmo DLX è stato inventato da Donald Knuth (il pdf originale è disponibile gratuitamente) ed è essenzialmente un&#8217;implementazione performante di un algoritmo di backtracking (Algoritmo X). L&#8217;algoritmo X si applica a problemi chiamati &#8216;Exact Cover [...]]]></description>
			<content:encoded><![CDATA[<p>Nel post precedente cercando di trovare un algoritmo interessante per la generazione di Sudoku mi sono imbattuto nei Dancing Links.</p>
<p>L&#8217;algoritmo DLX è stato inventato da <a href="http://www-cs-faculty.stanford.edu/~knuth/">Donald Knuth</a> (il pdf originale è <a href="http://lanl.arxiv.org/pdf/cs/0011047 ">disponibile gratuitamente</a>) ed è essenzialmente un&#8217;implementazione performante di un algoritmo di backtracking (Algoritmo X).</p>
<p><span id="more-49"></span></p>
<p>L&#8217;algoritmo X si applica a problemi chiamati &#8216;Exact Cover Problems&#8217;; tali problemi presentano (genericamente) questo enunciato:</p>
<blockquote><p>Data una matrice di soli &#8217;0&#8242; e &#8217;1&#8242; è possibile trovare un sottoinsieme di righe tali che per ogni colonna vi sia uno e uno solo &#8217;1&#8242; ?</p></blockquote>
<p>L&#8217;approccio dell&#8217;algoritmo X per risolvere un problema come questo è il seguente (data una matrice A):</p>
<ol>
<li>Se A è vuota il problema è risolto</li>
<li>Altrimenti scegli una colonna c</li>
<li>Scegli una riga r, tale che A[r,c] = 1</li>
<li>Includi r nella soluzione parziale</li>
<li>Per ogni j che soddisfi A[r,j] = 1
<ol>
<li>cancella la colonna j da A</li>
<li>Per ogni i che soddisfi A[i,j] = 1
<ol>
<li>cancella la riga i da A</li>
</ol>
</li>
</ol>
</li>
<li>Ripeti questo algoritmo iterativamente sulla matrice A così ridotta</li>
</ol>
<p>Il problema che rende questo algoritmo molto più laborioso di quanto non sembri è il punto 3. Knuth ci spiega infatti che la scelta della riga r determina la solvibilità o meno del problema (cioè se scegliamo la r giusta il problema si risolve, altrimenti no); questo ci costringe a provare iterativamente tutte le r candidate fino a che non troviamo quella giusta (il che equipara l&#8217;algoritmo X ad un algoritmo di backtracking).</p>
<p>I Dancing Links aiutano a velocizzare (in termini di esecuzione) l&#8217;algoritmo X offrendo una struttura di memorizzazione dati molto intelligente; Supponiamo di memorizzare solo gli &#8217;1&#8242; della matrice A, e di farlo nel seguente modo:</p>
<ol>
<li>Creiamo un&#8217;oggetto Nodo che contiene 4 puntatori ad altrettanti oggetti nodi (su,giu,sinistra e destra) e un puntatore ad un oggetto Colonna.</li>
<li>Creiamo un oggetto Colonna &lt; Nodo con in più alcune informazioni sulla quantità di nodi che contiene (diciamo un campo size).</li>
<li>Creiamo un&#8217;istanza un pò particolare dell&#8217;oggetto colonna (diciamo colonna 0) che punti al primo oggetto colonna della nostra matrice.</li>
</ol>
<p>Il risultato è illustrato egregiamente a pagina 6 del <a href="http://lanl.arxiv.org/pdf/cs/0011047">pdf originale di Knuth</a>.</p>
<p>Ma&#8230; dove risiede la velocità nell&#8217;operare su una struttura simile ? Se pensate ad un classico algoritmo di backtracking ricorderete che la parte più difficile/onerosa da gestire era quella legata al ripristino dello stato del sistema all&#8217;istante n (questo avveniva ogni volta che si realizzava che i passaggi n+1..n+k non portavano ad una soluzione).</p>
<p>Con i Dancing Links invece il tutto è leggermente più semplice, pensiamo infatti all&#8217;operazione &#8216;Inserisco un nodo&#8217;:</p>
<ol>
<li>Prendo x: un nodo da inserire tra i nodi k e m</li>
<li>k.giu = x</li>
<li>m.su = x</li>
<li>x.su  = k</li>
<li>x.giu = m</li>
<li>(k.colonna (equivalente a m.colonna)).size += 1</li>
</ol>
<p>In questo breve pseudocodice ho escluso i puntatori destra e sinistra ma ormai il funzionamento dovrebbe essere abbastanza chiaro.</p>
<h3>Il tutto in Ruby</h3>
<p>Ho appena finito il porting dell&#8217;<a href="http://www.bluechromis.com/stan/chesnutt.html">algorimo DLX implementato da Stan Chesnutt</a> nel suo &#8216;Sudoku Solver&#8217; in linguaggio Ruby, per il momento potete trovare tutti i sorgenti <a href="http://github.com/sandropaganotti">alla mia pagina di GitHub</a>, nel prossimo articolo utilizzeremo quanto creato per sviluppare il risolvi-sudoku, che a sua volta verrà poi utilizzato per il più ambizioso genera-sudoku.</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2008/11/23/knuth-e-i-dancing-links/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Un algoritmo per creare Sudoku?</title>
		<link>http://sandropaganotti.com/2008/11/14/un-algoritmo-per-creare-sudoku/</link>
		<comments>http://sandropaganotti.com/2008/11/14/un-algoritmo-per-creare-sudoku/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 21:54:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[Dancing Links]]></category>
		<category><![CDATA[Sudoku]]></category>

		<guid isPermaLink="false">http://sandropaganotti.com/?p=35</guid>
		<description><![CDATA[Da un paio di settimane stò studiando un pò il mondo che contorna questi simpatici puzzles con l&#8217;obiettivo di creare un generatore di Sudoku in Ruby. La prima cosa che ho scoperto è che non è stato ancora dimostrato il numero minimo di cifre che è necessario esporre (cioè visualizzare &#8216;completate&#8217; all&#8217;inizio del puzzle) per [...]]]></description>
			<content:encoded><![CDATA[<p>Da un paio di settimane stò studiando un pò il mondo che contorna questi simpatici puzzles con l&#8217;obiettivo di creare un generatore di Sudoku in Ruby.</p>
<p>La prima cosa che ho scoperto è che non è stato ancora dimostrato il numero minimo di cifre che è necessario esporre (cioè visualizzare &#8216;completate&#8217; all&#8217;inizio del puzzle) per garantire al Sudoku una soluzione univoca; al momento sono stati trovati<a href="http://en.wikipedia.org/wiki/Image:Sudoku_puzzle_hard_for_brute_force.jpg"> Sudoku validi con 17 cifre esposte.</a></p>
<p>Ma come si determina quando un Sudoku ha una soluzione univoca?</p>
<p><span id="more-35"></span>Il primo articolo che ho trovato in questo senso è una pubblicazione scientifica chiamata <a class="external text" title="http://www.ams.org/notices/200706/tx070600708p.pdf" rel="nofollow" href="http://www.ams.org/notices/200706/tx070600708p.pdf">Sudoku Squares and Chromatic Polynomials</a> che si &#8216;limita&#8217; a dimostrare che per garantire una soluzione univoca un Sudoku deve avere, tra le sue celle esposte, almeno 8 delle 9 cifre.</p>
<p>E&#8217; stato inoltre dimostrato che per avere una soluzione univoca un Sudoku deve necessariamente esporre almeno una casella all&#8217;interno <a href="http://en.wikipedia.org/wiki/Image:Mask_of_non_legal_sudoku.JPG">dell&#8217;area illustrata in questa immagine</a>.</p>
<p>Chiaramente queste due dimostrazioni mi aiutano soltanto ad escludere a priori alcuni Sudoku ma non mi danno garanzie ne in un senso ne nell&#8217;altro nel caso che il mio puzzle superi le richieste espresse; in questo caso sembra che un buon modo per valutare l&#8217;unicità delle soluzioni du un Sudoku sia il DLX ovvero il metodo dei Dancing Links</p>
<h3>I Dancing Links:</h3>
<p>La <a href="http://en.wikipedia.org/wiki/Dancing_Links">tecnica dei Dancing Links</a> è stata inventata da <a href="http://en.wikipedia.org/wiki/Donald_Knuth">Donald Knuth</a> come metodo risolutivo per l&#8217;<a href="http://en.wikipedia.org/wiki/Algorithm_X">Algoritimo X</a> da lui stesso inventato. Secondo questa interpretazione il problema posto dai Sudoku viene visto come una serie di vincoli che legano gruppi di possibili valori.</p>
<p>Cerco di spiegarmi: per ogni Sudoku esistono 81 caselle, ognuna delle quali può ospitare 9 cifre (nel senso che sono virtualmente nove le cifre che concorrono ad insediare una casella), quindi possiamo dire che:</p>
<pre><code class="javascript">
R1C1 = {R1C1#1 R1C1#2 R1C1#3 R1C1#4 R1C1#5 R1C1#6 R1C1#7 R1C1#8 R1C1#9 }
R1C2 = {R1C2#1 R1C2#2 R1C2#3 R1C2#4 R1C2#5 R1C2#6 R1C2#7 R1C2#8 R1C2#9 }
...
R9C9 = {R9C9#1 R9C9#2 R9C9#3 R9C9#4 R9C9#5 R9C9#6 R9C9#7 R9C9#8 R9C9#9 }
</code></pre>
<p>cioè che per la prima casella in alto a sx ( R1C1: Riga 1 Colonna 1 ) ci sono 9 potenziali valori (marcati come R1C1#1..R1C1#9), lo stesso discorso si può fare per tutte le altre 80 celle ottenendo un numero complessivo di 81(celle) * 9(potenziali valori per cella) = 729 elementi del tipo &#8220;RxCy#z.</p>
<p>Ora che abbiamo definito questo primo set di vincoli (bhe, sono vincoli a tutti gli effetti; abbiamo assegnato ad ogni cella un particolare sottoinsieme di valori potenziali) possiamo prendere in considerazione le altre regole sancite da questo gioco:</p>
<h4>Per ogni colonna ogni cifra può comparire una sola volta:</h4>
<p>Modellizziamo questa regola usando la sintassi precedente ed associando ad ogni coppia (colonna/valore) i valori potenziali che la soddisfano:</p>
<pre><code class="javascript">
C1#1 = {R1C1#1, R2C1#1, R3C1#1, R4C1#1, R5C1#1, R6C1#1, R7C1#1, R8C1#1, R9C1#1}
C1#2 = {R1C1#2, R2C1#2, R3C1#2, R4C1#2, R5C1#2, R6C1#2, R7C1#2, R8C1#2, R9C1#2}
...
C9#9 = {R1C9#9, R2C9#9, R3C9#9, R4C9#9, R5C9#9, R6C9#9, R7C9#9, R8C9#9, R9C9#9}
</code></pre>
<p>Anche qui, come nel caso precedente definiamo i valori potenziali che si candidano a soddisfare le coppie colonna/valore.</p>
<h4>Per ogni riga una cifra può comparire una sola volta:</h4>
<p>Ripetiamo lo stesso ragionamento fatto per le colonne stavolta per le righe:</p>
<pre><code class="javascript">
R1#1 = {R1C1#1, R1C2#1, R1C3#1, R1C4#1, R1C5#1, R1C6#1, R1C7#1, R1C8#1, R1C9#1}
R1#2 = {R1C1#2, R1C2#2, R1C3#2, R1C4#2, R1C5#2, R1C6#2, R1C7#2, R1C8#2, R1C9#2}
...
R9#9 = {R9C1#9, R9C2#9, R9C3#9, R9C4#9, R9C5#9, R9C6#9, R9C7#9, R9C8#9, R9C9#9}
</code></pre>
<h4>In ognuno dei 9 box 3&#215;3 ogni cifra può comparire una sola volta:</h4>
<p>Il ragionamento è di nuovo lo stesso ma questa volta elenchiamo i valori potenziali per ogni coppia (box/valore); chiamiamo il box con la sintassi B1..B9:</p>
<pre><code class="javascript">
B1#1 = {R1C1#1, R1C2#1, R1C3#1, R2C1#1, R2C2#1, R2C3#1, R3C1#1, R3C2#1, R3C3#1}
B1#2 = {R1C1#2, R1C2#2, R1C3#2, R2C1#2, R2C2#2, R2C3#2, R3C1#2, R3C2#2, R3C3#2}
...
B9#9 = {R7C7#9, R7C8#9, R7C9#9, R8C7#9, R8C8#9, R8C9#9, R9C7#9, R9C8#9, R9C9#9}
</code></pre>
<h4>Conclusioni (per questo episodio):</h4>
<p>Se proviamo a fare due conti scopriremo che abbiamo definito 81(cella/valori) + 81(colonna/valore) + 81(riga/valore) + 81(box/valore) = 81 x 4 = 324 vincoli. Ognuno di questi vincoli coinvolge 9 valori potenziali quindi per ogni valore potenziale esistono sempre 4 vincoli.</p>
<p>E&#8217; possibile rappresentare tutti questi vincoli in una matrice che riporti sulle colonne i suddetti vincoli (quindi R1C1..R9C9,C1#1..C9#9,R1#1..R9#9,B1#1..B9#9) e sulle righe tutti i valori potenziali (R1C1#1..R9C9#9). Ad ogni cella di questa matrice si andrà poi ad inserire un 1 nel caso che il vincolo specificato incida sul valore potenziale ed uno zero altrimenti.</p>
<p>Bob Hanson ha <a href="http://www.stolaf.edu/people/hansonr/sudoku/exactcovermatrix.htm">creato e pubblicato la matrice completa</a>.</p>
<p>Nel prossimo capitolo (che spero vivamente di postare tra sette giorni) scopriremo come risolvere un Sudoku, e &#8211; cosa importante &#8211; accertarci che tale soluzione sia univoca, usando la tecnica dei Dancing Links.</p>
<p>Sandro</p>
]]></content:encoded>
			<wfw:commentRss>http://sandropaganotti.com/2008/11/14/un-algoritmo-per-creare-sudoku/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

