public void Cycle3() { // A→B // ↑ ↓ // └─C var graph = new[] { new { Value = "A", DependsOn = "B" }, new { Value = "B", DependsOn = "C" }, new { Value = "C", DependsOn = "A" }, }; var byValue = graph.ToLookup(k => k.Value); var components = graph.DetectCycles(s => byValue[s.DependsOn]); Assert.AreEqual(1, components.Count); Assert.AreEqual(0, components.IndependentComponents().Count()); Assert.AreEqual(1, components.Cycles().Count()); Assert.AreEqual(3, components.Single().Count); }
public void Cycle2() { var graph = new[] { TestValue.Create(1, 2), TestValue.Create(2, 1), }; var byValue = graph.ToLookup(t => t.Value); var components = graph.DetectCycles(s => s.DependsOn.SelectMany(d => byValue[d])); Assert.AreEqual(1, components.Count); Assert.AreEqual(0, components.IndependentComponents().Count()); Assert.AreEqual(1, components.Cycles().Count()); Assert.AreEqual(2, components.First().Count()); }
public void Cycle3WithStub() { TestValue<string> vD; var graph = new[] { TestValue.Create("A", "B"), TestValue.Create("B", "C"), TestValue.Create("C", "A", "D"), vD = TestValue.Create("D"), }; var byValue = graph.ToLookup(t => t.Value); var components = graph.DetectCycles(s => s.DependsOn.SelectMany(d => byValue[d])); Assert.AreEqual(2, components.Count); Assert.AreEqual(1, components.IndependentComponents().Count()); Assert.AreEqual(1, components.Cycles().Count()); Assert.AreEqual(1, components.Count(c => c.Count == 3)); Assert.AreEqual(1, components.Count(c => c.Count == 1)); Assert.IsTrue(components.Single(c => c.Count == 1).Single() == vD); }
public void TwoIsolated3Cycles() { var graph = new[] { TestValue.Create(1, 2), TestValue.Create(2, 3), TestValue.Create(3, 1), TestValue.Create(4, 5), TestValue.Create(5, 6), TestValue.Create(6, 4), }; var byValue = graph.ToLookup(t => t.Value); var components = graph.DetectCycles(s => s.DependsOn.SelectMany(d => byValue[d])); Assert.AreEqual(2, components.Count); Assert.AreEqual(0, components.IndependentComponents().Count()); Assert.AreEqual(2, components.Cycles().Count()); Assert.IsTrue(components.All(c => c.Count == 3)); }
public void SingleVertex() { var graph = new[] { 1 }; var components = graph.DetectCycles(t => null); Assert.AreEqual(1, components.Count); Assert.AreEqual(1, components.IndependentComponents().Count()); Assert.AreEqual(0, components.Cycles().Count()); }
public void Cycle4WithStubIgnoreCaseAndTrim() { var testValues = new { A = TestValue.Create("a ", "B"), B = TestValue.Create(" B", " c "), C = TestValue.Create("C", "A", "D"), D = TestValue.Create("d"), E = TestValue.Create("e", "b"), A2 = TestValue.Create("A ", "B"), }; var graph = new[] { testValues.A, testValues.B, testValues.C, testValues.D, testValues.E, testValues.A2, }; var ignoreCase = DerivedComparer.Create(StringComparer.OrdinalIgnoreCase, (string t) => t.Trim()); var byValue = graph.ToLookup(t => t.Value, ignoreCase); var components = graph.DetectCycles(s => s.DependsOn.SelectMany(d => byValue[d]), TestValue.CreateComparer(ignoreCase)); Assert.AreEqual(3, components.Count); Assert.AreEqual(2, components.IndependentComponents().Count()); // D & E are acyclic Assert.AreEqual(1, components.Cycles().Count()); Assert.AreEqual(1, components.Count(c => c.Count == 3)); Assert.AreEqual(2, components.Count(c => c.Count == 1)); var component1 = components.First(); Assert.IsTrue(component1.Single() == testValues.D); // first component has to be D (used by C which is in a cycle) var component2 = components.Skip(1).First().ToList(); var component3 = components.Skip(2).First(); Assert.IsTrue(component3.Single() == testValues.E); // 3rd component has to be E (requires B which is in a cycle) Assert.IsTrue(component2[0] == testValues.C); // first one has to be C (used by A & B) Assert.IsTrue(component2[1] == testValues.B); // first one has to be B (used by A) Assert.IsTrue(component2[2] == testValues.A); // first one has to be A (used by C, but was in the list ) }