Grafer

 

Video: Dijkstra algoritmen

 

Simalation:Graf & Dijkstra

 

Grafer er den mest komplekse udgave af Linked-Data (Self-Referencing) vi har fordi alle noder/Vertex kan peje på alle. Der er ikke – som med træer – en struktur hvor vi ved at børnene ikke peger på forældrene, fordi med graf kan alle pege på alle.

For at holde styr på vejen i mellem to byer/Vertex, laver en ny klasse som så har den værdi vejen har, vi kalder denne vej for EDGE, mens noderen eller byerne kalder for VERTEX.

Nogle grafer har ikke behov for vægte i mellem Vertex, og så kan man droppe edge klassen, mens dem som har vægte har edge som er implimenteret som en klasse. Dette gør grafer mere komplekse i forhold til et træ eller Linked-List fordi nu her vi en extra klasse, hvor de andre bare linkede direkte til den anden Vertex/Node, fordi vi ikke har behov for vægte i et træ, eller Linked-List.

Nedenfor ser du en Graf med 7 Vertex/Noder. Vi kan representere den som et Matrix, men vi vælger at bruge en Linked-List tilgang.

C# koden ovenover viser hvordan vi først laver Vertex´erne (graf.addVertex(“0”)). Siden laver vi Edge´s som knytter Vertexerne sammen til en graf (graf.addEdge(“0”,”1”,2)).

 

Vi kan printe alle Vertex og dens Adjacency Vertex samt vægten, med printGraph() metoden. Og resultatet bliver som forventet en liste af forbindelser og vægte, som helst skulle passe med billedet af grafen.

 

Byg Graf og Print Graf Kode

using System;

using System.Collections.Generic;

 

namespace Graph

{

    class Program

    {

        static void Main(string[] args)

        {

            Graph graf = new Graph();

            graf.addVertex("0");

            graf.addVertex("1");

            graf.addVertex("2");

            graf.addVertex("3");

            graf.addVertex("4");

            graf.addVertex("5");

            graf.addVertex("6");

 

            graf.addEdge("0", "1", 2);

            graf.addEdge("0", "3", 1);

            graf.addEdge("1", "4", 10);

            graf.addEdge("1", "3", 3);

            graf.addEdge("2", "0", 4);

            graf.addEdge("2", "5", 5);

            graf.addEdge("3", "4", 2);

            graf.addEdge("3", "6", 4);

            graf.addEdge("3", "5", 8);

            graf.addEdge("3", "2", 2);

            graf.addEdge("4", "6", 6);

            graf.addEdge("6", "5", 1);

 

            graf.printGraph();

        }

    }

 

    class Graph

    {

        List<Vertex> grafList = new List<Vertex>();

        public void addVertex(string navn)

        {

            Vertex v = new Vertex(navn);

            grafList.Add(v);

        }

        public void addEdge(String VertexBegin, String VertexEnd, double edgeWeight)

        {

            Edge edge = new Edge();

            edge.vertex = getVertex(VertexEnd);

            edge.weight = edgeWeight;

 

            getVertex(VertexBegin).edgeList.Add(edge);

        }

        public Vertex getVertex(String navn)

        {

            Vertex gemmer = null;

            foreach (Vertex vertex in grafList)

            {

                if (vertex.navn.Equals(navn))

                {

                    gemmer = vertex;

                }

            }

            return gemmer;

        }

        public void printGraph()

        {

            foreach (Vertex v in grafList)

            {

                foreach (Edge e in v.edgeList)

                {

                    Console.WriteLine("From: " + v.navn + " To: " + e.vertex.navn + " weight: " + e.weight);

                }

            }

        }

    }

    class Vertex

    {

        public String navn;

        public List<Edge> edgeList = new List<Edge>();

        public Boolean visited = false;

        public Vertex(String n)

        {

            navn = n;

        }

    }

    class Edge

    {

        public Vertex vertex;

        public double weight;

 

    }

}

 


 

