public List<Edge<int>> mfas(BidirectionalGraph<int, Edge<int>> G) { List<Edge<int>> F = new List<Edge<int>>(); IDictionary<int, int> P = new Dictionary<int, int>(); int sccCount = G.StronglyConnectedComponents(out P); if (sccCount == 0) { return F; } if (sccCount == 1) { Tuple<List<int>, List<int>> T = bisect(G); F = mfas(subGraph(T.Item1, G)); F.AddRange(mfas(subGraph(T.Item2, G))); F.AddRange(fromV2toV1(T, G)); } else { var scc = new HashSet<int>(P.Values); foreach (int k in scc) { List<int> S = P.Select(x => x).Where(x => x.Value == k).Select(x => x.Key).ToList<int>(); F.AddRange(mfas(subGraph(S, G))); } } return F; }
public static StronglyConntectedComponents <T> Sccs <T>(this BidirectionalGraph <T, Edge <T> > graph) { IDictionary <T, int> sccNumbering; graph.StronglyConnectedComponents(out sccNumbering); return(new StronglyConntectedComponents <T>(sccNumbering, sccNumbering.TurnAround())); }
/// <summary> /// Adds a new coercion rule. Trys to avoid cyclic implicit casts chains. /// </summary> /// <typeparam name="TOriginalType"></typeparam> /// <typeparam name="TCastingType"></typeparam> /// <param name="kind"></param> /// <param name="cast"></param> public void AddCoercionRule <TOriginalType, TCastingType>(CoercionKind kind, Func <TOriginalType, TCastingType> cast) { var original = typeof(TOriginalType); var casting = typeof(TCastingType); if (GetTypeByNative(original) == null) { throw new UnknownTypeException(original); } if (GetTypeByNative(casting) == null) { throw new UnknownTypeException(casting); } var rule = new CoercionRule(kind, original, casting, a => cast((TOriginalType)a)); if (allCoercionRules.TryGetEdge(original, casting, out TaggedEdge <Type, CoercionRule> existingEdge)) { throw new InvalidOperationException("Such a rule does already exist!"); } var edge = new TaggedEdge <System.Type, CoercionRule>(original, casting, rule); if (kind == CoercionKind.Implicit) { implicitCoercionRules.AddVertex(original); implicitCoercionRules.AddVertex(casting); implicitCoercionRules.AddEdge(edge); if (implicitCoercionRules.StronglyConnectedComponents(out IDictionary <Type, int> components) != implicitCoercionRules.Vertices.Count()) { implicitCoercionRules.RemoveEdge(edge); throw new InvalidOperationException("This action would create an implicit conversion cycle!"); } } allCoercionRules.AddVertex(original); allCoercionRules.AddVertex(casting); allCoercionRules.AddEdge(edge); Debug.WriteLine($"- added coercion rule from '{original.Name}' to '{casting.Name}'"); }