示例#1
0
        /// <summary>
        /// Get the maximim walking distance from any index of the given <see cref="ITransition"/> to
        /// its corresonding strongly connected group.
        /// </summary>
        /// <returns>The maximum walking distance from any index to a strongly connected group.</returns>
        /// <param name="transition">The given <see cref="ITransition"/> for which this distance is calculated.</param>
        /// <seealso cref="M:GetStronlyConnectedPeriod"/>
        public static int GetStronlyConnectedPeriod(this ITransition transition)
        {
            int n = transition.Length;
            CompactBitVector glb = CompactBitVector.All(n);
            CompactBitVector cur = CompactBitVector.All(n);
            int         low = 0x00, idx, rem, siz, period = 0x01;
            Stack <int> stack = new Stack <int> ();

            do
            {
                idx = low;
                do
                {
                    cur.Remove(idx);
                    stack.Push(idx);
                    idx = transition.GetTransitionOfIndex(idx);
                } while(cur.Contains(idx) && glb.Contains(idx));
                if (glb.Contains(idx))                   //we've found a new group
                {
                    siz = 0x00;
                    do
                    {
                        rem = stack.Pop();
                        siz++;
                    } while(rem != idx);
                    period = MathUtils.LeastCommonMultiple(period, siz);
                }
                stack.Clear();
                glb.AndLocal(cur);
                low = glb.GetLowest(low + 0x01);
            } while(low > 0x00);
            return(period);
        }
示例#2
0
        /// <summary>
        /// Calculate for each index of the transition the distance towards its strongly connected group and the
        /// tour size of that group.
        /// </summary>
        /// <returns>A <see cref="T:Tuple`2"/> containing two arrays. The first array contains the distance
        /// to a strongly connected group for the index of the transition. The second index contains
        /// the tour size the strongly connected group of the index of the transition.</returns>
        /// <param name="transition">The transition to calculate these values for.</param>
        /// <param name="distances">An array containing the distances to the corresponding strongly connected groups.</param>
        /// <param name="tourLengths">An array containing the tour lengths of the corresponding strongly connected groups.</param>
        /// <param name="initialTours">An array containing the first index of the strongly connected group.</param>
        public static void GetStronglyConnectedGroupsDistanceTour(this ITransition transition, out int[] distances, out int[] tourLengths, out int[] initialTours)
        {
            int n = transition.Length;
            CompactBitVector glb = CompactBitVector.All(n);
            CompactBitVector cur = CompactBitVector.All(n);

            distances    = new int[n];
            tourLengths  = new int[n];
            initialTours = new int[n];
            int         low = 0x00, idx, ini, rem, dist, tour;
            Stack <int> stack = new Stack <int> ();
            Stack <int> ttack = new Stack <int> ();

            do
            {
                idx = low;
                do
                {
                    cur.Remove(idx);
                    stack.Push(idx);
                    idx = transition.GetTransitionOfIndex(idx);
                } while(cur.Contains(idx) && glb.Contains(idx));
                if (glb.Contains(idx))                   //we've found a new group
                {
                    tour = 0x00;
                    ini  = idx;
                    do
                    {
                        tour++;
                        rem                = stack.Pop();
                        distances [rem]    = 0x00;
                        initialTours [rem] = rem;
                        ttack.Push(rem);
                    } while(rem != idx);
                    while (ttack.Count > 0x00)
                    {
                        tourLengths [ttack.Pop()] = tour;
                    }
                    dist = 0x00;
                }
                else
                {
                    dist = distances [idx];
                    tour = tourLengths [idx];
                    ini  = initialTours [idx];
                }
                while (stack.Count > 0x00)
                {
                    rem                = stack.Pop();
                    distances [rem]    = ++dist;
                    tourLengths [rem]  = tour;
                    initialTours [rem] = ini;
                }
                glb.AndLocal(cur);
                low = glb.GetLowest(low + 0x01);
            } while(low > 0x00);
        }
示例#3
0
        /// <summary>
        /// Get the maximim walking distance from any index of the given <see cref="ITransition"/> to
        /// its corresonding strongly connected group.
        /// </summary>
        /// <returns>The maximum walking distance from any index to a strongly connected group.</returns>
        /// <param name="transition">The given <see cref="ITransition"/> for which this distance is calculated.</param>
        /// <seealso cref="M:GetStronlyConnectedPeriod"/>
        public static int GetMaximumStronglyConnectedGroupsDistance(this ITransition transition)
        {
            int n = transition.Length;
            CompactBitVector glb = CompactBitVector.All(n);
            CompactBitVector cur = CompactBitVector.All(n);

            int[]       dists = new int[n];      //TODO replace with numbervector?
            int         low = 0x00, idx, rem, dist, maxdist = 0x00;
            Stack <int> stack = new Stack <int> ();

            do
            {
                idx = low;
                do
                {
                    cur.Remove(idx);
                    stack.Push(idx);
                    idx = transition.GetTransitionOfIndex(idx);
                } while(cur.Contains(idx) && glb.Contains(idx));
                if (glb.Contains(idx))                   //we've found a new group
                {
                    do
                    {
                        rem         = stack.Pop();
                        dists [rem] = 0x00;
                    } while(rem != idx);
                    dist = 0x00;
                }
                else
                {
                    dist = dists [idx];
                }
                while (stack.Count > 0x00)
                {
                    dists [stack.Pop()] = ++dist;
                }
                maxdist = Math.Max(maxdist, dist);
                glb.AndLocal(cur);
                low = glb.GetLowest(low + 0x01);
            } while(low > 0x00);
            return(maxdist);
        }
示例#4
0
        /// <summary>
        /// Enumerate the sets of strongly connected groups: indices that form a cycle.
        /// </summary>
        /// <returns>A <see cref="T:IEnumerable`1"/> that contains the indices of strongly connected groups.</returns>
        /// <remarks>
        /// <para>The strongly connected groups are generated lazily: on demand the next group is generated.</para>
        /// <para>There is no guarantee on the order of the generated groups, nor on the first element of
        /// every group.</para>
        /// <para>Singleton groups are generated as well: indices that have a transition to themselves.</para>
        /// <para>The algorithm is a special case of Tarjans algorithm especially optimized for the transition
        /// functions.</para>
        /// </remarks>
        public static IEnumerable <IEnumerable <int> > GetStronglyConnectedGroups(this ITransition transition)
        {
            int n = transition.Length;
            CompactBitVector glb = CompactBitVector.All(n);
            CompactBitVector cur = CompactBitVector.All(n);
            int         low = 0x00, idx, rem;
            Queue <int> pushQueue = new Queue <int> ();

            do
            {
                idx = low;
                do
                {
                    cur.Remove(idx);
                    pushQueue.Enqueue(idx);
                    idx = transition.GetTransitionOfIndex(idx);
                } while(cur.Contains(idx) && glb.Contains(idx));
                if (glb.Contains(idx))                   //we've found a new group
                {
                    pushQueue.Enqueue(idx);
                    do
                    {
                        rem = pushQueue.Dequeue();
                    } while(rem != idx);
                    yield return(pushQueue);

                    pushQueue = new Queue <int> ();
                }
                else
                {
                    pushQueue.Clear();
                }
                glb.AndLocal(cur);
                low = glb.GetLowest(low + 0x01);
            } while(low > 0x00);
        }