<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>dijkstra &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/dijkstra/</link>
	<description>Feed of posts on WordPress.com tagged "dijkstra"</description>
	<pubDate>Fri, 04 Dec 2009 11:40:35 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[[Perancangan Peta 3 Dimensi] Part 8 – Path Finder (pencarian Jalur terpendek)]]></title>
<link>http://asyadeeq.wordpress.com/2009/11/14/perancangan-peta-3-dimensi-part-8-%e2%80%93-path-finder-pencarian-jalur-terpendek/</link>
<pubDate>Sat, 14 Nov 2009 03:23:13 +0000</pubDate>
<dc:creator>asyadeeq</dc:creator>
<guid>http://asyadeeq.wordpress.com/2009/11/14/perancangan-peta-3-dimensi-part-8-%e2%80%93-path-finder-pencarian-jalur-terpendek/</guid>
<description><![CDATA[Hallo .. Skripsi sudah selesai, dokumen2 syarat kelulusan hampir beres, tinggal nunggu wisuda 15 des]]></description>
<content:encoded><![CDATA[Hallo .. Skripsi sudah selesai, dokumen2 syarat kelulusan hampir beres, tinggal nunggu wisuda 15 des]]></content:encoded>
</item>
<item>
<title><![CDATA[Algoritmo de Dijkstra, solucion por Software]]></title>
<link>http://cmop17.wordpress.com/2009/08/30/algoritmo-de-dijkstra-solucion-por-software/</link>
<pubDate>Sun, 30 Aug 2009 08:08:33 +0000</pubDate>
<dc:creator>Cmop</dc:creator>
<guid>http://cmop17.wordpress.com/2009/08/30/algoritmo-de-dijkstra-solucion-por-software/</guid>
<description><![CDATA[dijkstra El algoritmo de Dijkstra, también llamado algoritmo de caminos mínimos, es un algoritmo par]]></description>
<content:encoded><![CDATA[dijkstra El algoritmo de Dijkstra, también llamado algoritmo de caminos mínimos, es un algoritmo par]]></content:encoded>
</item>
<item>
<title><![CDATA[Algorithms for Web Developers]]></title>
<link>http://webunderconstruction.wordpress.com/2009/08/21/algorithms-for-web-developers/</link>
<pubDate>Fri, 21 Aug 2009 17:45:55 +0000</pubDate>
<dc:creator>Mobu</dc:creator>
<guid>http://webunderconstruction.wordpress.com/2009/08/21/algorithms-for-web-developers/</guid>
<description><![CDATA[Referring to my post below, I was thinking about the algorithms that actually have practical usage i]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Referring to my post below, I was thinking about the algorithms that actually have practical usage in the field of web developing. I would really appreciate any help for pointing me towards some of the algorithms.</p>
<p>To call yourself even a programmer, the most important structure in programming you should know is the &#8220;loop&#8221;. Yes, some even go further and say that those who can use loops effeciently have the rights to call themselves programmers. But I am going ahead. Here are the basic list of algorithms that you should know how to implement:</p>
<ol>
<li>Binary Search</li>
<li>Any sorting algorithm (such as mergsort, quicksort, heapsort etc.)</li>
<li>Union-Find (think about Social network and you will get the idea)</li>
<li>Encryption algorithm (RSA, DES, Blowfish or whatever you know)</li>
<li>Dijkstra&#8217;s algorithm (really useful in figuring out the shortest path)</li>
</ol>
<p>Remember, master these basic algorithms and then step up to the advanced algorithms. Do you know why Google is famous? They are famous because they&#8217;ve invented a simple but elegant solution to searching. Clearly, the developers had to go through all the basic algorithms to create something so sophisticated.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Analisi e implementazione dell'algoritmo di Dijkstra (Parte 1)]]></title>
<link>http://algoritmicamente.wordpress.com/2009/08/01/analisi-e-implementazione-dellalgoritmo-di-dijkstra-parte-1/</link>
<pubDate>Sat, 01 Aug 2009 11:01:14 +0000</pubDate>
<dc:creator>memoclaudio</dc:creator>
<guid>http://algoritmicamente.wordpress.com/2009/08/01/analisi-e-implementazione-dellalgoritmo-di-dijkstra-parte-1/</guid>
<description><![CDATA[In questo articolo viene descritto passo per passo l&#8217;algoritmo di Dijkstra, con relativi esemp]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In questo articolo viene descritto passo per passo l&#8217;algoritmo di Dijkstra, con relativi esempi per renderne più semplice la compresione . Per leggere tale articolo non serve nessuna base teorica in quanto tutto ciò che serve viene data nell&#8217;articolo, è comunque VIVAMENTE CONSIGLIATO approfondire le conoscenze teoriche.</p>
<p>Nel primo paragrafo vengono date le basi teoriche sui grafi, nel secondo basi teoriche sui cammini e sui cammini minimi e infine ( nel terzo paragrafo) vi è una completa analisi dell&#8217;algoritmo.</p>
<p><a title="Analisi e implementazione dell'algoritmo di Dijkstra (Parte 1)" href="http://algoritmicamente.wordpress.com/files/2009/08/analisi_dijkstra.pdf" target="_blank">Scarica l&#8217;articolo</a></p>
<p>Commenti consigli e critiche sono vivamente accettati!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Der Weg ist das Ziel - Mit Dijkstra von Java nach Scala]]></title>
<link>http://dgronau.wordpress.com/2009/07/29/der-weg-ist-das-ziel-mit-dijkstra-von-java-nach-scala/</link>
<pubDate>Wed, 29 Jul 2009 20:24:47 +0000</pubDate>
<dc:creator>dgronau</dc:creator>
<guid>http://dgronau.wordpress.com/2009/07/29/der-weg-ist-das-ziel-mit-dijkstra-von-java-nach-scala/</guid>
<description><![CDATA[Erst einmal ein Nachtrag zu meinem letzten Beitrag: Auch in teutschen Landen tut sich etwas in Sache]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Erst einmal ein Nachtrag zu meinem letzten Beitrag: Auch in teutschen Landen tut sich etwas in Sachen Scala. Noch nicht erschienen ist das <a href="http://www.amazon.de/gp/product/3446418636?ie=UTF8&#38;tag=danigron-21&#38;linkCode=as2&#38;camp=1638&#38;creative=6742&#38;creativeASIN=3446418636">Praxisbuch Scala: Programmieren in Scala für Ein- und Umsteiger</a><img src="http://www.assoc-amazon.de/e/ir?t=danigron-21&#38;l=as2&#38;o=3&#38;a=3446418636" width="1" height="1" border="0" alt="" style="border:none!important;margin:0!important;" />. In der deutschsprachigen Blogosphäre bin ich auf dieses <a href="http://scala2.blog.de/">Scala Blog</a> gestoßen. Es gibt sicher noch mehr, aber bevor ich lang herumsuche, schreibe ich doch lieber selber etwas:</p>
<p>Hier einmal ein etwas längeres Beispiel, wie man Java nach Scala übersetzten (oder sollte ich sagen: &#8220;eindampfen&#8221;) kann. Als nichttriviales Beispiel habe ich mir Dijkstras Algorithmus ausgesucht, der die kürzesten Wege in einem Graphen sucht.</p>
<p>Schritt eins: Irgendwo Java-Code klauen, z.B. von <a href="http://en.literateprograms.org/Dijkstra's_algorithm_(Java)?oldid=15444">Literate Programs</a> &#8211;  eine gute Seite, um mal etwas Beispielcode verschiedener Sprachen anzuschauen.</p>
<pre class="brush: java;">
import java.util.PriorityQueue;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

class Vertex implements Comparable&lt;Vertex&gt;
{
    public final String name;
    public Edge[] adjacencies;
    public double minDistance = Double.POSITIVE_INFINITY;
    public Vertex previous;
    public Vertex(String argName) { name = argName; }
    public String toString() { return name; }
    public int compareTo(Vertex other)
    {
        return Double.compare(minDistance, other.minDistance);
    }
}

class Edge
{
    public final Vertex target;
    public final double weight;
    public Edge(Vertex argTarget, double argWeight)
    { target = argTarget; weight = argWeight; }
}

public class Dijkstra
{
    public static void computePaths(Vertex source)
    {
        source.minDistance = 0.;
        PriorityQueue&lt;Vertex&gt; vertexQueue = new PriorityQueue&lt;Vertex&gt;();
	vertexQueue.add(source);
	while (!vertexQueue.isEmpty()) {
	    Vertex u = vertexQueue.poll();
            // Visit each edge exiting u
            for (Edge e : u.adjacencies)
            {
                Vertex v = e.target;
                double weight = e.weight;
                double distanceThroughU = u.minDistance + weight;
		if (distanceThroughU &lt; v.minDistance) {
		    vertexQueue.remove(v);
		    v.minDistance = distanceThroughU ;
		    v.previous = u;
		    vertexQueue.add(v);
		}
            }
        }
    }

    public static List&lt;Vertex&gt; getShortestPathTo(Vertex target)
    {
        List&lt;Vertex&gt; path = new ArrayList&lt;Vertex&gt;();
        for (Vertex vertex = target; vertex != null; vertex = vertex.previous)
            path.add(vertex);

        Collections.reverse(path);
        return path;
    }

    public static void main(String[] args)
    {
        Vertex v0 = new Vertex(&quot;Harrisburg&quot;);
	Vertex v1 = new Vertex(&quot;Baltimore&quot;);
	Vertex v2 = new Vertex(&quot;Washington&quot;);
	Vertex v3 = new Vertex(&quot;Philadelphia&quot;);
	Vertex v4 = new Vertex(&quot;Binghamton&quot;);
	Vertex v5 = new Vertex(&quot;Allentown&quot;);
	Vertex v6 = new Vertex(&quot;New York&quot;);
	v0.adjacencies = new Edge[]{ new Edge(v1,  79.83),
	                             new Edge(v5,  81.15) };
	v1.adjacencies = new Edge[]{ new Edge(v0,  79.75),
	                             new Edge(v2,  39.42),
	                             new Edge(v3, 103.00) };
	v2.adjacencies = new Edge[]{ new Edge(v1,  38.65) };
	v3.adjacencies = new Edge[]{ new Edge(v1, 102.53),
	                             new Edge(v5,  61.44),
	                             new Edge(v6,  96.79) };
	v4.adjacencies = new Edge[]{ new Edge(v5, 133.04) };
	v5.adjacencies = new Edge[]{ new Edge(v0,  81.77),
	                             new Edge(v3,  62.05),
	                             new Edge(v4, 134.47),
	                             new Edge(v6,  91.63) };
	v6.adjacencies = new Edge[]{ new Edge(v3,  97.24),
	                             new Edge(v5,  87.94) };
	Vertex[] vertices = { v0, v1, v2, v3, v4, v5, v6 };

        computePaths(v0);
        for (Vertex v : vertices)
	{
	    System.out.println(&quot;Distance to &quot; + v + &quot;: &quot; + v.minDistance);
	    List&lt;Vertex&gt; path = getShortestPathTo(v);
	    System.out.println(&quot;Path: &quot; + path);
	}
    }
}
</pre>
<p>Das ist einigermaßen lesbarer Java-Code. Setzen wir das Ganze einmal möglichst 1:1 in &#8220;Besseres-Java-Scala&#8221; um:</p>
<pre class="brush: java;">
object dijkstra {

    class Vertex(val name:String) extends Ordered[Vertex] {
        var adjacencies:Array[Edge] = _
        var minDistance = Double.MaxValue
        var previous: Vertex = _
        override def toString() = name
        def compare(other:Vertex) = Math.signum(minDistance - other.minDistance).toInt
    }

    case class Edge(target:Vertex, weight:Double)

    def computePaths(source: Vertex) {
        source.minDistance = 0.0
        var vertexQueue = new scala.collection.immutable.TreeSet[Vertex]
        vertexQueue += source

        while (!vertexQueue.isEmpty) {
            val u = vertexQueue.firstKey
            vertexQueue -= u
            // Visit each edge exiting u
            for (e &lt;- u.adjacencies) {
                val v = e.target
                val weight = e.weight
                val distanceThroughU = u.minDistance + weight
		if (distanceThroughU &lt; v.minDistance) {
		    vertexQueue -= v
		    v.minDistance = distanceThroughU
		    v.previous = u
		    vertexQueue += v
		}
            }
        }
    }

    def getShortestPathTo(target:Vertex):List[Vertex] = {
        var path = new scala.collection.mutable.ListBuffer[Vertex]
        var vertex = target
        while(vertex != null) {
            path + vertex
            vertex = vertex.previous
        }
        path.toList
    }

    def main(args: Array[String]) {
        val v0 = new Vertex(&quot;Harrisburg&quot;)
	val v1 = new Vertex(&quot;Baltimore&quot;)
	val v2 = new Vertex(&quot;Washington&quot;)
	val v3 = new Vertex(&quot;Philadelphia&quot;)
	val v4 = new Vertex(&quot;Binghamton&quot;)
	val v5 = new Vertex(&quot;Allentown&quot;)
	val v6 = new Vertex(&quot;New York&quot;)
	v0.adjacencies = Array(Edge(v1,  79.83),
	                       Edge(v5,  81.15))
	v1.adjacencies = Array(Edge(v0,  79.75),
	                       Edge(v2,  39.42),
	                       Edge(v3, 103.00))
	v2.adjacencies = Array(Edge(v1,  38.65))
	v3.adjacencies = Array(Edge(v1, 102.53),
	                       Edge(v5,  61.44),
	                       Edge(v6,  96.79))
	v4.adjacencies = Array(Edge(v5, 133.04))
	v5.adjacencies = Array(Edge(v0,  81.77),
	                       Edge(v3,  62.05),
	                       Edge(v4, 134.47),
	                       Edge(v6,  91.63))
	v6.adjacencies = Array(Edge(v3,  97.24),
	                       Edge(v5,  87.94))
	val vertices = Array(v0, v1, v2, v3, v4, v5, v6)
        computePaths(v0)
        for (v &lt;- vertices) {
	    println(&quot;Distance to &quot; + v + &quot;: &quot; + v.minDistance)
	    val path = getShortestPathTo(v)
	    println(&quot;Path: &quot; + path)
	}
    }
}
</pre>
<p>Kein großer Unterschied, außer dass man die Edge-Klasse jetzt mit der Lupe suchen muss. Das TreeSet ist ein Kompromiss, weil ich bei Scala-Klassen bleiben wollte, Scalas PriorityQueue aber kein &#8220;freies&#8221; Löschen von Elementen unterstützt.<br />
Schauen wir mal, wie das ganze etwas &#8220;idiomatischer&#8221; aussieht: </p>
<pre class="brush: java;">
object dijkstra {

    class Vertex(val name:String) extends Ordered[Vertex] {
        var adjacencies = List[Edge]()
        def -&gt; (e:Edge) = { adjacencies += e ; this}
        var minDistance = Double.MaxValue
        var previous: Option[Vertex] = None
        override def toString() = name
        def compare(other:Vertex) = Math.signum(minDistance - other.minDistance).toInt
    }

    case class Edge(target:Vertex, weight:Double)

    def computePaths(source: Vertex) {
        import scala.collection.immutable.TreeSet
        def loop(vertexQueue:TreeSet[Vertex]) {
            if (!vertexQueue.isEmpty) {
                val u = vertexQueue.firstKey
                // Visit each edge exiting u
                loop(u.adjacencies.foldLeft(vertexQueue - u){ (vq ,e) =&gt;
                    val v = e.target
                    val distanceThroughU = u.minDistance + e.weight
                    if (distanceThroughU &lt; v.minDistance) {
                        val vq1 = vq - v
                        v.minDistance = distanceThroughU
                        v.previous = Some(u)
                        vq1 + v
                    } else vq
                })
            }
        }
        source.minDistance = 0.0
        val vertexQueue = new TreeSet[Vertex]
        loop(vertexQueue + source)
    }

    def getShortestPathTo(target:Vertex) = {
        def path(target:Vertex):List[Vertex] = target :: target.previous.map(path).getOrElse(Nil)
        path(target).reverse
    }

    def main(args: Array[String]) {
        val v0 = new Vertex(&quot;Harrisburg&quot;)
	val v1 = new Vertex(&quot;Baltimore&quot;)
	val v2 = new Vertex(&quot;Washington&quot;)
	val v3 = new Vertex(&quot;Philadelphia&quot;)
	val v4 = new Vertex(&quot;Binghamton&quot;)
	val v5 = new Vertex(&quot;Allentown&quot;)
	val v6 = new Vertex(&quot;New York&quot;)
	v0 -&gt; Edge(v1, 79.83) -&gt; Edge(v5, 81.15)
	v1 -&gt; Edge(v0, 79.75) -&gt; Edge(v2, 39.42) -&gt; Edge(v3, 103.00)
	v2 -&gt; Edge(v1, 38.65)
        v3 -&gt; Edge(v1, 102.53) -&gt; Edge(v5, 61.44) -&gt; Edge(v6, 96.79)
	v4 -&gt; Edge(v5, 133.04)
        v5 -&gt; Edge(v0, 81.77) -&gt; Edge(v3, 62.05) -&gt; Edge(v4, 134.47) -&gt; Edge(v6, 91.63)
	v6 -&gt; Edge(v3, 97.24) -&gt; Edge(v5, 87.94)
	val vertices = Array(v0, v1, v2, v3, v4, v5, v6)
        computePaths(v0)
        for (v &lt;- vertices) {
	    println(&quot;Distance to &quot; + v + &quot;: &quot; + v.minDistance)
	    val path = getShortestPathTo(v)
	    println(&quot;Path: &quot; + path)
	}
    }
}
</pre>
<p>Alle Null-Referenzen sind verschwunden, die Edge-Arrays in Vertex durch Listen ersetzt (die durch eine etwas bequemere Syntax zu füllen sind), das previous-Feld ist jetzt eine Option, was in getShortestPathTo ausgenutzt wird.</p>
<p>Am stärksten hat sich computePaths verändert: Die while-Schleife wurde durch ein rekursive Funktion ersetzt und die for-Schleife durch ein foldLeft. Beide Änderungen dienten dazu, auch die vertexQueue-Struktur unveränderlich zu machen (man kann erkennen, wie sie &#8220;durchgereicht&#8221; wird)</p>
<p>Vertex ist die einzige verbliebene veränderliche Struktur, aber um diese auch unveränderlich zu machen, ist etwas mehr Aufwand erforderlich. Das Problem ist nämlich, dass die Edges auf einen Vertex verweisen und Vertizes Edges haben. Diesen Teufelskreis kann man aber durchbrechen, indem man Vertex in einen &#8220;Identitätsteil&#8221; und einen &#8220;Datenteil&#8221; aufsplittet, und die Edges nur auf den Identitätsteil zeigen lässt. </p>
<p>Hier die &#8220;funktionale&#8221; Version: </p>
<pre class="brush: java;">
object dijkstra {

    type Graph = Map[Vertex, Data]
    type VertexQueue = Map[Data, Vertex]

    case class Vertex(name:String) {
        def apply(graph:Graph) =
        graph.getOrElse(this, error(&quot;no data for vertex &quot; + name))
        override def toString() = name
    }

    case class Data(adjacencies:List[Edge], minDistance:Double, previous:Option[Vertex])
    extends Ordered[Data] {
        def compare(other:Data) = Math.signum(minDistance - other.minDistance).toInt
        def this(adjacencies:Edge*) = this(adjacencies.toList, Double.MaxValue, None)
    }

    case class Edge(target:Vertex, weight:Double)

    def computePaths(graph:Graph, source: Vertex) = {
        def foldLoop(u:Data, vertexQueue:VertexQueue, graph:Graph) =
        u.adjacencies.foldLeft((vertexQueue - u, graph)){ (tuple, edge) =&gt;
            val (vq, map) = tuple
            val v = edge.target
            val distanceThroughU = u.minDistance + edge.weight
            if (distanceThroughU &lt; v(map).minDistance) {
                val data = v(map)
                val newData = Data(data.adjacencies, distanceThroughU, vertexQueue get u)
                (vq - data + newData -&gt; v, map + v -&gt; newData)
            } else (vq, map)
        }

        def loop(vertexQueue:VertexQueue, graph:Graph):Graph =
        vertexQueue.keys.find(_ =&gt; true) match {
            case Some(u) =&gt; val tuple = foldLoop(u, vertexQueue, graph)
                            loop(tuple._1, tuple._2)
            case None =&gt; graph
        }

        val data = source(graph)
        val newData = Data(data.adjacencies, 0.0, data.previous)
        val vertexQueue = new scala.collection.immutable.TreeMap[Data,Vertex]
        loop(vertexQueue + newData -&gt; source, graph + source -&gt; newData)
    }

    def getShortestPathTo(target:Vertex, graph:Graph) = {
        def path(t:Vertex):List[Vertex] = t :: t(graph).previous.map(path).getOrElse(Nil)
        path(target).reverse
    }

    def main(args: Array[String]) {
        val v = Array(&quot;Harrisburg&quot;, &quot;Baltimore&quot;, &quot;Washington&quot;, &quot;Philadelphia&quot;,
                      &quot;Binghamton&quot;, &quot;Allentown&quot;,&quot;New York&quot;).map(Vertex(_))
        val startGraph =
        Map(v(0) -&gt; new Data(Edge(v(1), 79.83), Edge(v(5), 81.15)),
            v(1) -&gt; new Data(Edge(v(0), 79.75), Edge(v(2), 39.42), Edge(v(3), 103.00)),
            v(2) -&gt; new Data(Edge(v(1), 38.65)),
            v(3) -&gt; new Data(Edge(v(1), 102.53), Edge(v(5), 61.44), Edge(v(6), 96.79)),
            v(4) -&gt; new Data(Edge(v(5), 133.04)),
            v(5) -&gt; new Data(Edge(v(0), 81.77), Edge(v(3), 62.05), Edge(v(4), 134.47),
                             Edge(v(6), 91.63)),
            v(6) -&gt; new Data(Edge(v(3), 97.24), Edge(v(5), 87.94)))
        val graph = computePaths(startGraph, v(0))

        for (vertex &lt;- graph.keys) {
	    println(&quot;Distance to &quot; + vertex + &quot;: &quot; + vertex(graph).minDistance)
	    val path = getShortestPathTo(vertex, graph)
	    println(&quot;Path: &quot; + path)
	}
    }
}
</pre>
<p>Wie angekündigt habe ich von Vertex die Klasse Data abgeteilt. Der Graph (eine Map aus den Vertizes und ihren Daten) muss nun immer durchgereicht werden. Ein Problem ergab sich daraus, dass  Vertex jetzt nicht mehr &#8220;vergleichbar&#8221; ist, da ja die Distanzen in der Data-Klasse gelandet sind. Zuerst habe ich versucht, das ganze mit impliziten Parametern hinzubiegen, aber nach einiger Überlegung habe ich mich entschieden, einfach die Data-Klasse sortierbar zu machen, und die PriorityQueue des Originals nicht mehr durch ein TreeSet, sondern eine TreeMap abzubilden &#8211; wobei diesmal  Data auf Vertex zeigt (also genau umgekehrt wie in der Graph-Map). Da die beiden genannten Typen oft vorkamen, habe ich die Typ-Aliase &#8220;Graph&#8221; und &#8220;VertexQueue&#8221; eingeführt. Data als Schlüssel für eine Map zu verwenden ist übrigens nicht ganz unproblematisch: In größeren Graphen muss man aufpassen, dass zwei Data-Instanzen nicht als &#8220;gleich&#8221; angesehen werden, nur weil sie zufällig die gleichen Nachbarorte im gleichen Abstand haben.</p>
<p>Aus der inneren Funktion loop habe ich die Funktion foldLoop herausgebrochen, die die eigentliche Arbeit erledigt (wie foldLeft funktionert, hatte ich ja schon im Origami-Beitrag erklärt).</p>
<p>Vermutlich wird mein Programm keinen Schönheitspreis gewinnen, aber im Gegensatz zu den üblichen Beispielen zur funktionalen Programmierung (die oft wie Taschenspielertricks wirken) kann man hier sehen, wie es aus einem imperativen Programm Schritt für Schritt entstanden ist, und auch, welche Schwierigkeiten es dabei gab. Sicher könnte man das Programm weiter verbessern, aber dann müsste man stärker von der vorgegebenen Struktur abweichen und es wäre nicht mehr sinnvoll, es Seite an Seite neben das Java-Original zu stellen und zu vergleichen.</p>
<p>Dieser Code ist nur als &#8220;Demo&#8221; gedacht und ich vermute, dass er nicht besonders performant ist. Bei funktionaler Programmierung spielt die Auswahl der &#8220;richtigen&#8221; Datenstrukturen eine große Rolle, und diese sind hier sicher nicht optimal. Dabei ist es oft nicht die Geschwindigkeit, sondern der Speicherbedarf, der Probleme bereitet. Vermutlich sollte man sich erst einmal nach einer guten Graphen-Bibliothek umsehen, denn unveränderliche Datenstrukturen richtig zu schreiben ist nicht trivial.</p>
<p>Weiterhin sollte man in unserem Beispiel abwägen, ob man nicht <strong>lokal</strong> auch imperative Konstrukte zulassen sollte. &#8220;Imperativ&#8221; ist nicht gleich &#8220;schlecht&#8221;, schlecht sind vor allem Seiteneffekte und veränderliche Daten, die aus ihrer lokalen Umgebung &#8220;entkommen&#8221;, indem sie weitergereicht werden.</p>
<p>Schön, dass ihr bis hierhin durchgehalten habt. Und falls ihr mal dringend von Harrisburg nach Allentown müsst: Jetzt kennt ihr den kürzesten Weg!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[3 bài toán quy hoạch động hay]]></title>
<link>http://giaithuat.wordpress.com/2009/06/28/3-bai-toan-quy-ho%e1%ba%a1ch-d%e1%bb%99ng-hay/</link>
<pubDate>Sun, 28 Jun 2009 02:26:29 +0000</pubDate>
<dc:creator>FVS</dc:creator>
<guid>http://giaithuat.wordpress.com/2009/06/28/3-bai-toan-quy-ho%e1%ba%a1ch-d%e1%bb%99ng-hay/</guid>
<description><![CDATA[Minh họa cho vui Sau đây mình xin giới thiệu tới các bạn 3 bài toán quy hoạch động khá thú vị. Thú v]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div id="attachment_783" class="wp-caption aligncenter" style="width: 478px"><img class="size-full wp-image-783" title="PacmanUnited" src="http://giaithuat.wordpress.com/files/2009/06/pacmanunited.jpg" alt="Minh họa cho vui" width="468" height="280" /><p class="wp-caption-text">Minh họa cho vui</p></div>
<p>Sau đây mình xin giới thiệu tới các bạn <strong>3 </strong>bài toán quy hoạch động khá thú vị. Thú vị ở  chỗ chúng có đề bài rất giống nhau, chỉ  khác ở chỗ rất nhỏ nhưng lại làm cho chúng có mức độ  khó tăng dần. Thực ra thì cũng không có gì lắm, nhưng dẫu sao cũng mời các bạn cùng &#8220;thưởng thức&#8221; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  :</p>
<p><strong>Bài toán 1:</strong></p>
<p>Cho ma trận A kích cỡ M*N (1&#60;=M,N&#60;=100, M dòng, N cột).Mỗi ô của ma trận có một giá trị nguyên nằm trong khoảng 1..100. Từ  mỗi ô (I,J) (I: chỉ số cột, J: chỉ số dòng) có thể đến được các ô sau (nếu có):  (I+1,J-1), (I+1,J), (I+1,J+1).</p>
<p>Hãy tìm một đường đi xuất phát từ ô bất kì của cột 1 và kết thúc tại ô bất kì của cột N sao cho tổng giá trị của các ô đi qua trên đường đi là nhỏ nhất.</p>
<p><strong>&#62;&#62;Thuật giải:</strong> Không cần bàn nhiểu ta cũng thấy ngay được công thức quy hoạch động của bài này. Gọi Fx[I,J] là tổng giá trị nhỏ nhất để đi từ  một ô bất kì của cột 1 đến ô (I,J). Khi đó:</p>
<p>F[1,J]=A[1,J] (1&#60;=J&#60;=M)</p>
<p>F[I,J]=Min(F[I-1,J-1],F[I-1,J],F[I-1,J+1])+A[I,J] (2&#60;=I&#60;=N,1&#60;=J&#60;=M)</p>
<p>Truy vết in ra đường đi cũng không có gì khó khắn lắm <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Bài toán 2:</strong> Tương tự  như  bài toán 1 nhưng  ô (I,J) có thể đến các ô sau: (I,J+1), (I,J-1), (I+1,J)</p>
<p>Khá là vấn đề khi áp dụng QHĐ do một ô có thể được đến từ  một ô khác ở cột liền trước bên trái hoặc một ô liền trên hoặc một ô liền dưới. Ở bài toán trên ta tính Fx lần lượt từ  cột 1 đến cột N do kết quả mỗi cột chỉ phụ thuộc vào cột trước nó đằng này bài 2 chúng ta bị ép 3 phía như thế ta không biết sẽ phải tính toán Fx theo thứ  tự  như  thế nào :-S Các của mình đưa ra là QHĐ kết hợp thêm chút ít &#8220;thủ công&#8221;</p>
<p><strong>&#62;&#62;Thuật giải: </strong>Ta cũng thiết kế một mảng Fx[I,J] chức năng như  trên nhưng ta sẽ tính theo một cách khác. Đầu tiên cũng sẽ là gán F[1,J]:=A[1,J] với 1&#60;=J&#60;=M. Với mỗi ô (I,J) ta nhận thấy trên đường đi nhỏ nhất dẫn đến nó thì sẽ có một ô (I-1,X) để từ  ô (I-1,X) chuyển sang ô (I,X) rồi đi đến nó. Chỉ cần xác định được ô (I-1,X) tính được Fx[I,J]. Mà 1&#60;=X&#60;=M nên ta sẽ thử  lần lượt X từ 1 đến M rồi tìm Min. Khi tìm được ta nên lưu lại giá trị của X cho mỗi ô (I,J) để tiện cho việc truy vết. Sau đây là mã nguồn mình cài đặt cho thuật toán này:</p>
<blockquote><p>Uses Crt;<br />
Var Map:Array[1..100,1..100] Of Byte;<br />
Rs:Array[1..100,1..100] Of Record <span style="color:#339966;">{chính là mảng Fx, với value là giá trị nhỏ nhất còn Back là X)</span><br />
Back:Byte;<br />
Value:Longint;<br />
End;<br />
M,N,i,j:Byte;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Procedure ReadDT;<br />
Var I,J:Integer;<br />
F:text;<br />
Begin<br />
assign(f,&#8217;fi.inp&#8217;);reset(F);<br />
Readln(F,M,N);<br />
For J:=1 To M Do<br />
Begin<br />
For I:=1 To N Do Read(f,Map[I,J]);<br />
Readln(F);<br />
End;<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Function GetRs(X,Y,Back:Byte):Longint; <span style="color:#339966;">(Tính xem giá trị của đường đi tới ô (X,Y) nếu X=Back)</span><br />
Var S:Longint;<br />
I:Byte;<br />
Begin<br />
S:=Map[X,Y]+Rs[X-1,Back].Value;<br />
For I:=Back To Y-1 Do Inc(S,Map[X,I]);<br />
For I:=Y+1 To Back Do Inc(S,Map[X,I]);<br />
GetRs:=S;<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Procedure GenRsTable; <span style="color:#339966;">(tạo bảng giá trị (mảng Rs))</span><br />
Var Back,I,J:Byte;<br />
S:Longint;<br />
Begin<br />
For J:=1 To M Do Rs[1,J].Value:=Map[1,J];<br />
For I:=2 To N Do<br />
For J:=1 To M Do<br />
Begin<br />
Rs[I,J].Value:=GetRs(I,J,1);<br />
Rs[I,J].Back:=1;<br />
For Back:=2 To M Do<br />
Begin<br />
S:=GetRs(I,J,Back);<br />
If S&#60;Rs[I,J].Value Then<br />
Begin<br />
Rs[I,J].Value:=S;<br />
Rs[I,J].Back:=Back;<br />
End;<br />
End;<br />
End;<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Procedure OutIJ(X,Y:Byte);<br />
Var I:Byte;<br />
Begin<br />
If X=1 Then<br />
Begin<br />
Writeln(X,&#8217; &#8216;,Y);<br />
Exit;<br />
End;<br />
OutIJ(X-1,Rs[X,Y].Back);<br />
For I:=Rs[X,Y].Back To Y-1 Do Writeln(X,&#8217; &#8216;,I);<br />
For I:=Rs[X,Y].Back DownTo Y+1 Do Writeln(X,&#8217; &#8216;,I);<br />
Writeln(X,&#8217; &#8216;,Y);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Procedure WriteRs;<br />
Var I,J,JMin:Byte;<br />
SMin:Longint;<br />
Begin<br />
SMin:=Rs[N,1].Value;<br />
JMin:=1;<br />
For J:=1 To M Do<br />
If Rs[N,J].Value&#60;SMin Then Begin<br />
SMin:=Rs[N,J].Value;<br />
JMin:=J;<br />
End;<br />
Writeln(SMin);<br />
OutIJ(N,JMin);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Begin<br />
Clrscr;<br />
ReadDT;<br />
GenRsTable;<br />
writeRs;<br />
readln;<br />
End.</p></blockquote>
<p><strong>3. Bài toán 3:</strong> Tương tự  như  bài toán 1 nhưng  ô (I,J) có thể đến các ô sau: (I,J+1), (I,J-1), (I+1,J), (I-1,J)</p>
<p>Lần này bị o ép từ 4 phía thì có vẻ như  quy hoạch động khá khó khăn.</p>
<p><strong>&#62;&#62;Thuật giải: </strong>Coi mỗi ô của ma trận như  một đỉnh của đồ thị. Áp dụng dijkstral. Lưu ý chương trình của mình của mình không sử  dụng mạng hai chiều mà &#8220;dãn&#8221; ra thành mảng 1 chiểu. Hàm Conv(X,Y:Byte) cho vị trí ô (X,Y) trong mảng một chiều.</p>
<blockquote><p>Var P,Map:Array[1..100*100] Of Byte;<br />
L,R:Array[1..100*100] Of Integer;<br />
M,N:Byte;<br />
C,First,Last:Integer;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-}<br />
Function Conv(X,Y:Byte):Integer;<br />
Begin<br />
Conv:=Y*N-N+X;<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;}<br />
Procedure ReadDt;<br />
Var I,J:Byte;<br />
Begin<br />
Readln(M,N);<br />
For J:=1 To M Do<br />
For I:=1 To N Do Read(Map[Conv(I,J)]);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;}<br />
Procedure Add(Id:Integer);<br />
Begin<br />
If Last=100*100 Then Last:=1 Else Inc(Last);<br />
L[Last]:=Id;<br />
Inc(C);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;}<br />
Function Pop:Integer;<br />
Begin<br />
Pop:=L[First];<br />
If First=100*100 Then First:=1 Else Inc(First);<br />
Dec(C);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-}<br />
Procedure Proc(Id:Integer);<br />
Var X,Y:Byte;<br />
Begin<br />
X:=Id Mod N; If X=0 Then X:=N;<br />
Y:=Id Div N; If X&#60;&#62;N Then Inc(Y);<br />
If X&#60;N Then<br />
If (R[Conv(X+1,Y)]&#62;(Map[Conv(X+1,Y)]+R[ID]))Or(R[Conv(X+1,Y)]=0) Then<br />
Begin<br />
R[Conv(X+1,Y)]:=Map[Conv(X+1,Y)]+R[Id];<br />
P[Conv(X+1,Y)]:=Id;<br />
Add(Conv(X+1,Y));<br />
End;<br />
{&#8221;&#8221;&#8221;&#8221;&#8221;&#8221;&#8221;}<br />
If X&#62;1 Then<br />
If (R[Conv(X-1,Y)]&#62;(Map[Conv(X-1,Y)]+R[Id]))Or(R[Conv(X-1,Y)]=0) Then<br />
Begin<br />
R[Conv(X-1,Y)]:=Map[Conv(X-1,Y)]+R[Id];<br />
P[Conv(X-1,Y)]:=Id;<br />
Add(Conv(X-1,Y));<br />
End;<br />
{&#8221;&#8221;&#8221;&#8221;&#8221;&#8221;&#8221;}<br />
If (Y&#60;M)And(X&#60;&#62;1)And(X&#60;&#62;N) Then<br />
If (R[Conv(X,Y+1)]&#62;(Map[Conv(X,Y+1)]+R[Id]))Or(R[Conv(X,Y+1)]=0) Then<br />
Begin<br />
R[Conv(X,Y+1)]:=(Map[Conv(X,Y+1)]+R[Id]);<br />
P[Conv(X,Y+1)]:=Id;<br />
Add(Conv(X,Y+1));<br />
End;<br />
{&#8221;&#8221;&#8221;&#8221;&#8221;&#8221;&#8221;}<br />
If (Y&#62;1)And(X&#60;&#62;1)And(X&#60;&#62;N) Then<br />
If (R[Conv(X,Y-1)]&#62;(Map[Conv(X,Y-1)]+R[Id]))Or(R[Conv(X,Y-1)]=0) Then<br />
Begin<br />
R[Conv(X,Y-1)]:=(Map[Conv(X,Y-1)]+R[Id]);<br />
P[Conv(X,Y-1)]:=Id;<br />
Add(Conv(X,Y-1));<br />
End;</p>
<p>End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-}<br />
Procedure OutRs;<br />
Procedure DQ(Id:Integer);<br />
Var X,Y:Byte;<br />
Begin<br />
X:=Id Mod N; If X=0 Then X:=N;<br />
Y:=Id Div N; If X&#60;&#62;N Then Inc(Y);<br />
If P[Id]=0 Then<br />
Begin<br />
Writeln(Y,&#8217; &#8216;,X);<br />
Exit;<br />
End;<br />
DQ(P[Id]);<br />
Writeln(Y,&#8217; &#8216;,X);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;}<br />
Var Min,PMin:Integer;<br />
X,Y:Byte;<br />
Begin<br />
Min:=R[Conv(N,1)];<br />
PMin:=Conv(N,1);<br />
For Y:=2 To M Do<br />
If R[Conv(N,Y)]&#60;Min Then<br />
Begin<br />
Min:=R[Conv(N,Y)];<br />
PMin:=Conv(N,Y);<br />
End;<br />
Writeln(Min);<br />
DQ(PMin);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-}<br />
Procedure GenRs;<br />
Var I:Byte;<br />
Begin<br />
Last:=0;First:=1;<br />
FillChar(R,SizeOf(R),0);<br />
FillChar(P,SizeOf(P),0);<br />
C:=0;<br />
For I:=1 To M Do<br />
Begin<br />
Add(Conv(1,I));<br />
R[Conv(1,I)]:=Map[Conv(1,I)];<br />
End;<br />
While C&#60;&#62;0 Do Proc(Pop);<br />
End;<br />
{&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-}<br />
Begin<br />
ReadDT;<br />
GenRs;<br />
OutRs;<br />
End.</p></blockquote>
<p><span style="text-decoration:underline;"><strong>Lưu ý cấu trúc file Input:</strong></span></p>
<p>- Dòng đầu: M và N</p>
<p>- M dòng sau mỗi dòng là N số nguyên tương ứng với giá trị của ô (I,J)</p>
<p><strong><br />
</strong></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Further details on TOI]]></title>
<link>http://dranaxum.wordpress.com/2009/06/21/further-details-on-toi/</link>
<pubDate>Sun, 21 Jun 2009 11:56:10 +0000</pubDate>
<dc:creator>dranaxum</dc:creator>
<guid>http://dranaxum.wordpress.com/2009/06/21/further-details-on-toi/</guid>
<description><![CDATA[There is much chance that the launch of TOI (aka Training for Olympiad in Informatics see main artic]]></description>
<content:encoded><![CDATA[There is much chance that the launch of TOI (aka Training for Olympiad in Informatics see main artic]]></content:encoded>
</item>
<item>
<title><![CDATA[Thuật toán Dijkstra trên cấu trúc Heap]]></title>
<link>http://giaithuat.wordpress.com/2009/06/15/thu%e1%ba%adt-toan-dijkstra-tren-c%e1%ba%a5u-truc-heap/</link>
<pubDate>Mon, 15 Jun 2009 04:38:14 +0000</pubDate>
<dc:creator>FVS.Collector</dc:creator>
<guid>http://giaithuat.wordpress.com/2009/06/15/thu%e1%ba%adt-toan-dijkstra-tren-c%e1%ba%a5u-truc-heap/</guid>
<description><![CDATA[1. Nhắc lại thuật toán Dijkstra tìm đường đi ngắn nhất Bài toán: Cho đồ thị có hướng với trọng số cá]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><span><strong>1. <em>Nhắc lại thuật toán Dijkstra tìm đường đi ngắn nhất</em> </strong><br />
<strong>Bài toán:</strong> Cho đồ thị có hướng với trọng số các cung (i,j) là  C[i,j] không âm, tìm đường đi ngắn nhất từ đỉnh s đến đỉnh t.<br />
<strong><span style="text-decoration:underline;">Thuật  toán Dijkstra: </span></strong><br />
<em>Bước 1- Khởi trị: </em><br />
- Khởi trị nhãn đường đi  ngắn nhất từ đỉnh s tới đỉnh i là d[i]:= C[s,i] (nếu không có đường đi trực tiếp  từ s đến i thì C[s,i] bằng vô cùng). Lưu lại đỉnh trước khi tới i trên hành  trình ngắn nhất là Tr[i] := s<br />
- Khởi trị nhãn đỉnh s là d[s] =0<br />
- Đánh  dấu mọi đỉnh i là tự do (nhãn d[i] chưa tối ưu): DX[i]:=false<br />
<em>Bước 2  (vòng lặp vô hạn): </em><br />
- Tìm đỉnh i<sub>0</sub> tự do có nhãn  d[i<sub>0</sub>] nhỏ nhất.<br />
- Nếu không tìm được i<sub>0</sub> (i<sub>0</sub> =0) hoặc i<sub>0</sub> =t thì thoát khỏi vòng lặp còn không thì<br />
+ Đánh dấu  i<sub>0</sub> đã được cố định nhãn DX[i<sub>0</sub>]:=True (gọi i<sub>0</sub> là  đỉnh được cố định nhãn)<br />
+ Sửa nhãn cho các đỉnh j tự do kề với i<sub>0</sub> theo công thức d[j] = Min{d[j], d[i<sub>0</sub>]+C[i<sub>0</sub>,j] và ghi lưu  lại đỉnh trước j là i<sub>0</sub>: Tr[j]:= i<sub>0 </sub><br />
<em>Bước 3  &#38;minus Tìm và ghi kết quả: </em><br />
Dựa vào giá trị d[t] và mảng Tr để kết  luận thích hợp</span></p>
<p><strong><em>2. Cấu trúc Heap và một số phép xử lí trên Heap </em></strong><br />
a) <em> Mô tả  Heap:</em> Heap được mô tả như một cây nhị phân có cấu trúc sao cho giá trị khoá  ở mỗi nút không vượt quá giá trị khoá của hai nút con của nó (suy ra giá trị  khoá tại gốc Heap là nhỏ nhất).<br />
<em>b) Hai phép xử lí trên Heap </em></p>
<p><img class="alignright size-full wp-image-553" title="Thuật tóan Dijkstra trên cấu trúc Heap" src="http://giaithuat.wordpress.com/files/2009/06/dtr1.jpg" alt="Thuật tóan Dijkstra trên cấu trúc Heap" width="418" height="253" /><br />
-  <span style="text-decoration:underline;">Phép cập nhật Heap </span><br />
<span style="text-decoration:underline;">Vấn đề:</span> Giả sử nút v có giá trị khoá nhỏ  đi, cần chuyển nút v đến vị trí mới trên Heap để bảo toàn cấu trúc Heap<br />
<span style="text-decoration:underline;">Giải quyết: </span><br />
+ Nếu nút v chưa có trong Heap thì tạo thêm nút v  thành nút cuối cùng của Heap (<em>hình 1</em>)<br />
+ Chuyển nút v từ vị trí hiện  tại đến vị trí thích hợp bằng cách tìm đường đi ngược từ vị trí hiện tại của v  về phía gốc qua các nút cha có giá trị khoá lớn hơn giá trị khoá của v. Trên  đường đi ấy dồn nút cha xuống nút con, nút cha cuối cùng chính là vị trí mới<br />
của nút v (<em>hình 2</em>).</p>
<p><img class="alignleft size-full wp-image-554" title="Thuật toán Dijkstra trên cấu trúc Heap" src="http://giaithuat.wordpress.com/files/2009/06/dtr2.jpg" alt="Thuật toán Dijkstra trên cấu trúc Heap" width="468" height="283" /><br />
<em>Chú ý</em>: trên cây nhị phân, nếu đánh số  các nút từ gốc đến lá và từ con trái sang con phải thì dễ thấy: khi biết số hiệu  của nút cha là i có thể suy ra số hiệu hai nút con là 2*i và 2*i+1, ngược lại số  hiệu nút con là j thì số hiệu nút cha là j div 2.</p>
<p><img src="Data_thnt/52004/thuat2.jpg" alt="" /><br />
- <span style="text-decoration:underline;">Phép loại bỏ gốc của Heap </span><br />
<span style="text-decoration:underline;">Vấn đề:</span> Giả sử cần loại bỏ nút gốc khỏi Heap, hãy sắp xếp lại  Heap (gọi là phép vun đống)<br />
<span style="text-decoration:underline;">Giải quyết: </span><br />
+ Tìm đường đi từ gốc về  phía lá, đi qua các nút con có giá trị khoá nhỏ hơn trong hai nút con cho đến  khi gặp lá.<br />
+ Trên dọc đường đi ấy, kéo nút con lên vị trí nút cha của nó.<br />
Ví dụ trong hình vẽ 2 nếu bỏ nút gốc có khoá bằng 1, ta sẽ kéo nút con lên  vị trí nút cha trên đường đi qua các nút có giá trị khoá là 1, 2, 6, 8 và Heap  mới như hình 3</p>
<p><img class="alignleft size-full wp-image-556" title="Thuật toán Dijkstra trên cấu trúc Heap" src="http://giaithuat.wordpress.com/files/2009/06/dtr3.jpg" alt="Thuật toán Dijkstra trên cấu trúc Heap" width="468" height="217" /><br />
<strong><em>3. Thuật toán  Dijkstra tổ chức trên cấu trúc Heap (tạm kí hiệu là Dijkstra_Heap) </em></strong><br />
Tổ chức Heap: Heap gồm các nút là các đỉnh i tự do (chưa cố định  nhãn đường đi ngắn nhất), với khoá là nhãn đường đi ngắn nhất từ s đến i là  d[i]. Nút gốc chính là đỉnh tự do có nhãn d[i] nhỏ nhất. Mỗi lần lấy nút gốc ra  để cố định nhãn của nó và sửa nhãn cho các đỉnh tự do khác thì phải thức hiện  hai loại xử lí Heap đã nêu (phép cập nhật và phép loại bỏ gốc).</p>
<p>Vậy  thuật toán Dijkstra tổ chức trên Heap như sau:<br />
Cập nhật nút 1 của Heap  (tương ứng với nút s có giá trị khoá bằng 0)<br />
Vòng lặp cho đến khi Heap  rỗng (không còn nút nào)<br />
Begin<br />
+ Lấy đỉnh u tại nút gốc của Heap  (phép loại bỏ gốc Heap)<br />
+ Nếu u= t thì thoát khỏi vòng lặp<br />
+  Đánh dấu u là đỉnh đã được cố định nhãn<br />
+ Duyệt danh sách cung kề tìm  các cung có đỉnh đầu bằng u, đỉnh cuối là v<br />
Nếu v là đỉnh tự do và d[v]  &#62; d[u] + khoảng cách (u,v) thì<br />
Begin<br />
Sửa nhãn cho v và ghi  nhận đỉnh trước v là u<br />
Trên Heap, cập nhật lại nút tương ứng với đỉnh v.<br />
End;<br />
End;</p>
<p><strong><em>4. Đánh giá </em></strong><br />
+ Thuật toán  Dijkstra tổ chức như nêu ở mục 1. Có độ phức tạp thuật toán là O(N<sup>2</sup>),  nên không thể thực hiện trên đồ thị có nhiều đỉnh.<br />
+ Các phép xử lí Heap đã  nêu (cập nhật Heap và loại bỏ gốc Heap) cần thực hiện không quá 2.lgM phép so  sánh (nếu Heap có M nút). Số M tối đa là N (số đỉnh của đồ thị) và ngày càng nhỏ  dần (tới 0). Ngoài ra, nếu đồ thị thưa (số cung ít) thì thao tác tìm đỉnh v kề  với đỉnh u là không đáng kể khi ta tổ chức danh sách các cung kề này theo từng  đoạn có đỉnh đầu giống nhau (dạng Forward Star). Do đó trên đồ thị thưa, độ phức  tạp của Dijkstra_Heap có thể đạt tới O(N. k.lgN) trong đó k không đáng kể so với  N<br />
+ <em>Kết luận</em>: Trên đồ thị nhiều đỉnh ít cung thì Dijkstra_Heap là  thực hiện được trong thời gian có thể chấp nhận.</p>
<p><strong><em>5. Chương trình </em></strong></p>
<blockquote><p>uses crt;<br />
const maxN = 5001;<br />
maxM = 10001;<br />
maxC =  1000000000;<br />
fi = &#38;rquo;minpath.in&#38;rquo;;<br />
fo =  &#38;rquo;minpath.out&#38;rquo;;</p>
<p>type k1 = array[1..maxM] of integer;<br />
k2 = array[1..maxM] of longint;</p>
<p>k3 = array[1..maxN] of integer;<br />
k4 = array[1..maxN] of longint;<br />
k5 = array[1..maxN] of boolean;</p>
<p>var ke : ^k1; {danh sách đỉnh kề}<br />
c : ^k2; {trọng số cung tương ứng  với danh sách kề}<br />
p : ^k3; 1 {vị trí đỉnh kề trong danh sách kề}<br />
d : k4;  {nhãn đường đi ngắn nhất trong thuật toán Dijkstra}<br />
tr : k3; {lưu đỉnh trước  của các đỉnh trong hành trình ngắn nhất }<br />
dx : k5; {đánh dấu nhãn đã cố  định, không sửa nũă}<br />
h, {heap (Đống)}<br />
sh : k3; {số hiệu của nút trong  heap}<br />
n,m,s,t, {số đỉnh, số cạnh, đính xuất phát và đỉnh đích}<br />
shmax :  integer; {số nút max trên heap}</p>
<p>procedure doc_inp;<br />
var i,u,v,x :  integer;<br />
f : text;<br />
begin<br />
assign(f,fi);</p>
<p>{Đọc file input lần  thứ nhất}</p>
<p>reset(f);<br />
readln(f,n,m,s,t);<br />
new(p);<br />
new(ke);<br />
new(c);<br />
fillchar(p^,sizeof(p^),0);<br />
for i:=1 to m do<br />
begin<br />
readln(f,u);<br />
inc(p^[u]); {p^[u] số lượng đỉnh kề với đỉnh u}<br />
end;<br />
for i:=2 to n do<br />
p^[i] := p^[i] + p^[i-1]; {p[i]^ dùng để xây dựng chỉ  số của mảng kê}<br />
close(f); {p[i]^ là vị trí cuối cùng của đỉnh kề với đỉnh i  trong mảng kê}</p>
<p>{Đọc file input lần thứ hai}<br />
reset(f);<br />
readln(f);<br />
for i:=1 to m do<br />
begin<br />
readln(f,u,v,x);<br />
kê[p^[u]] := v; {xác  nhận kề với đỉnh u là đỉnh v}<br />
c^[p^[u]] := x; {xác nhận trọng số của cung  (u,v) là x}<br />
dec(p^[u]); {chuyển về vị trí của đỉnh kề tiếp theo của u}<br />
end;<br />
p^[n+1] := m; {hàng rào}<br />
close(f);<br />
end;</p>
<p>procedure  khoitri;<br />
var i : integer;<br />
begin<br />
for i:=1 to n do d[i] := maxC; {nhãn  độ dài đường đi ngắn nhất từ s tới i là vô cùng}<br />
d[s] := 0; {nhãn độ dài  đường đi ngắn nhất từ s tới s là 0}<br />
fillchar(dx,sizeof(dx),False); {khởi trị  mảng đánh dấu: mọi đỉnh chưa cố định nhãn }<br />
fillchar(sh,sizeof(sh),0); {khởi  trị số hiệu các nút của Heap là 0}<br />
shmax := 0; {khởi trị số nút của heap là  0}<br />
end;</p>
<p>procedure capnhat(v : integer);<br />
{đỉnh v vừa nhận giá trị  mới là d[v], do đó cần xếp lại vị trí của đỉnh v trong heap, bảo đảm tính chất  heap}</p>
<p>var cha,con : integer;<br />
begin<br />
con := sh[v]; {con là số hiệu  nút hiện tại của v}<br />
if con=0 then {v chưa có trong heap, thì bổ sung vào nút  cuối cùng của heap}<br />
begin<br />
inc(shmax);<br />
con := shmax;<br />
end;<br />
cha  := con div 2; {cha là số hiệu hiện tại của nút cha của nút v hiện tại}<br />
while  (cha&#62;0) and (d[h[cha]] &#62; d[v]) do<br />
{nếu nhãn của nút cha (có số hiệu là  <em>cha</em>) lớn hơn nhãn của nút v thì đưa dần nút v về phía gốc tới vị trí thoả  mãn điều kiện của heap bằng cách: kéo nút cha xuống vị trí của nút con của nó }<br />
begin<br />
h[con] := h[cha];<br />
sh[h[con]] := con;<br />
con := cha;<br />
cha  := con div 2;<br />
end;<br />
h[con] := v; {nút con cuối cùng trong quá trình &#8220;kéo  xuống&#8221; nêu trên, là vị trí mới của v}<br />
sh[v] := con;<br />
end;</p>
<p>function lay: integer;<br />
{lấy khỏi heap đỉnh gốc, vun lại heap để hai  cây con hợp thành heap mới}<br />
var r,c,v : integer;<br />
begin<br />
lay := h[1];  {lấy ra nút gốc là nút có nhãn nhỏ nhất trong các nút chưa cố định nhãn}<br />
v  := h[shmax]; {v: đỉnh cuối cùng của heap}<br />
dec(shmax); {sau khi loại đỉnh  gốc, số nút của heap giảm đi 1}<br />
r := 1; {bắt đầu vun từ nút gốc}<br />
while  r*2 &#60;= shmax do {quá trình vun heap}<br />
begin<br />
c := r*2; {số hiệu nút con  trái của r}<br />
if (c<br />
inc(c); {so sánh  nhãn của hai nút con, chọn c là con có nhãn nhỏ hơn}<br />
if d[v]&#60;=d[h[c]]  then break; { dừng khi nhãn v không vượt quá nhãn hai nút con}<br />
h[r] := h[c];  {chuyển nút có số hiệu là <em>con</em> lên nút có số hiệu là <em>cha</em>}<br />
sh[h[r]] := r; {xác nhận lại số hiệu trong heap của nút mới chuyển lên}<br />
r := c; {xác nhận cha mới để quá trình lặp lại}<br />
end;<br />
h[r] := v;  {đỉnh v được đặt vào vị trí r cuối cùng để bảo đảm điều kiện của heap}<br />
sh[v]  := r; {xác nhận lại số hiệu của nút v trong heap}<br />
end;</p>
<p>procedure  dijkstra;<br />
var i,u,j,v,min : integer;<br />
begin<br />
capnhat(1); {tạo nút thứ  nhất cho heap}<br />
repeat<br />
u := lay; {u: đỉnh chưa cố định nhãn, có nhãn nhỏ  nhất}<br />
if u=t then break; {tới đích thì dừng}<br />
dx[u] := True; {đánh dấu u  được cố định nhãn}<br />
for j:= p^[u]+1 to p^[ư1] do {j: chỉ số trong mảng ke,  của các đỉnh kề với u}<br />
begin<br />
v := kê[j]; {v kề với u}<br />
if (not dx[v])  and (d[v]&#62;d[u]+c^[j]) then {điều kiện sửa nhãn v}<br />
begin<br />
d[v] := d[u]  + c^[j]; {sửa lại nhãn của v}<br />
tr[v] := u; {ghi nhận lại đỉnh trước của v là  u}<br />
capnhat(v); {cập nhật lại v trong heap để bảo đảm cấu trúc heap }<br />
end;<br />
end;<br />
until shmax = 0; {dừng khi không còn đỉnh tự do (số nút  của heap bằng 0)}<br />
end;</p>
<p>procedure inkq;<br />
var f : text; i,j :  integer;<br />
kq : k3;<br />
begin<br />
assign(f,fo);<br />
rewrite(f);<br />
if  d[t]=maxc then<br />
writeln(f,-1) {ghi kết quả: vô nghiệm}<br />
else<br />
begin<br />
writeln(f,d[t]); {ghi độ dài đường đi ngắn nhất từ đỉnh s đến đỉnh t vào  file output}<br />
i := 0;<br />
while t&#60;&#62;s do {lần ngược các đỉnh liên tiếp  của hành trình ngắn nhất lưu vào mảng kq}<br />
begin<br />
inc(i);<br />
kq[i] := t;<br />
t := tr[t];<br />
end;<br />
inc(i);<br />
kq[i] := s;<br />
for j:=i downto 1 do  write(f,kq[j],′ ′); {ghi hành trình vào file output}<br />
end;<br />
close(f);<br />
end;</p>
<p>BEGIN<br />
doc_inp;<br />
khoitri;<br />
dijkstra;<br />
inkq;<br />
END.</p></blockquote>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Edsger Wybe Dijkstra - Tác giả thuật toán Dijkstra]]></title>
<link>http://giaithuat.wordpress.com/2009/06/15/edsger-wybe-dijkstra-tac-gi%e1%ba%a3-thu%e1%ba%adt-toan-dijkstra/</link>
<pubDate>Mon, 15 Jun 2009 04:15:44 +0000</pubDate>
<dc:creator>FVS.Collector</dc:creator>
<guid>http://giaithuat.wordpress.com/2009/06/15/edsger-wybe-dijkstra-tac-gi%e1%ba%a3-thu%e1%ba%adt-toan-dijkstra/</guid>
<description><![CDATA[Giáo sư Edsger Wybe Dijkstra (11/5/1930-6/8/2002) là một người đi đầu trong lĩnh vực máy tính, đã mấ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><img class="alignleft" title="Edsger Dijkstra - tác giả thuật toán Dijkstra" src="http://upload.wikimedia.org/wikipedia/commons/d/d9/Edsger_Wybe_Dijkstra.jpg" alt="" width="236" height="215" /><span style="font-family:Times New Roman;font-size:small;"><em>Giáo sư Edsger Wybe Dijkstra (11/5/1930-6/8/2002) là một người đi đầu  trong lĩnh vực máy tính, đã mất vào ngày 6/8/2002 tại Neunen-Hà Lan, sau một một  thời gian dài mắc bệnh ung thư. Bài viết này giới thiệu đôi nét về cuộc đời và  sự nghiệp của ông.</em></span></p>
<p><span style="font-family:Times New Roman;font-size:small;">Dijkstra sinh ngày 11/5/1930 tại Rotterdam-Hà Lan trong một gia đình mà bố là  một nhà hoá học và mẹ là một nhà toán học. Ông đã tốt nghiệp về chuyên ngành  toán và vật lý lý thuyết tại trường Đại học Leyden, sau đó lấy bằng tiến sỹ về  khoa học máy tính tại trường Đại học Amsterdam. Ông làm một lập trình viên tại  Mathematisch Centrum- Amsterdam từ 1952-1962; là một giáo sư toán học tại trường  Đại học công nghệ Eindhoven từ 1962-1984; là nhà nghiên cứu của Burroughs  Cooporation từ 1973-1984. Ông đã công tác tại trường Đại học Texas ở Austin và  làm giáo sư danh dự từ 1999.<br />
Dijkstra sống cùng với vợ, ba người con và hai  cháu. Dijkstra đã nhận giải thưởng ACM Turing vào năm 1972 (giải thưởng này được  coi là giải thưởng Nobel cho tin học). Ông là một thành viên của học viện hoàng  gia Hà Lan về khoa học và nghệ thuật, là thành viên của một học viện của Mỹ về  khoa học và nghệ thuật, và là viện sỹ của hiệp hội những nhà khoa học máy tính  Anh. Ông còn nhận rất nhiều giải thưởng khác như: AFIPS Harry Goode Award, IEEE  Computer Pioneer Award, ACM SIGCE Award; trường Đại học Athens đã trao tặng ông  bằng tiến sỹ danh dự vào năm 2001. Tổ chức C&#38;C Foudation của Nhật Bản đã coi  Dijkstra là người có công đầu tiên trong việc xây dựng nền tảng của lĩnh vực  phần mềm máy tính thông qua những công trình nghiên cứu về lý thuyết phần mềm,  lý thuyết thuật toán, lập trình cấu trúc và ngành ký hiệu học.<br />
Dijkstra nổi  tiếng vì đã nhận thức được rằng logic toán học là nền tảng để xây dựng nên những  chương trình máy, ngoài ra ông còn có nhiều đóng góp trong việc thúc đẩy sự phát  triển của các phương pháp toán học trong khoa học máy tính. Ông là người chịu  trách nhiệm xây dựng hệ điều hành theo phương pháp đồng bộ hoá các tiến trình  tuần tự (sequential processes); phát triển các chương trình máy tính, các phương  pháp kiểm tra chương trình chuẩn mực. Đặc biệt, ông trở nên rất nổi tiếng với  thuật toán tìm đường đi ngắn nhất, với những thành công trong việc thiết kế và  viết mã nguồn cho chương trình biên dịch Algol 60 đầu tiên. Ông cũng là người đi  đầu trong việc đề nghị loại bỏ câu lệnh nhảy GOTO trong chương  trình.<br />
Dijkstra có khả năng viết rất đáng khâm phục. Toàn bộ các công trình  của ông là một bộ sưu tập lớn với hơn 1300 tác phẩm (nếu quan tâm, bạn có thể  tìm hiểu thông qua địa chỉ http://www.cs.utexas.edu/users/EWD). Ông thường xuyên  trao đổi thư từ với hàng trăm người bạn và đồng nghiệp khác, tuy nhiên không  phải qua thư điện tử (email) mà qua những lá thư viết tay giản dị. Ông thích  dùng bút máy hơn là máy tính để viết những công trình khoa học và những lá thư  của mình.<br />
Dijkstra còn nổi danh vơi biệt tài hùng biện, sự dí dỏm và lối dùng  từ thông minh. Chẳng hạn, ông có nhận xét: ″Câu hỏi <em>máy tính có khả năng nghĩ  được không </em>thì cũng giống như câu hỏi <em>tàu ngầm có bơi được không</em>″;  lời khuyên của ông cho một nhà nghiên cứu khi được hỏi làm thế nào để chọn lựa  được chủ đề nghiên cứu là: ″<em>Hãy chỉ nên làm những gì mà bạn có thể làm</em>″;  nhận xét của ông trong buổi nói chuyện về giải thưởng Turing của mình: ″Với tư  cách là một công cụ, thì máy tính chỉ là một làn sóng nhỏ trên bề mặt nền văn  minh của chúng ta. Với tư cách là thách thức trí tuệ, máy tính là tiền tiền lệ  trong lịch sử văn hoá của loài người″.<br />
Dijkstra làm giàu thêm cho ngôn ngữ  máy tính với nhiều khái niệm và thành ngữ như lập trình có cấu trúc,sự đồng bộ  hoá, semaphores, câu lệnh.. Cuốn từ điển Oxford English Dictionary trích dẫn các  từ như ″vector″ và ″stack″ mà ông đã đề xướng.<br />
Dijkstra thích chơi nhạc của  Mozart bằng đàn piano cho bạn bè thưởng thức. Ông và người vợ của mình có thú  vui đi thám hiểm những công viên quốc gia bằng xe buýt riêng, chiếc xe được gán  cho cái tên Touring Machine, trong đó ông đã viết rất nhiều công trình khoa  học.<br />
Trong sự nghiệp khoa học của mình, Dijkstra đã nghiên cứu và theo đuổi  những tư tưởng có tính học thuật cao, không bị ràng buộc bởi chính trị, thương  mại, hay sự thúc ép bên ngoài nào. Nói một cách đơn giản, vẻ đẹp và sự tao nhã  trong lập trình và toán học đã là nguồn cảm hứng vô tận của ông. Ông giải quyết  công việc một sự tập trung cao độ, ông còn luôn luôn đưa ra nhiều thách thức cho  đồng nghiệp để cùng nghiên cứu. Trong thời gian rảnh rỗi, ông luôn sẵn lòng làm  vai trò như một nhà chính trị trong việc thúc đẩy sự phát triển của xã hội, ông  thường chỉ ra những sai lầm trong lối suy nghĩ của mọi người, chỉ ra sự nguy  hiểm của những tư tưởng cơ hội.. Ông có khả năng tổ chức mọi người thành những  nhóm thảo luận, nghiên cứu nhỏ nhằm góp phần nảy sinh ra những ý tưởng mới  mẻ.<br />
Dijkstra còn được mọi người kính trọng và khâm phục bởi ông là một con  người thông thái và rất mực công bằng.<br />
</span></p>
<p align="right"><span style="font-family:Times New Roman;font-size:small;"><strong>Nguyễn Văn Trường<br />
Trường ĐHSP Thái  nguyên</strong></span></p>
<p><strong><br />
</strong></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[To goto or to not goto? - At first glance]]></title>
<link>http://codepath.wordpress.com/2009/06/04/to-goto-or-to-not-goto-at-first-glance/</link>
<pubDate>Thu, 04 Jun 2009 15:22:48 +0000</pubDate>
<dc:creator>pritin</dc:creator>
<guid>http://codepath.wordpress.com/2009/06/04/to-goto-or-to-not-goto-at-first-glance/</guid>
<description><![CDATA[Most of the languages in use today, do indeed have the gotostatement. As we do already know, the got]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Most of the languages in use today, do indeed have the <span style="font-weight:bold;">goto</span>statement. As we do already know, the <span style="font-weight:bold;">goto</span> statement is used to unconditionally jump from place to place within a program, with destinations marked as <span style="font-weight:bold;">labels</span>. As you can already guess, this can make a program really hard to read, with its particularly<span style="font-style:italic;">jumpy</span> nature. The programmer, with all his wits, could well have written a perfectly unambiguous program, but what about his code? Sure ; he knows all about his own program, and is in a position to debug it and make changes, but what about debugging, when it comes to a team environment? While our smart programmer is on leave in Hawaii, rewarded for his hard work, how miserable life will be for his coworkers!<br />
Oh, and did I mention the program had 352 <span style="font-weight:bold;">goto </span>statements?</p>
<p>In the days of the structured programmer, the <span style="font-weight:bold;">goto</span> statement was a very powerful tool in the hands of a very powerful programmer. His days, however, are no more. Neither him nor his tool are powerful anymore. However, it would be wrong to say that the <span style="font-weight:bold;">goto</span> statement does not have any application in high level programming. While some high level languages, like <span style="font-style:italic;">Java</span> do not support the statement, other languages such as C#.NET continue to allow it ; and it proves to be useful in causing <span style="font-style:italic;">fall-throughs</span> in <span style="font-weight:bold;">switch-case </span>blocks.</p>
<p>The popular saying among many, so-called <span style="font-style:italic;">high level programmers</span> is, &#8220;<span style="font-style:italic;">Never use GOTO statements&#8221; ; </span>but this need not be completely true. However, there have been several great computer scientists, whose work has formed the base for what most of computer science is today, have sternly voiced their concerns against the <span style="font-weight:bold;">goto </span>statement. The most popular of such cases is Edsger W. Dijkstra&#8217;s letter to <span style="font-style:italic;">Communications of the Assosciation for Computing Machinery</span> in 1968, titled <span style="font-weight:bold;">A case against the go to statement. </span>(<a href="http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF">here</a>)<span style="font-family:helvetica, arial, 'sans serif';"></p>
<p></span></p>
<blockquote><p>Since a number of years I am familiar with the observation that the quality of programmers is a decreasing function of the density of go to statements in the programs they produce. Later I discovered why the use of the go to statement has such disastrous effects and did I become convinced that the go to statement should be abolished from all &#8220;higher level&#8221; programming languages (i.e. everything except –perhaps- plain machine code).</p></blockquote>
<p>In reality, <span style="font-weight:bold;">goto</span> statements belong to assembly language code, where the program, has no other option, but to jump (conditionally or unconditionally) to memory locations, specified explicitly in the program itself. When structural programming was programmer fashion, the <span style="font-weight:bold;">goto</span> statement, as I already mentioned was a very powerful tool; but this was before the<span style="font-weight:bold;">while</span> and <span style="font-weight:bold;">for</span> loop even came into existence. Now, with better options at hand which were not available at earlier times, we must strive to do whatever we can to make our programs easier to manage, read and debug - <span style="font-style:italic;">we must strive to make our programs more high-level.</p>
<p></span></p>
<blockquote><p>The go to statement as it stands is just too primitive, it is too much an invitation to make a mess of one&#8217;s program.</p></blockquote>
<p>The use of the word <span style="font-weight:bold;">mess</span>, in my opinion is quite apt. Imagine a program with 352 <span style="font-weight:bold;">goto</span> statements. You&#8217;re probably going to spend more than half of your office hours scrolling up and down, trying to locate the labels, and make sense of what the program actually does. (And I&#8217;d sincerely hope you&#8217;re not using the <span style="font-style:italic;">vi text editor.</span>) Owing to this seemingly random <span style="font-style:italic;">flow of control</span>between various statements, programs that use too many <span style="font-weight:bold;">goto</span>statements earn the &#8220;<span style="font-style:italic;">Spaghetti Code&#8221; </span>nickname, which falls very short of a complement.</p>
<p>So why would you use a <span style="font-weight:bold;">goto </span>statement anyway? It is also a proven fact that every<span style="font-weight:bold;"> goto</span> statement can be replaced with a suitable implementation of a set of looping constructs. (except for the fall through case in <span style="font-weight:bold;">switch</span> blocks I mentioned earlier). The reason for this is probably, that most programmers think (or like to think) in the way a computer thinks; executing a set of statements, and jumping to a new set of statements when a branching instruction is encountered. In a way, this is what dividing your programs into methods/functions also achieves, but it is much easier to <span style="font-style:italic;">manage</span> code.</p>
<p>So, to conclude, to not go to is a much more sensible decision.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Shortest path with Dijkstra and C#]]></title>
<link>http://letmetutoryou.wordpress.com/2009/05/26/shortest-path-with-dijkstra-and-c/</link>
<pubDate>Tue, 26 May 2009 17:42:24 +0000</pubDate>
<dc:creator>letmetutoryou</dc:creator>
<guid>http://letmetutoryou.wordpress.com/2009/05/26/shortest-path-with-dijkstra-and-c/</guid>
<description><![CDATA[Introducing to Graphs Graphs as restructures like trees or you prefer tress are a kind of graph, per]]></description>
<content:encoded><![CDATA[Introducing to Graphs Graphs as restructures like trees or you prefer tress are a kind of graph, per]]></content:encoded>
</item>
<item>
<title><![CDATA[La crisis del software]]></title>
<link>http://jummp.wordpress.com/2009/05/22/la-crisis-del-software/</link>
<pubDate>Fri, 22 May 2009 03:00:29 +0000</pubDate>
<dc:creator>jummp</dc:creator>
<guid>http://jummp.wordpress.com/2009/05/22/la-crisis-del-software/</guid>
<description><![CDATA[La crisis del software, en mi opinión, es algo que todavía no se ha superado, desde que se empezase ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>La crisis del software, en mi opinión, es algo que todavía no se ha superado, desde que se empezase a hablar de ella, en la década de los sesenta, a partir del genial holandés Edsger Dijkstra en su obra &#8220;The Humble Programmer&#8221;</p>
<p>Bien es cierto, que hay autores, con un prestigio infinitamente multiplicado por infinito superior al mío, que consideran que es algo que está superado, como por ejemplo, Roger S. Pressman, que lo redefine como aflicción crónica, al existir cada vez más casos de éxito.</p>
<p>Mi experiencia, al menos en el segmento en el que me muevo, es que se quiera llamar como se quiera, la crisis del software sigue presente.</p>
<p>La crisis del software se refiere principalmente a las siguientes características del proceso de desarrollo:</p>
<p>- Incumplimiento sistemático de los plazos de entrega.<br />
- Desajuste entre el presupuesto inicial estimado y el presupuesto final del proyecto.<br />
- Baja calidad del producto final: Incumplimiento de especificaciones y dificultad de mantenimiento.</p>
<p>Que alguien me diga en qué porcentaje de los proyectos en los que ha participado como programador, analista, jefe de proyectos o gerente se ha cumplido algunas de las premisas anteriores. En bastantes, ¿verdad?.</p>
<p>Por eso pienso que la crisis del software continua, por mucho que la aparición del concepto de ingeniería del software o de múltiples metodologías hayan intentado paliarla.</p>
<p>Bien es cierto, que las bases para eliminar la crisis del software en un proyecto de desarrollo de software son muy conocidas por todos, lo que pasa es que son tantos los ingredientes a utilizar (unos dependientes del grupo de desarrollo y otros no) para que un proyecto salga bien en plazos, presupuesto y calidad, que no resulta nada sencillo (aunque no es imposible) conseguirlo.</p>
<p>Por todo lo anterior, pese a que la solución tiene una base metodológica y de disciplina (de todas las partes que intervienen en el proyecto, teniendo mucho peso la parte usuaria), la base para arreglarla es cultural, es decir, la adquisición de buenos hábitos de base para el desarrollo de proyectos software (ya que sin esta cultura, la metodología se llenará de polvo en las estanterías y la disciplina un bien perecedero) y la erradicación de los mitos del software en todas sus vertientes.</p>
<p>Nadie tiene la llave para ser infalible en los proyectos de desarrollo de software, es decir, como he dicho antes, un proceso de desarrollo tiene muchos condicionantes y es muy complicado manejarlos todos, sobre todo cuando no dependen de uno. En cualquier caso, lo que hay que intentar siempre es tender a hacer las cosas de la mejor manera posible y a intentar cumplir los objetivos de plazos, presupuestarios y de calidad, porque si hay una cosa que debe clara a todos, es que si un proyecto no se enfoca hacia esos objetivos, es complicado, muy complicado, que se consigan por casualidad.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Regular expressions and "the horror!"]]></title>
<link>http://spinoza1111.wordpress.com/2009/05/17/regular-expressions-and-the-horror/</link>
<pubDate>Sun, 17 May 2009 13:01:35 +0000</pubDate>
<dc:creator>spinoza1111</dc:creator>
<guid>http://spinoza1111.wordpress.com/2009/05/17/regular-expressions-and-the-horror/</guid>
<description><![CDATA[Jeff Atwood has long blogged about &#8220;coding horrors&#8221;, but reading this post crystallizes ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Jeff Atwood has long blogged about &#8220;coding horrors&#8221;, but reading <a href="http://www.codinghorror.com/blog/archives/001016.html">this post</a> crystallizes for me why I&#8217;ve left the programming field.</p>
<p>This is because like most folklore about programming, the sage advice ignores the essentials.</p>
<p>Regular expressions were originally purely mathematical expressions which could be ambiguous (such as &#8220;*A&#8221;, anything followed by A, where &#8220;anything&#8221; might include A). They could be ambiguous because their function was to declare a class of languages.</p>
<p>&#8220;*A&#8221; (&#8220;anything A&#8221;) doesn&#8217;t preclude A from appearing more than once in a string in the language it defines because it is silent about what follows the last A. Unlike the corresponding regular expression code in a &#8220;real&#8221; regular expression used by a programmer, &#8220;*A&#8221; is silent about what follows A.</p>
<p>For the mathematician, &#8220;anything A&#8221; is implicitly followed by indeterminancy. He will interpret &#8220;anything A&#8221; as possibly including the letter A in anything since it&#8217;s not followed by &#8220;end of signal&#8221; or &#8220;nothing&#8221;.</p>
<p>Mathematically, &#8220;anything A&#8221; is perfectly fine, or, if you prefer, well-formed mathematical expressions are beyond good and evil and must be taken on their own terms. For example, the &#8220;limit&#8221; of calculus, were it a programming tool or concept, would be unacceptably vague. Science deals with partial knowledge, but in programming we try to control everything.</p>
<p>Which means the programmer has to translate the math to &#8220;*A$&#8221; where the dollar sign is some character meaning &#8220;end&#8221;.</p>
<p>But &#8220;end of input&#8221; never occured, as far as I know, the John von Neumann or Claude Shannon, two of the original mathematicians to work with mathematical regular expressions. This is because <em>end of input has no special mathematical meaning</em>.</p>
<p>Consider this. The programmer defines $ (end of input) to mean &#8220;what happens at the end of an input string&#8221;, and he is thinking about phenomena without mathematical significance, such as some user pressing the Enter key.</p>
<p>But the mathematician is not at liberty to delimit his input (and it is a programmer failing to see how the latter&#8217;s ability to set norms and conventions for his work makes him a technician, not a scientist). If the mathematician is told, $ means end of input, he will ask, what come after that? To him, $ is just another symbol, without the power to forbid other symbols to follow it.</p>
<p>John Cusack, in the 1989 film Say Anything, is asked by his girlfriend&#8217;s father&#8217;s criminal tax accountant what he wants to do with his life. Cusack says, I dunno, I just want to hang out with Mister So and So&#8217;s daughter. When pressed, Cusack says, well I don&#8217;t want to &#8220;process&#8221; anything.</p>
<p>Likewise, the mathematician, unlike the programmer, is uninterested in &#8220;processing data&#8221;, so to a mathematician, $ have no meaning&#8230;just as Cusack seems to the criminal tax accountant to be uninterested in Holy Money.</p>
<p>&#8220;Anything A&#8221; is mathematically meaningful but lousy &#8220;code&#8221;. This is because it cannot be a subexpression in a larger regex without trouble.</p>
<p>Consider &#8220;*AB&#8221;. As code it doesn&#8217;t specify whether AB can appear as part of &#8220;anything&#8221;. Worse, different regular expression systems in common use will treat this situation differently, and are documented in ways that imply that there is more than one way of interpreting &#8220;*&#8221;. Here, the programmer is just kidding in using asterisk: he means &#8220;anything except, of course, AB, silly&#8221;, and worse, some regexp systems pander to this sloppy thinking.</p>
<p>The problem is that sequencing (one basic RE subexpression such as &#8220;*&#8221; followed by another such as &#8220;AB&#8221;) is not thought of consciously as a regular expression operator of equal status with alternation (*&#124;AB). But concatenation, sequencing is a genuine operator, with three possible interpretations:</p>
<p>1. If the handles of the sequenced pair share a non-null common set of characters, refuse to proceed.<br />
2. If the handles share this non-null intersection, prefer the left hand side<br />
3. If the handles share this prefer the rhs.</p>
<p>Programmers are if Prometheus clumsy, for they pervert mathematics. </p>
<p>Which brings me to Jeff&#8217;s article. The credit crisis alone, which has a large software component, indicates that there&#8217;s something very wrong with programming as folklore.</p>
<p>Programming-as-folklore consists of pseudosage advice meant to avoid difficulty. Now, there&#8217;s nothing wrong with artisanship and craft, but programming folklore replaces mathematics. </p>
<p>In mathematics, &#8220;anything A&#8221; means &#8220;anything followed by the letter A, including AA or AAA&#8221;. In programming it might or might not be a bug, because no independent effort has been made to &#8220;standardize&#8221; regular expressions.</p>
<p>But &#8220;standardization&#8221; brings me to the real horror&#8230;the Heart of Darkness, if you will, or, if you prefer, Apocalypse Now.</p>
<p>&#8220;Standardization&#8221; is a bureaucratic <em>ersatz</em> for something hero computer scientist Edsger Dijkstra said he wanted in his 1972 Turing Award lecture and didn&#8217;t get. Dijkstra had been horrified, like Mistah Kurtz, by the IBM 360.</p>
<p>He was horrified by the IBM 360 because after several years of work which had shown the importance of being able to save the overall state of a computation quickly, safely, and in the general case, the designers (led by Gene Amdahl) decided that there needed instead to be 16 [sic] &#8220;general-purpose registers&#8221; named R0..R15&#8230;and no stack in sight. As a direct result, in the 1970s, I knew several bitter, twisted, and prematurely aged assembler programmers who each had come to terms, each in his own way, with what you do when you call a subroutine.</p>
<p>Amdahl&#8217;s anti-intellectualism treated the actual normal case, one of almost overwhelming complexity in real workplaces, as something that would almost never obtain: his reasoning resembled that of Columbia space shuttle engineers who reasoned that because by 2003 large chunks of foam had not dropped off Columbia, things would continue as before. But in reality, there were all sorts of complex applications for the 360 even in the &#8220;ordinary&#8221; business world.</p>
<p>For example, graphs, lattices, trees and recursion are thought to be &#8220;highly theoretical&#8221; by &#8220;ordinary business programmers&#8221;: but I encountered recursion implemented foolishly and by accident in software at a re-insurer (an insurance company that insured other companies against loss). The difficulty of &#8220;unwinding&#8221; securitized mortgages in today&#8217;s credit crisis is caused by the fact that in the large, a securitized instrument is a vast tree of financial relationships, encoded in software. In some cases, this branching tree may be a graph, for nothing in many systems prevents a derivative from being linked to itself through an indirect chain.</p>
<p>Dijkstra felt that some sort of tribunal of academic people should vet new computers for their mathematical safety and correctness. Suffice it to say, he was ignored, with the ersatz being &#8220;standardization&#8221; being driven by manufacturer greed, as in the absurd case of the &#8220;standardization&#8221; of C.</p>
<p>But this is a special case of something so general as to constitute our world: for the fact is that people, in an administered world, are so administered, and so fucked-over, from cradle to grave as to not be able to think outside the real box. In the 1950s, in Britain especially, in the USA to a degree, this was the welfare state, but the welfare state was of course entirely too much the carrot and not the stick, so the carrot is also the stick.</p>
<p>As such, when Dijsktra mentions a tribunal of academics, we get a standardization committee. Such committees, however, are unimpressed with anything like mathematical elegance.</p>
<p>&#8220;Regular expressions&#8221; retain for this reason a meaning only in mathematics. In programming, they are whatever Perl, or regex, chooses them to be.</p>
<p>I bailed happily out of the cynical world this created in programming.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[symptoms of being in love.]]></title>
<link>http://iisc.wordpress.com/2009/04/15/symptoms-of-being-in-love/</link>
<pubDate>Thu, 16 Apr 2009 06:01:48 +0000</pubDate>
<dc:creator>iisc</dc:creator>
<guid>http://iisc.wordpress.com/2009/04/15/symptoms-of-being-in-love/</guid>
<description><![CDATA[Vamsi asked me such a delicate question that instead of answering him as a comment, I thought of com]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Vamsi asked me such a <a href="http://iisc.wordpress.com/2009/04/13/bhondoo-celebrates-valentines-day/#comment-1288">delicate question</a> that instead of answering him as a comment, I thought of coming up with a new post. His question was:</p>
<blockquote><p>But how does one know if he/she is in “true” love??</p></blockquote>
<p>Being a novice in the field, I consulted bhOndOO, the person having long time experience in Love. He told me the following symptoms. Although the symptoms are related to <em>iisc life</em>, those can be easily transformed into the appropriate environment. Further, the symptoms assume a male Lover, appropriate modifications should be done for a female Lover. Here is what bhOndOO says.</p>
<p>You are in Love:</p>
<ul>
<li> when the first thought in the morning (or whenever you wake up) is not that of your advisor, but of her.</li>
<li> when for no apparent reason, you smile to yourself and look around to see nobody witnessing it.</li>
<li> when you walk on the road in front of the library and start noticing pairs of birds rather than worrying about the <a href="http://iisc.wordpress.com/2008/04/15/shit-blessings/">shitty blessings</a>.</li>
<li> when you are sitting alone in your hostel room, although impossible, you feel that she would knock at the door.</li>
<li> when you avoid calling your friends on mobile because you are expecting a call from her and she should not receive an engaged tone.</li>
<li> when she calls and you see her name on the mobile display, smile follows the missing pulse. When you say &#8220;Hello&#8221;, you try to hide all your excitement as if her number is not even stored in your mobile.</li>
<li> when you keep looking at the tea board entrance or the mess entrance for her arrival &#8212; even if that never happens.</li>
<li> when you pay for her in tea board, you start thinking about running the house together!</li>
<li> when you see a happy couple with a child in Nesara, you steal a glance at her for her reaction.</li>
<li>when you miss a lecture to have a coffee with her.</li>
<li>when the first thing you notice when you reach the department is her bicycle.</li>
<li> when on her birthday, you gift her something that she casually talked about almost 11 months back.</li>
<li> when you keep searching for her name on google, keep checking her orkut scrapbook, keep checking her friends&#8217; scrapbook for what she has written, and feel skeptical about the boy who writes often in her scrapbook.</li>
<li>when you try to postpone the meeting with your advisor because you have to meet her.</li>
<li>when asleep, you dream of her getting married to Gullu.</li>
<li>when you read <a href="http://en.wikipedia.org/wiki/The_Fountainhead">The Fountainhead</a>, you imagine yourself to be Howard Roark and her to be Dominique Francon.</li>
<li>when you are appreciated by friends or advisor, you wish hard that she should have been there.</li>
<li>when you share your childhood photo with her.</li>
<li>when suddenly Dijkstra&#8217;s shortest path algorithm starts outputting the path from your hostel to the department via her hostel.</li>
<li>when you feel happy to see her smiling.</li>
</ul>
<p>What are your symptoms?</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[From CodingHorror.com : Should programmers be "mathematically inclined"?]]></title>
<link>http://randomspark.wordpress.com/2009/04/12/from-codinghorrorcom-should-programmers-be-mathematically-inclined/</link>
<pubDate>Sun, 12 Apr 2009 05:26:34 +0000</pubDate>
<dc:creator>Mike Suria</dc:creator>
<guid>http://randomspark.wordpress.com/2009/04/12/from-codinghorrorcom-should-programmers-be-mathematically-inclined/</guid>
<description><![CDATA[Came across this article while perusing the CodingHorror blog today. Quite interesting read, too. Yo]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Came across this article while perusing the CodingHorror blog today. Quite interesting read, too. You should read this one if you&#8217;re in the same line of work as I am </p>
<p>http://www.codinghorror.com/blog/archives/001249.html</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[What the World needs?]]></title>
<link>http://damecar.wordpress.com/2009/03/11/what-the-world-needs/</link>
<pubDate>Thu, 12 Mar 2009 03:49:55 +0000</pubDate>
<dc:creator>Antonio</dc:creator>
<guid>http://damecar.wordpress.com/2009/03/11/what-the-world-needs/</guid>
<description><![CDATA[You must not give the world what it asks for, but what it needs. -Edsger Wybe Dijkstra.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>You<span> </span>must not give the world<span> </span>what it asks for, but what it needs.</p>
<p style="text-align:right;"><em>-Edsger Wybe Dijkstra.</em></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Reading #1 Reid Ginoza]]></title>
<link>http://codecritique.wordpress.com/2009/03/03/reading-1-reid-ginoza/</link>
<pubDate>Tue, 03 Mar 2009 11:33:15 +0000</pubDate>
<dc:creator>codecritique</dc:creator>
<guid>http://codecritique.wordpress.com/2009/03/03/reading-1-reid-ginoza/</guid>
<description><![CDATA[Dijkstra aims to present programming &#8220;as a discipline on its own merits, as a methodology of c]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Dijkstra aims to present programming &#8220;as a discipline on its own merits, as a methodology of constructive reasoning applicable to any problem capable of algorithmic solution,&#8221; quoted from Niklaus Wirth. To this end, Dijkstra describes “the programmer&#8217;s activity as ‘designing a class of computations’, rather than as ‘making a program’.”</p>
<p>What is so striking about these descriptions is their attention toward the abstract. Programmers are not just looking for a computation, but a class of them. A class is used to describe some collection of items—in this case, computations—that have some major feature in common. By focusing on this common feature, we make our attention more abstract and less stuck on the particulars.</p>
<p>For example, sorting words into a dictionary and sorting PIN numbers numerically involve two different concretes. The first deals with letters, the second with numbers. But look at what they have in common: both the letters and the digits are grouped into a larger whole, say a “word” in the general sense (including letter words and number words), and both the alphabet and the numbers have an order to them. When we realize that there is an order to these basic building blocks (letters or numbers), we no longer care whether they are numbers or letters, and instead, we just apply a sorting algorithm. All that was needed to sort is an ordering system.</p>
<p>Dijkstra’s work, especially in the middle chapters with the study of sequences, has led me to a deeper understanding of where the mathematics comes into computing. By Dijkstra’s definition, computing must be a process of abstraction. You must be able to identify when the computations are the same, when they’re different, and when certain ones are specific instances of another more general one. This is how one can form those classes of computations.</p>
<p>Because there is a serious attempt to focus on the abstraction, it makes sense that mathematics enters computing. Mathematics is a well-refined language for identifying exactly what those common features between objects are and what logical consequences those features lead to. Math itself describes abstractions.</p>
<p>The Hoare logic was  especially exciting. Although it is clearly mathematical, it’s exciting to watch the concept develop out of the need to communicate and refine algorithms. This truly is “applied math” as Dijkstra had said. With the mathematics of the Hoare logic, one is able to identify quickly what are the important parts of the programs are, without getting bogged down by the details.</p>
<p>And thus, with the mathematics, one is able to quickly identify where the classes of computations are, because it is easy to see which computations have the same form or not. Once one has those classes of computations, arriving at a suitable algorithm for a particular job just means following a similar abstraction one took to identify those classes in the first place. If that falls into a class that has already been solved, then you benefit from the work done before you.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Rineke Dijkstra]]></title>
<link>http://brianjmorrison.wordpress.com/2009/02/07/rineke-dijkstra/</link>
<pubDate>Sat, 07 Feb 2009 11:22:12 +0000</pubDate>
<dc:creator>brianjmorrison</dc:creator>
<guid>http://brianjmorrison.wordpress.com/2009/02/07/rineke-dijkstra/</guid>
<description><![CDATA[Dijkstra is a Dutch Photography/ artist who works mostly on single person portraits, but generally f]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Dijkstra is a Dutch Photography/ artist who works mostly on single person portraits, but generally forming some sort of larger series. She has approached topics such as social grouping and the passage of time.</p>
<p>In the series below Dijkstra photographs young men and women who have recently been enlisted into military service, Shany (below) is photographed in 2002 at the induction center in Israel and this continues over 18 months. Each portrait is an intimate reflection on identity and personal expression in the face of military oppression.</p>
<p><img class="aligncenter size-full wp-image-139" title="Shany, Herzliya Israel 2002" src="http://brianjmorrison.wordpress.com/files/2009/02/tng_006.jpg" alt="Shany, Herzliya Israel 2002" width="296" height="388" /></p>
<p><img class="aligncenter size-full wp-image-140" title="Shany, Herzliya Israel 2003" src="http://brianjmorrison.wordpress.com/files/2009/02/tng_007.jpg" alt="Shany, Herzliya Israel 2003" width="296" height="387" /></p>
<p><a href="http://www.rinekedijkstra.net/">WEBSITE</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Citazione della settimana]]></title>
<link>http://syymza.wordpress.com/2009/02/02/citazione-della-settimana-2/</link>
<pubDate>Mon, 02 Feb 2009 21:53:11 +0000</pubDate>
<dc:creator>syymza</dc:creator>
<guid>http://syymza.wordpress.com/2009/02/02/citazione-della-settimana-2/</guid>
<description><![CDATA[L&#8217;informatica non riguarda i computer più di quanto l&#8217;astronomia riguardi i telescopi. (]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><em>L&#8217;informatica non riguarda i computer più di quanto l&#8217;astronomia riguardi i telescopi.<br />
(Edsger Wybe Dijkstra)</em></p>
<p><strong>Note dall&#8217;Angolo di Dani:</strong></p>
<p>Dijkstra, per chi non lo conoscesse, è tra i personaggi più odiati tra coloro che studiano informatica, per due fondamentali ragioni:</p>
<ol>
<li>Nessuno conosce l&#8217;esatta pronuncia del suo cognome (provando ad associare il nome esce poi una specie ci scioglilingua)</li>
<li>E&#8217; a lui che è attribuito uno degli algoritmi alla base della ricerca operativa, quello relativo ai cammino minimi, richiamato in problemi di reti e programmi software.</li>
</ol>
<p>Nonostante ciò, tutti riconoscono la sua genialità: basti pensare che è tra coloro che han ricevuto un Premio Turing, una specie di equivalente del Premio Nobel (inesistente per l&#8217;informatica).</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[On the Importance of Representations]]></title>
<link>http://arungiridhar.wordpress.com/2009/01/17/on-the-importance-of-representations/</link>
<pubDate>Sat, 17 Jan 2009 21:41:12 +0000</pubDate>
<dc:creator>Arun</dc:creator>
<guid>http://arungiridhar.wordpress.com/2009/01/17/on-the-importance-of-representations/</guid>
<description><![CDATA[Note: This post is a first attempt to write about topics that are of professional or didactic intere]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><em>Note: This post is a first attempt to write about topics that are of professional or didactic interest, but which may not be profound enough to merit a separate journal paper or other publication. Some of these topics originated from research-related conversations around campus, and others from internal group seminars in the past few years. I request feedback about length, tone, and format styles.</em></p>
<h4>A. Introduction</h4>
<p>There are generally two separate decisions to make in any computational problem. The first is to represent the knowledge about the problem in some useful way. Usually we are required to choose one of several possible representations. The second is to choose a method (or an algorithm) that can operate on the representation to produce the required result. Depending on the representation chosen, there may be several algorithms available to choose from.</p>
<p>From a practical perspective, a good algorithm is often one that is acceptably fast and makes acceptably low demands on system resources (like memory), and the analysis of algorithms is a rich field in its own right with powerful mathematical tools. Choosing the right representation, however, is more often the result of personal or learned experience based on a rare insight than on rigorous analysis. This post shows the importance of knowing what representation to use for what situation.</p>
<h4>B. Example</h4>
<p>Here&#8217;s an example problem (<a href="http://projecteuler.net/index.php?section=problems&#38;id=172">Problem 172</a> from <a href="http://projecteuler.net/">Project Euler</a>) that shows the importance of the right representation:</p>
<p>How many 18-digit numbers n (without leading zeros) are there such that no digit occurs more than three times in n?</p>
<p>(I recommend that you spend some time analyzing the problem by yourself before reading further).</p>
<h4>C. First Representation</h4>
<p>Now, what is the first representation that springs to mind? Most of us probably visualized a one-dimensional array, each element representing a digit of the 18-digit number and ranging in value from 0 to 9 (except for the element corresponding to the first digit, which goes from 1 to 9). Let&#8217;s call this representation R1.</p>
<table width="100%" cellpadding="1" cellspacing="1" summary="Representation R1" border="2">
<tr>
<th>Digit</th>
<th>10<sup>17</sup></th>
<th>10<sup>16</sup></th>
<th>10<sup>15</sup></th>
<th>10<sup>14</sup></th>
<th>10<sup>13</sup></th>
<th>10<sup>12</sup></th>
<th>10<sup>11</sup></th>
<th>10<sup>10</sup></th>
<th>10<sup>9</sup></th>
<th>10<sup>8</sup></th>
<th>10<sup>7</sup></th>
<th>10<sup>6</sup></th>
<th>10<sup>5</sup></th>
<th>10<sup>4</sup></th>
<th>10<sup>3</sup></th>
<th>10<sup>2</sup></th>
<th>10<sup>1</sup></th>
<th>10<sup>0</sup></th>
</tr>
<tr>
<th>Values</th>
<td align="center">1&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
</tr>
</table>
<p>Clearly this is a natural first choice for a representation, and a natural choice of accompanying algorithm (algorithm A1) would be a bunch of nested for-loops, one for each digit, with a series of if-else statements buried inside all the loops to check for legality (no digit should occur more than thrice), and a statement to increment a counter for every legal number found. The total time spent inside the loops is then <img src='http://l.wordpress.com/latex.php?latex=9%5Ctimes+10%5E%7B17%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9\times 10^{17}' title='9\times 10^{17}' class='latex' /> evaluations, which would take a few hundred thousand years to complete.</p>
<p>One &#8220;refinement&#8221; to this brute-force approach would be to use backtracking, which is to bring some of the if-else checks from the deepest for-loop to some of the outer for-loops, so that illegal sub-numbers with just a few digits are trapped and pruned off early instead of letting them grow into full-fledged 18-digit numbers. Let us be extremely generous and say that backtracking would speed up the brute-force algorithm A1 by a million times. The estimated run time is now &#8220;only&#8221; <img src='http://l.wordpress.com/latex.php?latex=9%5Ctimes+10%5E%7B11%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9\times 10^{11}' title='9\times 10^{11}' class='latex' /> loop evaluations, and can be done in a few months.</p>
<p>Backtracking has its advantages over brute-force, but thinking up any improvement to the algorithm A1 without changing the underlying representation R1 is essentially an exercise in futility, because at the very least, no algorithm based on A1 can go faster than having to evaluate the number of legal solutions, which could still be intractably large. A better representation is needed.</p>
<h4>D. Second Representation</h4>
<p>Here are some thoughts:</p>
<p>1. The problem is to find only the number of possible solutions, not to actually list them out. (Knuth<a href="#refknuth" id="knuth"><sup>[1]</sup></a>   calls these two distinct questions &#8220;enumeration&#8221; and &#8220;generation&#8221; respectively, which is the terminology I adopt). We need an algorithm that can compute the final number of solutions without having to wade through each individual solution in turn. It&#8217;s like the difference between saying &#8220;There are <img src='http://l.wordpress.com/latex.php?latex=52%21&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='52!' title='52!' class='latex' /> permutations of a deck of cards&#8221;, which takes 3 seconds to say out loud (unless you&#8217;ve been taking interesting medication), and having to list out all <img src='http://l.wordpress.com/latex.php?latex=52%21&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='52!' title='52!' class='latex' /> permutations and counting them one by one, which would take <img src='http://l.wordpress.com/latex.php?latex=10%5E%7B50%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='10^{50}' title='10^{50}' class='latex' /> times the age of the universe. We need a representation that will allow such an algorithm to operate.</p>
<p>2. The number of legal 18-digit numbers (those with at most 3 occurrences of any digit) is less than the number of all 18-digit numbers. We would prefer a representation that allows for only the legal numbers to be represented if possible.</p>
<p>3. If an 18-digit number is legal, then all permutations of its digits are also legal. Additionally, if it is illegal, then all permutations of its digits are also illegal. To restate, what is important for the problem is only the number of instances of each numeral (0&#8211;9), and not their position within the 18-digit number itself.</p>
<p>The third point above immediately suggests an alternate representation R2. This representation is a one-dimensional array of length 10, representing the numerals from 0 to 9. The value of each element of the array is the number of occurrences of the corresponding numeral, which we can limit to be in the range [0,3] since we know that no numeral can occur more than 3 times.</p>
<table width="75%" cellpadding="1" cellspacing="1" summary="Representation R1" border="2">
<tr>
<th>Numeral</th>
<th>9</th>
<th>8</th>
<th>7</th>
<th>6</th>
<th>5</th>
<th>4</th>
<th>3</th>
<th>2</th>
<th>1</th>
<th>0</th>
</tr>
<tr>
<th>Occurrences</th>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
<td align="center">0&#8211;3</td>
</tr>
</table>
<p>Further, the sum of all the array elements should be exactly equal to the number of digits (18 in this case) of the final number. Even the most basic brute-force algorithm A2 will now have to examine only <img src='http://l.wordpress.com/latex.php?latex=4%5E%7B10%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4^{10}' title='4^{10}' class='latex' /> = a million cases for validity. It is also easy to speed up algorithm A2 using the equality constraint that the array elements have to add up to 18, by looping through only 9 of the elements and computing the tenth as being 18 minus the sum of the first 9. The number of distinct cases is now only <img src='http://l.wordpress.com/latex.php?latex=4%5E%7B9%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4^{9}' title='4^{9}' class='latex' /> = a quarter million. For each array, the number of distinct permutations of the 18-digit number is given by the <a href="http://en.wikipedia.org/wiki/Multinomial_theorem">multinomial of the array elements</a>: <img src='http://l.wordpress.com/latex.php?latex=%5Cfrac%7B%5Cleft%28%5Csum_%7Bi%3D0%7D%5E9+a_%7Bi%7D%5Cright%29%21%7D%7B%5Cprod_%7Bi%3D0%7D%5E%7B9%7D%5Cleft%28a_%7Bi%7D%21%5Cright%29%7D+%3D+%5Cfrac%7B18%21%7D%7B%5Cprod_%7Bi%3D0%7D%5E%7B9%7D%5Cleft%28a_%7Bi%7D%21%5Cright%29%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\frac{\left(\sum_{i=0}^9 a_{i}\right)!}{\prod_{i=0}^{9}\left(a_{i}!\right)} = \frac{18!}{\prod_{i=0}^{9}\left(a_{i}!\right)}' title='\frac{\left(\sum_{i=0}^9 a_{i}\right)!}{\prod_{i=0}^{9}\left(a_{i}!\right)} = \frac{18!}{\prod_{i=0}^{9}\left(a_{i}!\right)}' class='latex' />. All we need to do is run through the <img src='http://l.wordpress.com/latex.php?latex=4%5E%7B9%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4^{9}' title='4^{9}' class='latex' /> cases, check for validity of the tenth digit, and if so, add the multinomial to the answer. (There&#8217;s some minor bookkeeping to keep track of the starting digit not being 0, but it&#8217;s easy to figure out). This approach takes about a second to run, depending on what else you have running in the background. As before, it can be sped up by backtracking, using the fact that if a partial sum of the array elements has exceeded 18, then no assignment of values to the remaining elements will reduce it to within 18, and can therefore be pruned off early.</p>
<h4>E. Third Representation</h4>
<p>It might look like that is the end of the story, but if we revisit the third point from above, we see that it is only the number of instances of each numeral (0&#8211;9) which is required, and not their identities themselves! Representation R1 differentiated between two different numerals and also their position within the 18-digit number. Representation R2 does not bother with the position, but still differentiates between the numerals themselves. Now, we may observe that the number of 18-digit numbers made up of 3 instances each of the numerals {1,2,3,4,5,6} is exactly equal to the number of 18-digit numbers made up of 3 instances each of the numerals {4,5,6,7,8,9}. These were represented two different times in R2, when all we really needed was a way to represent (just once) the fact that 6 numerals were represented 3 times each and the remaining 4 were not represented at all.</p>
<p>Representation R3 implements exactly that, with a one-dimensional array of length 4, representing the number of numerals with 0, 1, 2, and 3 instances each.</p>
<table width="60%" cellpadding="1" cellspacing="1" summary="Representation R1" border="2">
<tr>
<th>Number of numerals with ___ instances each</th>
<th>3</th>
<th>2</th>
<th>1</th>
<th>0</th>
</tr>
<tr>
<th>Ranges</th>
<td align="center">0&#8211;6</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
<td align="center">0&#8211;9</td>
</tr>
</table>
<p>Clearly, the sum of the array should always be 10 (being the number of numerals in 0 to 9), and their index-weighted sum <img src='http://l.wordpress.com/latex.php?latex=3%5Ctimes+a_%7B3%7D+%2B+2%5Ctimes+a_%7B2%7D+%2B+1%5Ctimes+a_%7B1%7D+%2B+0%5Ctimes+a_%7B0%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='3\times a_{3} + 2\times a_{2} + 1\times a_{1} + 0\times a_{0}' title='3\times a_{3} + 2\times a_{2} + 1\times a_{1} + 0\times a_{0}' class='latex' /> should always be 18 (being the number of digits in the final number). Since each element is required to be a non-negative integer, even a brute force approach A3 has only <img src='http://l.wordpress.com/latex.php?latex=min%281%2B18%2Fi%2C+10%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='min(1+18/i, 10)' title='min(1+18/i, 10)' class='latex' /> possibilities for the ith element of the array. The two equality constraints chop off another two degrees of freedom, and even the crudest brute force only lists 7 possibilities for <img src='http://l.wordpress.com/latex.php?latex=a_%7B3%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{3}' title='a_{3}' class='latex' /> (from 0 to 6) and 10 possibilities for <img src='http://l.wordpress.com/latex.php?latex=a_%7B2%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{2}' title='a_{2}' class='latex' /> (from 0 to 9), with <img src='http://l.wordpress.com/latex.php?latex=a_%7B1%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{1}' title='a_{1}' class='latex' /> and <img src='http://l.wordpress.com/latex.php?latex=a_%7B0%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{0}' title='a_{0}' class='latex' /> being computed and checked for legality from <img src='http://l.wordpress.com/latex.php?latex=a_%7B3%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{3}' title='a_{3}' class='latex' /> and <img src='http://l.wordpress.com/latex.php?latex=a_%7B2%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{2}' title='a_{2}' class='latex' />. Out of these 70 possibilities (which can be reduced drastically by adding backtrack to A3), it turns out that there are only 17 legal combinations. </p>
<table width="60%" cellpadding="1" cellspacing="1" summary="Representation R1" border="2">
<tr>
<th>Number of numerals with ___ instances each</th>
<th>3</th>
<th>2</th>
<th>1</th>
<th>0</th>
</tr>
<tr>
<th>a</th>
<td align="center">0</td>
<td align="center">8</td>
<td align="center">2</td>
<td align="center">0</td>
</tr>
<tr>
<th>b</th>
<td align="center">0</td>
<td align="center">9</td>
<td align="center">0</td>
<td align="center">1</td>
</tr>
<tr>
<th>c</th>
<td align="center">1</td>
<td align="center">6</td>
<td align="center">3</td>
<td align="center">0</td>
</tr>
<tr>
<th>d</th>
<td align="center">1</td>
<td align="center">7</td>
<td align="center">1</td>
<td align="center">1</td>
</tr>
<tr>
<th>e</th>
<td align="center">2</td>
<td align="center">4</td>
<td align="center">4</td>
<td align="center">0</td>
</tr>
<tr>
<th>f</th>
<td align="center">2</td>
<td align="center">5</td>
<td align="center">2</td>
<td align="center">1</td>
</tr>
<tr>
<th>g</th>
<td align="center">2</td>
<td align="center">6</td>
<td align="center">0</td>
<td align="center">2</td>
</tr>
<tr>
<th>h</th>
<td align="center">3</td>
<td align="center">2</td>
<td align="center">5</td>
<td align="center">0</td>
</tr>
<tr>
<th>i</th>
<td align="center">3</td>
<td align="center">3</td>
<td align="center">3</td>
<td align="center">1</td>
</tr>
<tr>
<th>j</th>
<td align="center">3</td>
<td align="center">4</td>
<td align="center">1</td>
<td align="center">2</td>
</tr>
<tr>
<th>k</th>
<td align="center">4</td>
<td align="center">0</td>
<td align="center">6</td>
<td align="center">0</td>
</tr>
<tr>
<th>l</th>
<td align="center">4</td>
<td align="center">1</td>
<td align="center">4</td>
<td align="center">1</td>
</tr>
<tr>
<th>m</th>
<td align="center">4</td>
<td align="center">2</td>
<td align="center">2</td>
<td align="center">2</td>
</tr>
<tr>
<th>n</th>
<td align="center">4</td>
<td align="center">3</td>
<td align="center">0</td>
<td align="center">3</td>
</tr>
<tr>
<th>o</th>
<td align="center">5</td>
<td align="center">0</td>
<td align="center">3</td>
<td align="center">2</td>
</tr>
<tr>
<th>p</th>
<td align="center">5</td>
<td align="center">1</td>
<td align="center">1</td>
<td align="center">3</td>
</tr>
<tr>
<th>q</th>
<td align="center">6</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">4</td>
</tr>
</table>
<p>(Recall we started with <img src='http://l.wordpress.com/latex.php?latex=9%5Ctimes+10%5E%7B17%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9\times 10^{17}' title='9\times 10^{17}' class='latex' /> combinations in the first representation). Computing the combinatorics for each of the 17 legal combinations is now a product of two multinomials, one representing the number of ways that ten distinguishable numerals can be partitioned into four sets of sizes <img src='http://l.wordpress.com/latex.php?latex=a_%7B0%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{0}' title='a_{0}' class='latex' /> through <img src='http://l.wordpress.com/latex.php?latex=a_%7B3%7D&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='a_{3}' title='a_{3}' class='latex' />, and the second representing the number of distinct ways that the 18-digit concatenation of those numerals can be permuted. The bookkeeping to prevent the first digit being 0 is a little more involved, and I leave it as an exercise to the reader.</p>
<h4>F. Final Thoughts</h4>
<p>Here are some final thoughts:</p>
<ol>
<li>Representation R1 is unequivocally the wrong representation for this problem. For most problems both R2 and R3 are suitable, but the choice between them depends on the problem instance. For example, if the constraint is to enumerate the number of n-digit numbers no digit of which occurs more than m times, R2 (and A2) will scale polynomially in m with a constant exponent of 10 (the number of numerals), while R3 (and A3) could scale exponentially in m in the worst case. However, it is reasonable to suppose that the average case runtime for R3 and A3 is probably much better than for R2 and A2, as long as the instances are not pathological.</li>
<li>Algorithm A3 is more complicated than A2, requiring some more bookkeeping. For problems with many edge cases or corner cases, the relative simplicity (and consequently the improved maintainability) of R2 and A2 may be worth the lower execution speed.</li>
<li>The specific problem chosen in this may be easy, but it captures the issue of choosing good representations for other (more serious) problems. Still, as of date, only 454 people have solved the problem on Project Euler, compared to over 48,000 who have solved the problem of summing all numbers below 1000 that are multiples of 3 or 5, indicating that for every 100 people who know how to use a for-loop correctly, only one knows how to choose a good representation.</li>
<li>To quote Art Westerberg<a href="#refwesterberg" id="westerberg"><sup>[2]</sup></a>: &#8220;Our ability to enumerate requires we have a way to represent the space of alternatives. Such a representation may be the one real contribution of a Ph.D. thesis &#8212; i.e., they are not that easy to discover.&#8221;</li>
</ol>
<h4>References:</h4>
<p><a href="#knuth" id="refknuth">[1]</a>. Donald E. Knuth, The Art of Computer Programming, Volume 4 Fascicle 0, Introduction to Combinatorial Algorithms and Boolean Functions (2008), ISBN 0-321-53496-4, page 1.</p>
<p><a href="#westerberg" id="refwesterberg">[2]</a>. Arthur W. Westerberg, A retrospective on design and process synthesis. Computers and Chemical Engineering<br />
Volume 28, Issue 4, 15 April 2004, pages 447-458.</p>
<h4>Further reading:</h4>
<p>1. Edsger Dijkstra&#8217;s <a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD12xx/EWD1250.html">EWD1250</a> and <a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD12xx/EWD1255.html">EWD1255</a> are particularly relevant in the context of this post.</p>
<p>2. Donald Knuth&#8217;s TAOCP, as always. If you have never read TAOCP before, get thee to a library, go: farewell. Or, if thou wilt needs hyperlinking, <a href="http://www-cs-faculty.stanford.edu/~uno/taocp.html">hyperlink this</a>. To a library, go, and quickly too. Farewell.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[All Pair Shortest Path Using Dijkstra]]></title>
<link>http://ferdidolot.wordpress.com/?p=64</link>
<pubDate>Fri, 09 Jan 2009 04:33:54 +0000</pubDate>
<dc:creator>Ferdiansyah Dolot</dc:creator>
<guid>http://ferdidolot.wordpress.com/?p=64</guid>
<description><![CDATA[import java.util.*; public class DijkstraASP{ public static void main(String args[]){ Main m =new Ma]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>import java.util.*;</p>
<p>public class DijkstraASP{<br />
public static void main(String args[]){<br />
Main m =new Main();<br />
}<br />
}<br />
class Verteks{<br />
int no;<br />
int value;<br />
String color;<br />
Verteks(int no , int value){<br />
this.no = no;<br />
this.value = value;<br />
}<br />
Verteks(int no,String color){<br />
this.no = no;<br />
this.color = color;<br />
}<br />
public String getColor(){<br />
return color;<br />
}<br />
public void setColor(String color){<br />
this.color = color;<br />
}<br />
public int getValue(){<br />
return value;<br />
}<br />
public int getNo(){<br />
return no;<br />
}<br />
public void setValue(int a){<br />
value = a;<br />
}<br />
}<br />
class Main{<br />
public Main(){<br />
Scanner in = new Scanner(System.in);<br />
int n = 3;//jumlah verteks<br />
PriorityQueue&#60;Verteks&#62; pq = new PriorityQueue&#60;Verteks&#62;(n,new Comparator&#60;Verteks&#62;(){<br />
public int compare(Verteks a,Verteks b){<br />
if(a.getValue() &#60; b.getValue())<br />
return -1;<br />
else<br />
return 1;<br />
}<br />
});<br />
Verteks d[][] = new Verteks[n][n];<br />
int edge[][] = new int[n][n];<br />
for(int i=0 ; i&#60;n ; i++){<br />
Arrays.fill(edge[i] , 0);<br />
for(int j=0 ; j&#60;n ; j++){<br />
d[i][j]=new Verteks(j,Integer.MAX_VALUE);<br />
}<br />
}<br />
for(int i=0 ; i&#60;n ; i++){<br />
d[i][i].setValue(0);<br />
}<br />
edge[0][1] =edge[1][0]=2;<br />
edge[1][2]=edge[2][1]=1;<br />
edge[0][2]= edge[2][0]=4;<br />
int u=0;<br />
for(int i=0 ; i&#60;n ; i++){<br />
pq.add(d[i][i]);<br />
while(!pq.isEmpty()){<br />
u = pq.poll().getNo();<br />
System.out.println(&#8220;u :&#8221;+u);<br />
for(int j=0 ; j&#60;n ; j++){<br />
if(edge[i][j]!=0){<br />
if((d[i][j].getValue()) &#62; (d[i][u].getValue() + edge[u][j])){<br />
d[i][j].setValue(d[i][u].getValue()+edge[u][j]);<br />
pq.add(d[i][j]);<br />
}</p>
<p>}<br />
}<br />
}<br />
}<br />
for(int i=0 ; i&#60;n ; i++){<br />
for(int j=0 ; j&#60;n ; j++){<br />
System.out.println(d[i][j].getValue());<br />
}<br />
}<br />
}<br />
}</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Computer Science.]]></title>
<link>http://damecar.wordpress.com/2009/01/08/computer-science/</link>
<pubDate>Fri, 09 Jan 2009 03:57:16 +0000</pubDate>
<dc:creator>Antonio</dc:creator>
<guid>http://damecar.wordpress.com/2009/01/08/computer-science/</guid>
<description><![CDATA[Computer Science is no more about computers than astronomy is about telescopes. -Edsger Wybe Dijkstr]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Computer Science is no more about computers than astronomy is about telescopes.</p>
<p style="text-align:right;"><em>-Edsger</em> Wybe <em>Dijkstra</em>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Terrain-Sensitive Movement]]></title>
<link>http://panzergame.wordpress.com/2009/01/04/terrain-sensitive-movement/</link>
<pubDate>Sun, 04 Jan 2009 18:27:20 +0000</pubDate>
<dc:creator>Stefan</dc:creator>
<guid>http://panzergame.wordpress.com/2009/01/04/terrain-sensitive-movement/</guid>
<description><![CDATA[I had planned to work more on the game during the Christmas holidays, but I did not start until a fe]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I had planned to work more on the game during the Christmas holidays, but I did not start until a few days ago. But I made some clear progress these last few days.</p>
<p>The algorithm that calculates the set of hexagons a unit can reach now takes terrain into account. For instance, crossing a forested hexagon costs more movement points than passing through a hexagon representing farm land.</p>
<p>The screenshot shows the hexagons the blueish tank near the bottom-left corner can move to. The forest hexes at the top were previously reachable.</p>
<p><img class="alignnone size-full wp-image-259" title="screenshot-0901041" src="http://panzergame.wordpress.com/files/2009/01/screenshot-0901041.png" alt="screenshot-0901041" width="399" height="339" /></p>
<p>At first, I thought all I had to do was associate costs with every edge and sum them up as I traversed the graph, but after a while I realized that breadth-first search (which is what I used before) cannot be used  with weighted graphs to solve this problem (unless all edges have the same weight). So I had to throw away the old search code and implement <a href="http://en.wikipedia.org/wiki/Dijkstra's_algorithm">Dijkstra&#8217;s algorithm</a> instead. Took me longer than I expected, but now the code is cleaner and handles weighted graphs properly.</p>
<p>I also simplified the rules for how close to an enemy a unit is allowed to move without having to stop. The new rule is simply that you cannot pass through a hex that is adjacent to an enemy unit. That is all that is needed, really. Thanks Peter E. for making a comment that made me realize how pointless the (relative) complexity of the old method was!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Visual Algorithms [Graph Algorithms]]]></title>
<link>http://jaqoup.wordpress.com/2008/12/08/visual-algorithms-graph-algorithms/</link>
<pubDate>Mon, 08 Dec 2008 12:18:13 +0000</pubDate>
<dc:creator>Jaqoup</dc:creator>
<guid>http://jaqoup.wordpress.com/2008/12/08/visual-algorithms-graph-algorithms/</guid>
<description><![CDATA[here is one of the assignments i liked to be doing in Scientific Computing specifically a Mathematic]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>here is one of the assignments i liked to be doing in Scientific Computing</p>
<p>specifically a Mathematical Programming assignment</p>
<p>i could have just implemented a Console application running the algorithm and get my marks, but thats not what i need from SC Dept <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>i think it would be useful for those who want to learn one of the algorithms it runs or for those who want to see what a SC assignment looks like <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>well here is the main form </p>
<p><img class="aligncenter size-full wp-image-175" title="Visual Algorithms Main Form" src="http://jaqoup.wordpress.com/files/2008/12/visualalgorithmsmain.jpg" alt="Visual Algorithms Main Form" width="655" height="514" /></p>
<p><!--more--></p>
<p>as you can see the form is divided into two parts the settings part and the drawing panel</p>
<p>in the settings part you&#8217;ll find all the data about your Graph the Nodes, their positions and algorithm specific information as the start and end nodes of the algorithm &#8211; if it needs -</p>
<p>to draw a graph you should first add the nodes of the graph, by just writing the name of the node and press &#8220;Add Node&#8221;</p>
<p><img class="alignleft size-full wp-image-176" src="http://jaqoup.wordpress.com/files/2008/12/addnode.jpg" alt="" width="115" height="87" /></p>
<p> </p>
<p> You can enter as long name as you like but i doubt that all the name will appear on the drawn graph, (you&#8217;ll see what i mean now)</p>
<p> </p>
<p>and after you add it it will be drawn in the drawing area</p>
<p>as in the next figure i&#8217;ve added some nodes</p>
<p><img class="aligncenter size-full wp-image-177" src="http://jaqoup.wordpress.com/files/2008/12/addingnodes.jpg" alt="" width="655" height="515" /></p>
<p>note that when i added the nodes their names appeared in the upper-leftmost  list A,B,C,D and End</p>
<p>and on the drawing panel only one node is shown</p>
<p>that&#8217;s because all the nodes are drawn in that location</p>
<p>you can move the node by whatever drag-drop , select it and double click anywhere on the drawing panel and it will appear there</p>
<p>or you can select it and edit it&#8217;s X.Pos &#38; Y.Pos here</p>
<p><img class="alignnone size-full wp-image-178" src="http://jaqoup.wordpress.com/files/2008/12/editnode.jpg" alt="" width="117" height="116" /> but make sure when a node is selected it&#8217;s name is written in this textbox and it is highlighted   in the list </p>
<p>after you move the Nodes to another positions now you should set the edges between the nodes</p>
<p>in the algorithm specific part you&#8217;ll find a hyperlink &#8220;Manage Weights&#8221;</p>
<p>click it and another form containing the adjacency matrix will show up</p>
<p><img class="aligncenter size-full wp-image-179" src="http://jaqoup.wordpress.com/files/2008/12/adjacencymatrix.jpg" alt="" width="655" height="514" /></p>
<p>a &#8220;0&#8243; means no connection</p>
<p>here you can enter the weights of the edges between the  nodes</p>
<p>in some algorithms which operate on nondirected graphs where the direction won&#8217;t matter u&#8217;ll find this form makes itself symmetric whenever you enter a value</p>
<p>as when you enter the value from &#8220;A&#8221; to &#8220;B&#8221; you&#8217;ll find the same value Automatically written from &#8220;B&#8221; to &#8220;A&#8221;</p>
<p>then&#8230;</p>
<p>after you enter the whights just close the form and the graph will be drawn</p>
<p>like this </p>
<p><img class="aligncenter size-full wp-image-180" src="http://jaqoup.wordpress.com/files/2008/12/drawngraph.jpg" alt="" width="655" height="561" />note that the number written above each node is it&#8217;s weight , cost or whatever, according to the algorithm.</p>
<p>and the red number on the edges is it&#8217;s weight ( the numbers you entered in the adjacency matrix form -don&#8217;t they look familiar :D &#8211; )</p>
<p>and this is how it looks like for the algorithms that use Directed edges</p>
<p><img class="aligncenter size-full wp-image-183" src="http://jaqoup.wordpress.com/files/2008/12/directed.jpg" alt="" width="655" height="510" /></p>
<p>then what you should do now is keep clicking the &#8216;Next Step&#8221; button till the algorithm finishes</p>
<p>but first some algorithms need to have the start and end Nodes specified like Dijkstra and Max Flow</p>
<p>this is the Shortest path between &#8220;A&#8221; and &#8220;C&#8221; after some &#8220;Next Step&#8221; clicks <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><img class="aligncenter size-full wp-image-181" src="http://jaqoup.wordpress.com/files/2008/12/shortestpath.jpg" alt="" width="655" height="514" /></p>
<p>&#8220;The black Edges are the path&#8221;</p>
<p>and the number written above the &#8220;C&#8221; Node &#8211; which is not visible <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  &#8211; is the total cost to get there form &#8220;A&#8221; i guess it&#8217;ll be 31.8 or you can move the node and see it <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>you can get the program from my box and watch the other algorithms</p>
<p><img class="alignleft size-full wp-image-182" src="http://jaqoup.wordpress.com/files/2008/12/arrows.jpg" alt="" width="105" height="52" />you can move between algorithms by clicking those arrows</p>
<p> </p>
<p>you&#8217;ll find Dijkstra , Kruskal MST , Prim MST and Ford Fulkerson Max Flow algorithms implemented</p>
<p>you can also save the graph to a file and load it again anytime</p>
<p>and about that slider on the top left of the drawing panel :&#124;</p>
<p>why would anybody place a slider on a drawing panel ?!!!!!</p>
<p>of course it is a zoom control !! :&#124; , :&#124;  -sort of&#8230; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  -</p>
<p>i think i&#8217;ll write how to implement your algorithm in this project soon isA</p>
<p>ah ..</p>
<p>I Forgot&#8230;&#8230; </p>
<p>it uses framework 3.5 to run <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Happy Eid <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  , <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