Nu kommer vi til den komplekse del af Grafer, hvor vi skal undersøge grafen udfra ét punkt. Der findes i princippet 2 måder at gøre dette på, Breadth og Depth. Den print vi brugte ovenover kikke bare i listen og printede de vertex som var direkte forbundet, eller sagt på en anden måde, der blev kun printet ét nivo fra alle punkter. Det er selvfølgelig ikke nok, hvis vi vil undersøge hvordan grafen er struktureret. Et simpelt spørgsmål kunne være: “kan man komme fra A til H”. Det kan man ikke svar på ved at bruge print metoden ovenover, fordi den som sagt kun undresøgte ét nivo, og hvis A og H ikke er direkt forbundet, kan den ikke bruges.

Det positive med Breadth og Depth er at de er totalt ens, bort set fra den Liste som de bruger. Breadt bruger en Queue, og Depth bruger en Stack. Det er interessant at egenskaben af de to Datatyper giver os de her forskellige traversals.


 

Breadth-First Traversal

 

        public void BreathFirstTraversal(String navnPaaStartVertex)

        {

            Queue<Vertex> vertexQueue = new Queue<Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            vertexQueue.Enqueue(startVertex);

            traversalOrder.Enqueue(startVertex);

            Vertex frontVertex;

            while (vertexQueue.Count > 0)

            {

                frontVertex = vertexQueue.Dequeue();

                Console.WriteLine("Front Vertex: " + frontVertex.navn);

                foreach (Edge e in frontVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        vertexQueue.Enqueue(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                    }

                }

            }

        }


Depth_First Traversal

 

        public void DepthFirstTraversal(String navnPaaStartVertex)

        {

            Stack <Vertex> vertexStack = new Stack <Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            Vertex topVertex;

            vertexStack.Push(startVertex);

            traversalOrder.Enqueue(startVertex);

 

            while (vertexStack.Count > 0)

            {

                topVertex = vertexStack.Pop();

                Console.WriteLine("Top Vertex: " + topVertex.navn);

                foreach (Edge e in topVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        vertexStack.Push(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                    }

                }

            }

        }

 

Samlet kode

 

using System;

using System.Collections.Generic;

 

namespace Graph_1

{

    class Program

    {

        static void Main(string[] args)

        {

            Graph graf = new Graph();

            graf.addVertex("0");

            graf.addVertex("1");

            graf.addVertex("2");

            graf.addVertex("3");

            graf.addVertex("4");

            graf.addVertex("5");

            graf.addVertex("6");

 

            graf.addEdge("0", "1", 2);

            graf.addEdge("0", "3", 1);

            graf.addEdge("1", "4", 10);

            graf.addEdge("1", "3", 3);

            graf.addEdge("2", "0", 4);

            graf.addEdge("2", "5", 5);

            graf.addEdge("3", "4", 2);

            graf.addEdge("3", "6", 4);

            graf.addEdge("3", "5", 8);

            graf.addEdge("3", "2", 2);

            graf.addEdge("4", "6", 6);

            graf.addEdge("6", "5", 1);

 

            Console.WriteLine("------------Print Graph---------------");

            graf.printGraph();

            Console.WriteLine("------------Breath-First Traversal----------");

            graf.BreathFirstTraversal("0");

            graf.setAllToNotVisited();

            Console.WriteLine("------------Depth-First Traversal----------");

            graf.DepthFirstTraversal("0");

        }

    }

    class Graph

    {

        List<Vertex> grafList = new List<Vertex>();

        public void addVertex(string navn)

        {

            Vertex v = new Vertex(navn);

            grafList.Add(v);

        }

 

        public void addEdge(String VertexBegin, String VertexEnd, double edgeWeight)

        {

            Edge edge = new Edge();

            edge.vertex = getVertex(VertexEnd);

            edge.weight = edgeWeight;

 

            getVertex(VertexBegin).edgeList.Add(edge);

        }

 

        public Vertex getVertex(String navn)

        {

            Vertex gemmer = null;

            foreach (Vertex vertex in grafList)

            {

                if (vertex.navn.Equals(navn))

                {

                    gemmer = vertex;

                }

            }

            return gemmer;

        }

        public void setAllToNotVisited()

        {

            foreach (Vertex v in grafList)

            {

                v.visited = false;

            }

        }

        public void printGraph()

