Ejemplo 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);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Critical path analysis algorithm
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static IDigraph CriticalPathAnalysis(IDigraph g)
        {
            //TODO: more info here
            int i = g.NumberOfVertices;

            int[] nums1 = new int[(uint)i];
            nums1[0] = 0;
            g.TopologicalOrderTraversal(new EarliestTimeVisitor(nums1));
            int[] nums2 = new int[(uint)i];
            nums2[i - 1] = nums1[i - 1];
            g.DepthFirstTraversal(new PostOrder(new LatestTimeVisitor(nums2)), 0);
            IDigraph digraph1 = new DigraphAsLists(i);

            for (int j = 0; j < i; j++)
            {
                digraph1.AddVertex(j);
            }
            IEnumerator iEnumerator = g.Edges.GetEnumerator();

            try
            {
                while (iEnumerator.MoveNext())
                {
                    IEdge edge = (IEdge)iEnumerator.Current;
                    int   k    = nums2[edge.V1.Number] - nums1[edge.V0.Number] - (int)edge.Weight;
                    digraph1.AddConnection(edge.V0.Number, edge.V1.Number, (int)edge.Weight);
                }
            }
            finally
            {
                IDisposable iDisposable = iEnumerator as IDisposable;
                if (iDisposable != null)
                {
                    iDisposable.Dispose();
                }
            }
            return(DijkstrasAlgorithm(digraph1, 0));
        }