public void DirectedGraphAllowsDuplicateEdgesTest() { var graph = new DirectedGraph<int>(new[] { 1, 2 }); graph.AddEdge(1, 2); graph.AddEdge(1, 2); graph.FindCycle().Should().BeEmpty("Expected no cycle vertices to be found"); }
public void DirectedGraphFindsNoCyclesInAcyclicGraphTest() { var graph = new DirectedGraph<int>(new[] { 1, 2, 3, 4, 5 }); // Add non-cyclic edges graph.AddEdge(1, 2); graph.AddEdge(1, 5); graph.AddEdge(2, 3); graph.AddEdge(2, 4); graph.AddEdge(3, 4); graph.AddEdge(3, 5); graph.AddEdge(1, 5); graph.FindCycle().Should().BeEmpty("Expected no cycle vertices to be found"); }
public void DirectedGraphFindsCyclesTest() { var graph = new DirectedGraph<int>(new[] { 1, 2, 3, 4, 5 }); // Add cycle graph.AddEdge(1, 2); graph.AddEdge(2, 3); graph.AddEdge(3, 1); // Add extra edges graph.AddEdge(3, 4); graph.AddEdge(4, 5); graph.FindCycle().ShouldBeEquivalentTo(new[] { 1, 2, 3 }, "Expected cycle vertices to be found"); }
static IReadOnlyDictionary<string, IReadOnlyList<Export<IStyleRule, StyleRuleMetadata>>> OrderAndMapRules( IReadOnlyList<Export<IStyleRule, StyleRuleMetadata>> rules) { var languageRuleMap = new Dictionary<string, IReadOnlyList<Export<IStyleRule, StyleRuleMetadata>>>(); ILookup<string, Export<IStyleRule, StyleRuleMetadata>> languageRuleLookup = rules.ToLookup(r => r.Metadata.LanguageName); foreach (IGrouping<string, Export<IStyleRule, StyleRuleMetadata>> languageRules in languageRuleLookup) { var graph = new DirectedGraph<Export<IStyleRule, StyleRuleMetadata>>(languageRules); Dictionary<string, Export<IStyleRule, StyleRuleMetadata>> nameRuleMap = languageRules.ToDictionary(r => r.Metadata.Name); foreach (Export<IStyleRule, StyleRuleMetadata> languageRule in languageRules) { foreach (string afterName in languageRule.Metadata.AfterNames) { Export<IStyleRule, StyleRuleMetadata> afterRule; if (nameRuleMap.TryGetValue(afterName, out afterRule)) { graph.AddEdge(afterRule, languageRule); } } foreach (string beforeName in languageRule.Metadata.BeforeNames) { Export<IStyleRule, StyleRuleMetadata> beforeRule; if (nameRuleMap.TryGetValue(beforeName, out beforeRule)) { graph.AddEdge(languageRule, beforeRule); } } } IReadOnlyList<Export<IStyleRule, StyleRuleMetadata>> cycle = graph.FindCycle(); if (cycle.Count > 0) { var ruleNames = String.Join(", ", cycle.Select(r => r.Metadata.Name)); throw new InvalidOperationException($"Dependency cycle exists in rules {ruleNames}"); } languageRuleMap.Add(languageRules.Key, graph.Sort()); } return languageRuleMap; }