        {

            foreach (Vertex v in grafList)

            {

                foreach (Edge e in v.edgeList)

                {

                    Console.WriteLine("From: " + v.navn + " To: " + e.vertex.navn + " weight: " + e.weight);

                }

            }

        }

        public void BreathFirstTraversal(String navnPaaStartVertex)

        {

            Queue<Vertex> vertexQueue = new Queue<Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            vertexQueue.Enqueue(startVertex);

            traversalOrder.Enqueue(startVertex);

            Vertex frontVertex;

            while (vertexQueue.Count > 0)

            {

                Console.WriteLine("Antal i Queue: " + vertexQueue.Count);

                frontVertex = vertexQueue.Dequeue();

                Console.WriteLine("  <-  Dequeue: " +frontVertex.navn + "     frontVertex");

                foreach (Edge e in frontVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        Console.WriteLine("  ->  Enqueue: " + e.vertex.navn);

                        vertexQueue.Enqueue(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                    }

                }

            }

            Console.Write(" Traversal order: ");

            foreach (Vertex v in traversalOrder)

            {

                Console.Write( v.navn + " ");

            }

            Console.WriteLine();

        }

        public void DepthFirstTraversal(String navnPaaStartVertex)

        {

            Stack <Vertex> vertexStack = new Stack <Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            Vertex topVertex;

            vertexStack.Push(startVertex);

            traversalOrder.Enqueue(startVertex);

 

            while (vertexStack.Count > 0)

            {

                Console.WriteLine( "Antal i Stack: "+vertexStack.Count );

                topVertex = vertexStack.Pop();

                Console.WriteLine("  <-  Pop from stack: " + topVertex.navn+ "    topVertex" ) ;

                foreach (Edge e in topVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        Console.WriteLine("  ->  Push to stack: " + e.vertex.navn);

                        vertexStack.Push(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                    }

                }

            }

            Console.Write(" Traversal order: ");

            foreach (Vertex v in traversalOrder)

            {

                Console.Write(  v.navn + " ");

            }

            Console.WriteLine();

        }

    }

    class Vertex

    {

        public String navn;

        public List<Edge> edgeList = new List<Edge>();

        public Boolean visited = false;

        public Vertex(String n)

        {

            navn = n;

        }

    }

    class Edge

    {

        public Vertex vertex;

        public double weight;

    }

}

 

 

 


 

Samlet Kode med Dijkstra

using System;

using System.Collections.Generic;

 

namespace Graph_3

{

    class Program

    {

        static void Main(string[] args)

        {

            Graph graf = new Graph();

            Graph graf2 = new Graph();

            graf2.addVertex("0");

            graf2.addVertex("1");

            graf2.addVertex("2");

            graf2.addVertex("3");

            graf2.addVertex("4");

            graf2.addVertex("5");

            graf2.addVertex("6");

 

            graf2.addEdge("0", "1", 2);

            graf2.addEdge("0", "3", 1);

            graf2.addEdge("1", "4", 10);

            graf2.addEdge("1", "3", 3);

            graf2.addEdge("2", "0", 4);

            graf2.addEdge("2", "5", 5);

            graf2.addEdge("3", "4", 2);

            graf2.addEdge("3", "6", 4);

            graf2.addEdge("3", "5", 8);

            graf2.addEdge("3", "2", 2);

            graf2.addEdge("4", "6", 6);

            graf2.addEdge("6", "5", 1);

            //--Extra for testing-----------

            //graf2.addVertex("7");

            //graf2.addVertex("8");

            //graf2.addEdge("4", "7", 1);

            //graf2.addEdge("7", "8", 1);

            //graf2.addEdge("1", "8", 1);

 

 

            graf.addVertex("A");

            graf.addVertex("B");

            graf.addVertex("C");

            graf.addVertex("D");

            graf.addVertex("E");

            graf.addVertex("F");

            graf.addVertex("G");

            graf.addVertex("H");

            graf.addVertex("I");

 

            graf.addEdge("A", "B", 2); //var 2

            graf.addEdge("A", "D", 5);

            graf.addEdge("A", "E", 4);

            graf.addEdge("B", "E", 1);

            graf.addEdge("D", "G", 2);

            graf.addEdge("E", "F", 3);

            graf.addEdge("E", "H", 6);

            graf.addEdge("F", "C", 4);

            graf.addEdge("F", "H", 3);

            graf.addEdge("C", "B", 3);

            graf.addEdge("H", "I", 1);

            graf.addEdge("I", "F", 1); // var 1, 

            graf.addEdge("G", "H", 1);

 

            Console.WriteLine("------------Print Graph 1.---------------");

            graf.printGraph();

            Console.WriteLine("------------Print Graph 2.---------------");

            graf2.printGraph();

            Console.WriteLine("------------Breath-First Traversal Graph 1.----------");

            graf.BreathFirstTraversal("A");

            graf.setAllToNotVisited();

            Console.WriteLine("------------Depth-First Traversal Graph 1.----------");

            graf.DepthFirstTraversal("A");

            graf.setAllToNotVisited();

            Console.WriteLine("------------is ther a connecition Graph 1.----------");

            Console.WriteLine(graf.isThereAConnection("A", "H"));

 

            graf2.setAllToNotVisited();

            graf2.findShortesPathUnweightedGraph("0");

            graf.setAllToNotVisited();

            graf.findShortesPathUnweightedGraph("H");

            Console.WriteLine("------------Dijkstra.----------");

            graf.setAllToNotVisited();

            graf.dijkstra("A", "H");

        }

    }

 

 

