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("--------"); } }
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); }