예제 #1
0
        /// <summary>
        /// find and return the maximum cyclic throughput cost
        /// </summary>
        /// <param name="sort">topological sorted enumerable of vertices</param>
        /// <param name="graph">a delay graph</param>
        /// <param name="registered">a hash set containing registered vertices</param>
        /// <returns>a value representing maximum throughput cost of all cycles</returns>
        internal static long FindMaxThroughputCostCore(IEnumerable <DelayGraphVertex> sort, DelayGraph graph, HashSet <DelayGraphVertex> registered)
        {
            long maxCycleCost = 0;
            var  table        = new WaveFrontDictionary <Dictionary <DelayGraphVertex, long> >();

            foreach (var v in sort)
            {
                var  inEdges          = graph.GetForwardInEdges(v);
                var  outEdges         = graph.GetForwardOutEdges(v);
                var  feedbackInEdges  = graph.GetFeedbackInEdges(v);
                var  feedbackOutEdges = graph.GetFeedbackOutEdges(v);
                int  myRefCount       = outEdges.Count();
                long cost             = GetThroughputCost(v, registered);

                Dictionary <DelayGraphVertex, long> myData = null;
                // first, consume predecessor's wavefront data, if any
                foreach (var e in inEdges)
                {
                    var p    = e.Source;
                    var data = table.Use(p);
                    if (data == null)
                    {
                        continue;
                    }
                    // copy data into myData
                    myData = GetOrMakeMyData(table, v, myRefCount, myData);

                    UpdateMaxData(myData, data);
                }

                if (cost > 0 && myData != null)
                {
                    // incr all costs in myData by cost
                    foreach (var p in myData.Keys.ToList())
                    {
                        myData[p] += cost;
                    }
                }

                if (feedbackInEdges.Any())
                {
                    // v is start of cycle - enter v into myData
                    myData    = GetOrMakeMyData(table, v, myRefCount, myData);
                    myData[v] = cost;
                }

                if (myData == null)
                {
                    continue;
                }

                // update max cycle cost
                foreach (var e in feedbackOutEdges)
                {
                    var  p = e.Target;
                    long cycleCost;
                    if (myData.TryGetValue(p, out cycleCost) &&
                        cycleCost > maxCycleCost)
                    {
                        maxCycleCost = cycleCost;
                    }
                }
            }

            return(maxCycleCost);
        }