    class Graph

    {

        List<Vertex> grafList = new List<Vertex>();

        public void dijkstra(String navnPaaStartVertex, String navnPaaStopVertex)

        {

            Console.WriteLine();

            Console.WriteLine("--------------------- From " + navnPaaStartVertex + " to " + navnPaaStopVertex + " ----------------");

            Console.WriteLine();

 

            List<Vertex> priorityQueue = new List<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            startVertex.lengthFromStartVertex = 0;

            priorityQueue.Add(startVertex);

            Vertex frontVertex = startVertex;

 

            Boolean search = true;

            while (priorityQueue.Count > 0 && search)

            {

                //---- Prioritizing from the Queue-----

                int value = 1000000000; //Symboliserer uendelig stort tal.

                int teller = 0;

                foreach (Vertex v in priorityQueue)

                {

                    if (v.lengthFromStartVertex < value)

                    {

                        frontVertex = priorityQueue[teller];

                        value = v.lengthFromStartVertex;

                    }

                    teller++;

                }

                priorityQueue.Remove(frontVertex);

                frontVertex.visited = true;

                Console.WriteLine("  <-  Dequeue: " + frontVertex.navn + " with weight: " + frontVertex.lengthFromStartVertex +

                                  " Queue size:" + priorityQueue.Count);

                //----Prioritizing STOP-------------------------------------------

 

                //-----We have found the Vertex-------------------------------------

                if (frontVertex.navn.Equals(navnPaaStopVertex))

                {

                    Console.WriteLine("  ----------  Found: Name: " + frontVertex.navn + " Weight: " + frontVertex.lengthFromStartVertex);

                    Vertex holder = frontVertex;

                    while (!holder.navn.Equals(navnPaaStartVertex))

                    {

                        Console.WriteLine("backtracking: " + holder.navn);

                        holder = holder.previousVertex;

                    }

 

                    Console.WriteLine("backtracking: " + navnPaaStartVertex);

                    search = false;

                    break;

                }

                //--------------------------------------

 

                foreach (Edge e in frontVertex.edgeList)

                {

                    int w = (int)e.weight;

                    if (e.vertex.visited == false) //Den er ikke besøgt før.

                    {

                        //0 findes ikke i køen, så skal den indsættes i prioritetskøen.

                        //1 findes allerede i køen og er mindre, skal derfor overskrive.

                        //2 findes allerede i køen men er større, derfor ingen overskrivning.

                      

                        int tilstand = 0; //Starter med antagelse at den ikke findes i køen.

 

                        foreach (Vertex v in priorityQueue)

                        {                                 

                            if (v.navn.Equals(e.vertex.navn)) //Så findes den i Køen.

                            {

                                if (frontVertex.lengthFromStartVertex + w >= v.lengthFromStartVertex)

                                {

                                    tilstand = 2;   //2: findes allerede i køen men er større. Ikke overskrive.

                                }

                                else

                                {

                                    tilstand = 1; //1: findes allerede i køen og er mindre, derfor overskrive.

                                }

                            }

                        }

                        if (tilstand == 0) //Tilstand 0: findes ikke i Køen. Indsættes i Prioritetskøen.

                        {

                            e.vertex.lengthFromStartVertex = frontVertex.lengthFromStartVertex + w;

                            e.vertex.previousVertex = frontVertex;

                            priorityQueue.Add(e.vertex);

                            Console.WriteLine("  ->  Enqueing: " + e.vertex.navn + " Weight: " + e.vertex.lengthFromStartVertex +

                                     " Previous Vertex: " + e.vertex.previousVertex.navn + " Queue size:" + priorityQueue.Count);

                        }

                        else if (tilstand == 1) //Tilstand 1: findes i køen og er mindre. Skal OVERSKRIVE.

                        {                                               

                            Vertex v = getVertex(e.vertex.navn);

                            v.lengthFromStartVertex = frontVertex.lengthFromStartVertex + w;

                            v.previousVertex = frontVertex;

                            Console.WriteLine("  * Overskriver Vertex " + e.vertex.navn + " Weight: " + e.vertex.lengthFromStartVertex);

                        }

                        else if (tilstand == 2) //Tilstand 2: findes i køen men er større. Laver ingenting

                        {

                            Console.WriteLine("  * Findes allerede og har mindre eller samme vægt: " + e.vertex.navn);

                        }

                    }

                    else

                    {

                        Console.WriteLine("  * Besøgt Vertex før: " + e.vertex.navn);

                    }

                }

            }

        }

 

