コード例 #1
0
 private static void Rec(List <StateInfo> As, List <StateInfo> Bs, BidirectionalDictionary <StateInfo, StateInfo> Correspondences)
 {
     if (As.Count > 0)
     {
         var a = As[0];
         var b = a.GetFirst(Bs);
         if (b != null)
         {
             //Console.WriteLine("{0} - {1}", a, b);
             Correspondences.AddAssociation(a, b);
             Rec(new List <StateInfo>(As.Skip(1)), new List <StateInfo>(Bs.Where(s => s.State != b.State)), Correspondences);
             a.Rejected.Add(b.State);
             Correspondences.RemoveAssociationFirst(a);
             foreach (var aa in As.Skip(1))
             {
                 aa.Rejected.Clear();
             }
             Rec(As, Bs, Correspondences);
         }
     }
     else
     {
         Console.WriteLine("--------");
         foreach (var pair in Correspondences)
         {
             Console.WriteLine("{0} - {1}", pair.Key.State, pair.Value.State);
         }
         Console.WriteLine("--------");
     }
 }
コード例 #2
0
        public IsomorphicInfo IsIsomorphic(FiniteStateMachine <TInput, TOutput> other)
        {
            BidirectionalDictionary <FSMState <TInput, TOutput>, FSMState <TInput, TOutput> > statesCorrespondence = new BidirectionalDictionary <FSMState <TInput, TOutput>, FSMState <TInput, TOutput> >();
            BidirectionalDictionary <TInput, TInput>   inputCorrespondence  = new BidirectionalDictionary <TInput, TInput>();
            BidirectionalDictionary <TOutput, TOutput> outputCorrespondence = new BidirectionalDictionary <TOutput, TOutput>();

            // У изоморфных автоматов должно совпадать:
            //      - число состояний
            //      - величина входного алфавита
            //      - величина выходного автомата
            bool resultFlag = this.stateSet.Count == other.stateSet.Count &&
                              this.inputSet.Count == other.inputSet.Count &&
                              this.outputSet.Count == other.outputSet.Count;

            IsomorphicInfo result = null;

            if (resultFlag)
            {
                EventableDictionary <FSMState <TInput, TOutput>, StateInfo> ThisStatistics =
                    new EventableDictionary <FSMState <TInput, TOutput>, StateInfo>(stateSet.Count);
                EventableDictionary <FSMState <TInput, TOutput>, StateInfo> OtherStatistics =
                    new EventableDictionary <FSMState <TInput, TOutput>, StateInfo>(other.stateSet.Count);

                CalcStats(stateSet, ThisStatistics);
                CalcStats(other.stateSet, OtherStatistics);

                foreach (var statState in ThisStatistics)
                {
                    foreach (var statOtherState in OtherStatistics)
                    {
                        if (statState.Value.InputCount == statOtherState.Value.InputCount &&
                            statState.Value.LoopCount == statOtherState.Value.LoopCount &&
                            statState.Value.OutputCount == statOtherState.Value.OutputCount)
                        {
                            statState.Value.Potential.Add(statOtherState.Key);
                            statOtherState.Value.Potential.Add(statState.Key);
                        }
                    }
                    if (statState.Value.Potential.Count == 0)
                    {
                        // Если у какого-нибудь состояния нет потенциальных вариантов на замену, то наша затея - фигня.
                        resultFlag = false;
                        break;
                    }
                }

                if (resultFlag)
                {
                    result = new IsomorphicInfo();

                    // Запихиваем в соответствия те пары состояний, про которые уже всё понятно
                    foreach (var statItem in ThisStatistics)
                    {
                        if (statItem.Value.Potential.Count == 1)
                        {
                            if (!statesCorrespondence.ExistsFirst(statItem.Key) &&
                                !statesCorrespondence.ExistsSecond(statItem.Value.Potential[0]))
                            {
                                statesCorrespondence.AddAssociation(statItem.Key, statItem.Value.Potential[0]);
                            }
                            else
                            {
                                result = null;
                                break;
                            }
                        }
                    }

                    if (result != null)
                    {
                        result.As.AddRange(
                            stateSet.Select(
                                s => ThisStatistics.Where(ss => ss.Key.StateCore == s.StateCore).First().Value));
                        result.Bs.AddRange(
                            other.stateSet.Select(
                                s => OtherStatistics.Where(ss => ss.Key.StateCore == s.StateCore).First().Value));
                        result.Zs.AddRange(inputSet.Select(i => new InputInfo(i)));
                        result.Xs.AddRange(other.inputSet.Select(i => new InputInfo(i)));

                        if (!RecursiveInput(
                                new List <InputInfo>(inputSet.Select(i => new InputInfo(i))),
                                new List <InputInfo>(other.inputSet.Select(i => new InputInfo(i))),
                                result))
                        {
                            result = null;
                        }
                    }
                }
            }
            return(result);
        }