Esempio n. 1
0
        /// <summary>
        /// Thanks to Morton Mertner for a fix here
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        public static IDigraph DijkstrasAlgorithm(IDigraph g, int s)
        {
            int n = g.NumberOfVertices;

            Entry[] table = new Entry[n];
            for (int v = 0; v < n; ++v)
            {
                table[v] = new Entry(false,
                                     int.MaxValue, int.MaxValue);
            }
            table[s].distance = 0;
            IPriorityQueue queue = new BinaryHeap(g.NumberOfEdges);

            queue.Enqueue(new Association(0, g.GetVertex(s)));
            int vertexCount = 0;             // MM fix

            while (!queue.IsEmpty)
            {
                Association assoc = (Association)queue.DequeueMin();
                IVertex     v0    = (IVertex)assoc.Value;
                if (!table[v0.Number].known)
                {
                    table[v0.Number].known = true;
                    vertexCount++;                     // MM fix
                    foreach (IEdge e in v0.EmanatingEdges)
                    {
                        IVertex v1 = e.MateOf(v0);
                        int     d  = table[v0.Number].distance + (e.Weight != null ? (int)e.Weight : 0);
                        if (table[v1.Number].distance > d)
                        {
                            table[v1.Number].distance    = d;
                            table[v1.Number].predecessor = v0.Number;
                            queue.Enqueue(new Association(d, v1));
                        }
                    }
                }
            }
            // MM fixed loop to filter out unused edges and vertices
            IDigraph result = new DigraphAsLists(vertexCount);
            int      cv     = 0;

            int[] v2cv = new int[n];
            for (int v = 0; v < n; ++v)
            {
                if (table[v].known)
                {
                    result.AddVertex(cv, table[v].distance);
                    v2cv[v] = cv++;
                }
            }
            for (int v = 0; v < n; ++v)
            {
                if (v != s && table[v].known && table[v].distance < int.MaxValue)
                {
                    result.AddConnection(v2cv[v], v2cv[table[v].predecessor]);
                }
            }
            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Kruskal's algorithm is an algorithm that finds a minimum spanning tree for a connected weighted graph.
        /// This means it finds a subset of the edges that forms a tree that includes every vertex,
        /// where the total weight of all the edges in the tree is minimized.
        /// If the graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for each connected component).
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static IGraph KruskalsAlgorithm(IGraph g)
        {
            Console.WriteLine("Starting...");
            int    i1     = g.NumberOfVertices;
            IGraph graph1 = new GraphAsLists(i1);

            for (int j1 = 0; j1 < i1; j1++)
            {
                graph1.AddVertex(j1);
            }
            IPriorityQueue priorityQueue = new BinaryHeap(g.NumberOfEdges);
            IEnumerator    iEnumerator   = g.Edges.GetEnumerator();

            Console.WriteLine("got the edge enumerator...");
            try
            {
                while (iEnumerator.MoveNext())
                {
                    IEdge edge1 = (IEdge)iEnumerator.Current;
                    int   k;
                    //the casting depends on the datatype of the weight, here you are on your own
                    //we'll assume that an int will do as an example
                    if (edge1.Weight == null)
                    {
                        k = 0;
                    }
                    else
                    {
                        try
                        {
                            k = (int)edge1.Weight;
                        }
                        catch
                        {
                            k = 0;
                        }
                    }

                    priorityQueue.Enqueue(new Association(k, edge1));
                }
            }
            finally
            {
                IDisposable iDisposable = iEnumerator as IDisposable;
                if (iDisposable != null)
                {
                    iDisposable.Dispose();
                }
            }
            Console.WriteLine("after the edge enumerator...");
            Console.WriteLine(priorityQueue.ToString());
            IPartition partition = new PartitionAsForest(i1);

            Console.WriteLine("The partition: " + partition.Count);
            while (!priorityQueue.IsEmpty && (partition.Count > 1))
            {
                IEdge edge2 = (IEdge)((Association)priorityQueue.DequeueMin()).Value;
                Console.WriteLine(edge2.ToString());
                int i2 = edge2.V0.Number;
                int j2 = edge2.V1.Number;
                Console.WriteLine("got vertices (" + i2 + "," + j2 + ")");
                ISet set1 = partition.Find(i2);
                ISet set2 = partition.Find(j2);

                if (set1 != set2)
                {
                    partition.Join(set1, set2);
                    graph1.AddConnection(i2, j2);
                }
            }
            return(graph1);
        }
Esempio n. 3
0
        /// <summary>
        /// Computes a spanning tree
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        public static IGraph PrimsAlgorithm(IGraph g, int s)
        {
            int i1 = g.NumberOfVertices;

            Entry[] entrys = new Entry[i1];
            for (int j1 = 0; j1 < i1; j1++)
            {
                entrys[j1] = new Entry(false, int.MaxValue, int.MaxValue);
            }
            entrys[s].distance = 0;
            IPriorityQueue priorityQueue = new BinaryHeap(g.NumberOfEdges);

            priorityQueue.Enqueue(new Association(0, g.GetVertex(s)));


            while (!priorityQueue.IsEmpty)
            {
                IVertex vertex1 = (IVertex)((Association)priorityQueue.DequeueMin()).Value;
                if (entrys[vertex1.Number].known)
                {
                    continue;
                }
                entrys[vertex1.Number].known = true;

                IEnumerator iEnumerator = vertex1.EmanatingEdges.GetEnumerator();
                try
                {
                    while (iEnumerator.MoveNext())
                    {
                        IEdge   edge    = (IEdge)iEnumerator.Current;
                        IVertex vertex2 = edge.MateOf(vertex1);

                        int k = (edge.Weight == null? 0 :(int)edge.Weight);
                        if (!entrys[vertex2.Number].known && entrys[vertex2.Number].distance > k)
                        {
                            entrys[vertex2.Number].distance    = k;
                            entrys[vertex2.Number].predecessor = vertex1.Number;
                            priorityQueue.Enqueue(new Association(k, vertex2));
                        }
                    }
                }
                finally
                {
                    IDisposable iDisposable = iEnumerator as IDisposable;
                    if (iDisposable != null)
                    {
                        iDisposable.Dispose();
                    }
                }
            }

            IGraph graph1 = new GraphAsLists(i1);

            for (int i2 = 0; i2 < i1; i2++)
            {
                graph1.AddVertex(i2);
            }
            for (int j2 = 0; j2 < i1; j2++)
            {
                if (j2 != s)
                {
                    graph1.AddConnection(j2, entrys[j2].predecessor);
                }
            }
            return(graph1);
        }