        public void findShortesPathUnweightedGraph(String navnPaaStartVertex)

        {

            Queue<Vertex> vertexQueue = new Queue<Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            startVertex.lengthFromStartVertex = 0;

            vertexQueue.Enqueue(startVertex);

            traversalOrder.Enqueue(startVertex);

            Vertex frontVertex;

 

            while (vertexQueue.Count > 0)

            {

                frontVertex = vertexQueue.Dequeue();

 

                foreach (Edge e in frontVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        e.vertex.visited = true;

                        e.vertex.lengthFromStartVertex = frontVertex.lengthFromStartVertex + 1;

                        e.vertex.previousVertex = frontVertex;

                        vertexQueue.Enqueue(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                    }

                }

            }

            Console.WriteLine("-------- Shortes Path in an Unweighted Graph-------------");

            Console.WriteLine("-------- From vertex: " + navnPaaStartVertex + " to all other rechable Vertex-------");

            foreach (Vertex v in traversalOrder)

            {

                Console.Write("Name: " + v.navn + " Distance: " + v.lengthFromStartVertex + " - ");

            }

            Console.WriteLine();

        }

 

 

        public Boolean isThereAConnection(String a, String b)

        {

            Boolean fundet = false;

            Queue<Vertex> vertexQueue = new Queue<Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(a);

            startVertex.visited = true;

            vertexQueue.Enqueue(startVertex);

            traversalOrder.Enqueue(startVertex);

            Vertex frontVertex;

            while (vertexQueue.Count > 0)

            {

                frontVertex = vertexQueue.Dequeue();

                foreach (Edge e in frontVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        vertexQueue.Enqueue(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                        if (e.vertex.navn.Equals(b))

                        {

                            fundet = true;

                        }

                    }

                }

            }

 

            return fundet;

        }

        public void addVertex(string navn)

        {

            Vertex v = new Vertex(navn);

            grafList.Add(v);

        }

 

        public void addEdge(String VertexBegin, String VertexEnd, double edgeWeight)

        {

            Edge edge = new Edge();

            edge.vertex = getVertex(VertexEnd);

            edge.weight = edgeWeight;

 

            getVertex(VertexBegin).edgeList.Add(edge);

        }

 

        public Vertex getVertex(String navn)

        {

            Vertex gemmer = null;

            foreach (Vertex vertex in grafList)

            {

                if (vertex.navn.Equals(navn))

                {

                    gemmer = vertex;

                }

            }

            return gemmer;

        }

        public void setAllToNotVisited()

        {

            foreach (Vertex v in grafList)

            {

                v.visited = false;

            }

 

        }

        public void printGraph()

        {

            foreach (Vertex v in grafList)

            {

                foreach (Edge e in v.edgeList)

                {

                    Console.WriteLine("From: " + v.navn + " To: " + e.vertex.navn + " weight: " + e.weight);

                }

            }

        }

 

        public void BreathFirstTraversal(String navnPaaStartVertex)

        {

            Queue<Vertex> vertexQueue = new Queue<Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            vertexQueue.Enqueue(startVertex);

            traversalOrder.Enqueue(startVertex);

            Vertex frontVertex;

            while (vertexQueue.Count > 0)

            {

                Console.WriteLine("Items in Queue: " + vertexQueue.Count);

                frontVertex = vertexQueue.Dequeue();

                Console.WriteLine("  <-  Dequeue: " + frontVertex.navn + "     frontVertex");

                foreach (Edge e in frontVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        Console.WriteLine("  ->  Enqueue: " + e.vertex.navn);

                        vertexQueue.Enqueue(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                    }

                }

            }

            Console.Write(" Traversal order: ");

            foreach (Vertex v in traversalOrder)

            {

                Console.Write(v.navn + " ");

            }

            Console.WriteLine();

        }

        public void DepthFirstTraversal(String navnPaaStartVertex)

        {

            Stack<Vertex> vertexStack = new Stack<Vertex>();

            Queue<Vertex> traversalOrder = new Queue<Vertex>();

            Vertex startVertex = getVertex(navnPaaStartVertex);

            startVertex.visited = true;

            Vertex topVertex;

            vertexStack.Push(startVertex);

            traversalOrder.Enqueue(startVertex);

 

            while (vertexStack.Count > 0)

            {

                Console.WriteLine("Items in Stack: " + vertexStack.Count);

                topVertex = vertexStack.Pop();

                Console.WriteLine("  <-  Pop from stack: " + topVertex.navn + "    topVertex");

                foreach (Edge e in topVertex.edgeList)

                {

                    if (e.vertex.visited == false)

                    {

                        Console.WriteLine("  ->  Push to stack: " + e.vertex.navn);

                        vertexStack.Push(e.vertex);

                        traversalOrder.Enqueue(e.vertex);

                        e.vertex.visited = true;

                    }

                }

            }

 

            Console.Write(" Traversal order: ");

            foreach (Vertex v in traversalOrder)

            {

                Console.Write(v.navn + " ");

            }

            Console.WriteLine();

 

        }

    }

    class Vertex

    {

        public String navn;

        public List<Edge> edgeList = new List<Edge>();

        public Boolean visited = false;

        public int lengthFromStartVertex = 0;

        public Vertex previousVertex = null;

        public Vertex(String n)

        {

            navn = n;

        }

    }

    class Edge

    {

        public Vertex vertex;

        public double weight;

    }

}

Output

 

Dijkstra2af2.png

 

 

Dijkstra1af2.png

 

 

 

 

Fagudtryk(Grafer)

Graph

https://lh4.googleusercontent.com/EBArhxK2gU-UYvetV3xoiDL-hVwVfJek39go02VAW4FEQy-Zh6ylVtd2lA_N5kzK1XYSDVAQlHMZlGngN5t0bmCCDNx7W0UcDc5ECLZCgHGuhpIoKuc*
As shown on the image above the graph is a “more complex” data structure than the ordinary tree. Thus a graph supports cycles, while the tree doesn’t. In the other hand the nodes of a tree are defined by their parents and children, while in a graph that isn’t true.

In this case each graph is defined by its edges and its vertices. In most of the cases, in order to model and solve our problem, we can assume that the vertices are consecutive numbers starting from (1, or 0 in case of 0 based arrays, as we will see later).

As we see each tree is a graph, but not every graph is a tree.

Vertex

I en graf kalder man noden for Vertex.

Edge

I en graf kalder man fobindelsen i mellem to Vertex for Edge.

Path

Vejen fra en Vertex til en aden Vertex.

Directed Graph

&

Undirected Graph

https://lh4.googleusercontent.com/ir26Y52W14NgyqIY0PoG9MYqmLuQeP9ap727Tt-tcvG00v8fSJZV6MnpUqlbeeidFrUDhjkRPYJoTwlsZOFXJkMZ3fr_XvXMh8bpUYD9Po0pDylnzSA*

Graf som har edges som har en direction (tegnes med pil)

Weighted Graph

https://lh6.googleusercontent.com/e90gKIoYLtQUlaI6inmVwPNeLz57nCDAA0Uk2xn_zrS6CLZgneXqZs_ecSjjv-OYIf9952zV55tvLkdf-sA7uE0FZHA0BaLIowxcp2we3rXDgMJJ5Po*

Connected Graph

https://lh4.googleusercontent.com/clNNmxQn0DzFzP9prrVim74lDALrM9UYimOY5mPRhQ7EyaqzYq0g2g9VJq0dYSczTe0J98FebZmNjMMy0ELJzvWbuHmL2uwRiFft4ebfjaZLeGXAG3w*

Undriected Graph & Adjecency Matrix

https://lh3.googleusercontent.com/NnV56-_JD2A8LoBmjwj2BEmADXo76U8FN0BQX4PqODwEKWt0JiqztDR4sVqKw0ur89Iwf_zIuSUhlISFCBkvtJhbAPXA1-wvvfxlMXDz2ko0yHDN_y0*

Directed Graph & Adjacency Matrix

https://lh5.googleusercontent.com/9umEfj4gKYCtWAee_oeEJJKSxvpBbhcshnJhYjyiNLWiwaRn5CEGgXmjX0iw0xVLZPpbzxu3S5SBWY5HEig56ZKvWfCZxvbUrpaUH3InlOeSK9Ze3fg*

Weighted Directed Graph & Adjacency Matrix

https://lh5.googleusercontent.com/KurjV8TDbTxFjT-InXCemlCn_F6g_nPOQLJi-8wv_c2NfMT2SmTIr6YTFNvdVImFGSWcwaNgcwvMpi32RCHTf6RADfgvhmRPJkYhR60h_xk_7Vxq5x8*

Directed Graph & Adjacency List


Den vi bruger, dog har vi også vægte på. Så det bliver til en: Weighted Directed Adjacency List

https://lh3.googleusercontent.com/KLFMioeZD4ob-QjTgiIIZKb_wRd903uZuN1eMHZU9qA6wyZ0Q4cWyjXSukHrJZo3GGcgvO9SN1EglGaYWlPzE-Yh0WRVaGKHP_Mb6vEcQ6vyjqZNmmk*

Undirecte Graph

 

Connected

Complete

Disconnected

https://lh5.googleusercontent.com/64Swd_tFP65BNwvfNZ4-xX8ph1xzujozCNMu4FEIkV-5p5NWnS7a6V7_XlRrQ8L2DkwPZK7lCFkBwQK6-6RD49R-mOltJJ4mWJcf-p341gIPOB1b1OI*

Adjacent Vertices

Vertex B is adjacent to A, but A is not adjacent to B.https://lh6.googleusercontent.com/RJRZCc0ieoL5g9pHOYTXJE5EzXjOOpVhs6d1prNYluGObLccgoIRKXkoq-kIALzh9ayEaXJcPdlzQLWH2Fl2Sej-9gurqILUGqTp0zkNidJCiCjS7jM

Two vertices are adjacent in an undirected graph if they are joined by an edge
Sometimes adjacent vertices are called neighbors

Breadth-First Traversal

https://lh6.googleusercontent.com/bzkq5PquW1xp7bdqZc-MHqn2es_5omcezMD0r8pO0eGheIMIf8a9bA0wqtd640fCWxGe9YhdW6EvU22nwT0DduwIt6NO0zXDY-eBDQu9pzcTdwbu4EE

https://lh5.googleusercontent.com/2P_3RCd1d-fWoCvG5s7fE95Z9Q47RJyjbqWs0_WoDlryNjMbjzwmr9sZIpnYma387gftCNunIggIuKM_PnT0gZ_D3N8AKVdVOZFWTurtADWGemDJQyY*







Depth-First Traversal

https://lh4.googleusercontent.com/oPDMqzEREYvj1KxfH67-6DXjbCghN7toIhxFDpooSfVvXPg51Ch-tZl1AMO_2Gjr_urAaGtINzaDEiHfWyKt54KCgugbkqz_gjMWPMWdZ5BKVyXbaEY

https://lh6.googleusercontent.com/mrthFnnfykx7FJxQlkUwN9ioj2J1JnFrZzIQ6nZZO-_dT9Flu7rz-zpAOxoSb_cvMLHd98YTMdAlUvtbWebjz4hmfMPc693sZMSwl7JfLVGlAz4gsg8

 

 

Shortest Path in an Unweighted Graph

https://lh6.googleusercontent.com/91urahyfBdYiHUmC_zXn3QtTzDFGrHI6BvYu5O-gg49WE5hYVQuXqa0wbhXe_0cHtem85kg4P648LHAxeyAxsIjCIHN-KsnYbS0DqdooYqK6dSxy7ig*
(a) The graph after the shortest-path algorithm has traversed from vertex A to vertex H; (b) the data in the vertexhttps://lh5.googleusercontent.com/LoVkVVLvNG6o6_NtEaDfHfqX61PY7h0XEQLH9sv27z1LgKiaDhQyqZRaSoxIjTpP-l_uaEfpO9DcSnklS41WWqG4zuN3F0GDSYpPEs71aV0hSdFRQ_Y

 

 

 

 

Shortest Path in an Weighted Graph




Dijkstra´s algorithm

https://lh5.googleusercontent.com/0d6t7i98AVzN5pkWFzX7SjOS2rej2BEjoQHmbUisGPku2Z0lAM9NGWItHKwRoLbqrfdEd0NSkbM1kodlwDa9nXxvn9y09flXBlx4_xNDsgk6WFTc4hg*
(a) A weighted graph and
(b) the possible paths from vertex A to vertex H.https://lh4.googleusercontent.com/2SYLh322V7UYYld3oytbk0-19A7B_ekd0PL8IaHkRqCFb4otAJXQInJoBAz5pi7p_llS7yYsIuirmi81EMahSwHRb4BWiCMMIDEvw8j_-5MBq4q4V1I

 

Fagudtryk(Stack/Queue)

Stack

https://lh4.googleusercontent.com/-38egnKg1jMQVAdMVU6Fr9X-g4--H_LFQSa9aaGOsDkTBkgVhVAXQK4ZqxYtSYl91uZLdSc5zZ3nFIBKBJYqq7Lafz0NQlvSBaYx8MwtHUzxhceS60Y*
Er en speciel udgave af Linked-List, med filosofien Last-in, first-out (LIFO). Med metoderne push og pop. Data er gemt liniert.

Queue

https://lh4.googleusercontent.com/VJ98zZ-zxPOXylbH28BTVJdIwCpmC3N47mCGs_EWbfbLKHkE8iEJe4dax88s4aBi09n1ftCvYEVGB4-ctRwveHLQ_WYNci5cDZrAptXJdPDPZVnV668*
Ligner stack, men har en first-in, first-out (FIFO) filosofi. Metoderne kaldes enqueue og dequeue. Data er gemt liniert

 

Fagudtryk(Prioritetskøer)

Priority queue

Ligner stack og queue, men med den forskel at elementerne kan prioriteres.

Krav: Elementerne skal kunne prioriters.
Krav: Elementerne aflevers med det højeste prioritet først.

Mulighed: Returnere det laveste prioriterede først.

Simpel implimentering af Priority queue

Gemme i en u-sortret liste. Når et element ønskes, laves en søgning efter det højeste element.

Normal Implimentering af Priority queue

Når elementer kommer ind bliver de placeret således at de er sorteret. Ofte bruges en Heap, men er sorted Linke-List er også en mulighed. Fidusen er at elementere er sorteret efter deres prioriterig, så at det kun koster O(1) at hente elementer.

insert(Item i)

Metoden som bruges til at indsætte elementer i PQ.

max() eller getMax()

Metode til at hente det element med højeste priorited fra PQ og fjerne det fra køen.