public static IEnumerable<UndirectedGraph<string, Edge<string>>> GetUndirectedGraphs() { yield return new UndirectedGraph<string, Edge<string>>(); foreach (var g in GetAdjacencyGraphs()) { var ug = new UndirectedGraph<string, Edge<string>>(); ug.AddVerticesAndEdgeRange(g.Edges); yield return ug; } }
private static void ClearEdgesCommon([NotNull, InstantHandle] Action <UndirectedGraph <int, Edge <int> >, int> clearEdges) { int edgesRemoved = 0; var graph = new UndirectedGraph <int, Edge <int> >(); // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local graph.EdgeRemoved += e => { Assert.IsNotNull(e); // ReSharper disable once AccessToModifiedClosure ++edgesRemoved; }; AssertEmptyGraph(graph); // Clear 1 => not in graph clearEdges(graph, 1); AssertEmptyGraph(graph); CheckCounter(0); // Clear 1 => In graph but no out edges graph.AddVertex(1); clearEdges(graph, 1); AssertHasVertices(graph, new[] { 1 }); AssertNoEdge(graph); CheckCounter(0); var edge12 = new Edge <int>(1, 2); var edge23 = new Edge <int>(2, 3); graph.AddVerticesAndEdgeRange(new[] { edge12, edge23 }); // Clear 1 clearEdges(graph, 1); AssertHasEdges(graph, new[] { edge23 }); CheckCounter(1); var edge13 = new Edge <int>(1, 3); var edge31 = new Edge <int>(3, 1); var edge32 = new Edge <int>(3, 2); graph.AddVerticesAndEdgeRange(new[] { edge12, edge13, edge31, edge32 }); // Clear 3 clearEdges(graph, 3); AssertHasEdges(graph, new[] { edge12 }); CheckCounter(4); // Clear 2 = Clear clearEdges(graph, 2); AssertNoEdge(graph); CheckCounter(1); var edge11 = new Edge <int>(1, 1); graph.AddVerticesAndEdgeRange(new[] { edge11, edge12, edge13, edge23, edge31, edge32 }); // Clear self edge clearEdges(graph, 1); AssertHasEdges(graph, new[] { edge23, edge32 }); CheckCounter(4); #region Local function void CheckCounter(int expectedRemovedEdges) { Assert.AreEqual(expectedRemovedEdges, edgesRemoved); edgesRemoved = 0; } #endregion }
public void Cover() { var graph = new UndirectedGraph <int, Edge <int> >(); var algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph); algorithm.Compute(); CollectionAssert.IsEmpty(algorithm.CoverSet); graph.AddVertexRange(new[] { 1, 2, 3 }); algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph); algorithm.Compute(); CollectionAssert.IsEmpty(algorithm.CoverSet); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(2, 2), new Edge <int>(3, 1) }); algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph, new Random(123456)); algorithm.Compute(); CollectionAssert.AreEquivalent( new[] { 1, 2 }, algorithm.CoverSet); graph.AddVertex(4); algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph, new Random(123456)); algorithm.Compute(); CollectionAssert.AreEquivalent( new[] { 1, 2 }, algorithm.CoverSet); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(5, 2) }); algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph, new Random(123456)); algorithm.Compute(); CollectionAssert.AreEquivalent( new[] { 1, 2 }, algorithm.CoverSet); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(6, 7), new Edge <int>(7, 8), new Edge <int>(9, 8) }); algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph, new Random(123456)); algorithm.Compute(); CollectionAssert.AreEquivalent( new[] { 2, 3, 7, 9 }, algorithm.CoverSet); // Other seed give other results algorithm = new MinimumVertexCoverApproximationAlgorithm <int, Edge <int> >(graph, new Random(456789)); algorithm.Compute(); CollectionAssert.AreEquivalent( new[] { 1, 2, 7, 8 }, algorithm.CoverSet); }
public void Clone() { var wrappedGraph = new UndirectedGraph <int, Edge <int> >(); var graph = new ArrayUndirectedGraph <int, Edge <int> >(wrappedGraph); AssertEmptyGraph(graph); var clonedGraph = graph.Clone(); Assert.IsNotNull(clonedGraph); AssertEmptyGraph(clonedGraph); clonedGraph = (ArrayUndirectedGraph <int, Edge <int> >)((ICloneable)graph).Clone(); Assert.IsNotNull(clonedGraph); AssertEmptyGraph(clonedGraph); wrappedGraph.AddVertexRange(new[] { 1, 2, 3 }); graph = new ArrayUndirectedGraph <int, Edge <int> >(wrappedGraph); AssertHasVertices(graph, new[] { 1, 2, 3 }); AssertNoEdge(graph); clonedGraph = graph.Clone(); Assert.IsNotNull(clonedGraph); AssertHasVertices(clonedGraph, new[] { 1, 2, 3 }); AssertNoEdge(clonedGraph); clonedGraph = (ArrayUndirectedGraph <int, Edge <int> >)((ICloneable)graph).Clone(); Assert.IsNotNull(clonedGraph); AssertHasVertices(clonedGraph, new[] { 1, 2, 3 }); AssertNoEdge(clonedGraph); var edge1 = new Edge <int>(1, 2); var edge2 = new Edge <int>(1, 3); var edge3 = new Edge <int>(2, 3); wrappedGraph.AddVerticesAndEdgeRange(new[] { edge1, edge2, edge3 }); graph = new ArrayUndirectedGraph <int, Edge <int> >(wrappedGraph); AssertHasVertices(graph, new[] { 1, 2, 3 }); AssertHasEdges(graph, new[] { edge1, edge2, edge3 }); clonedGraph = graph.Clone(); Assert.IsNotNull(clonedGraph); AssertHasVertices(clonedGraph, new[] { 1, 2, 3 }); AssertHasEdges(clonedGraph, new[] { edge1, edge2, edge3 }); clonedGraph = (ArrayUndirectedGraph <int, Edge <int> >)((ICloneable)graph).Clone(); Assert.IsNotNull(clonedGraph); AssertHasVertices(clonedGraph, new[] { 1, 2, 3 }); AssertHasEdges(clonedGraph, new[] { edge1, edge2, edge3 }); wrappedGraph.AddVertex(4); graph = new ArrayUndirectedGraph <int, Edge <int> >(wrappedGraph); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertHasEdges(graph, new[] { edge1, edge2, edge3 }); clonedGraph = graph.Clone(); Assert.IsNotNull(clonedGraph); AssertHasVertices(clonedGraph, new[] { 1, 2, 3, 4 }); AssertHasEdges(clonedGraph, new[] { edge1, edge2, edge3 }); clonedGraph = (ArrayUndirectedGraph <int, Edge <int> >)((ICloneable)graph).Clone(); Assert.IsNotNull(clonedGraph); AssertHasVertices(clonedGraph, new[] { 1, 2, 3, 4 }); AssertHasEdges(clonedGraph, new[] { edge1, edge2, edge3 }); }
public static UndirectedGraph<string, Edge<string>> LoadUndirectedGraph(string graphmlFile) { var g = LoadGraph(graphmlFile); var ug = new UndirectedGraph<string, Edge<string>>(); ug.AddVerticesAndEdgeRange(g.Edges); return ug; }
public void ToMsaglGraph() { var graph = new AdjacencyGraph <int, Edge <int> >(); ToMsaglGraph_Test(graph); graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVertexRange(new[] { 1, 2, 4 }); ToMsaglGraph_Test(graph); graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(2, 3), new Edge <int>(2, 5), new Edge <int>(3, 4), new Edge <int>(4, 3) }); graph.AddVertex(6); ToMsaglGraph_Test(graph); var undirectedGraph = new UndirectedGraph <int, Edge <int> >(); undirectedGraph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(2, 3), new Edge <int>(2, 5), new Edge <int>(3, 4), new Edge <int>(4, 3) }); undirectedGraph.AddVertex(6); ToMsaglGraph_Test(undirectedGraph); #region Local function // ReSharper disable once InconsistentNaming void ToMsaglGraph_Test(IEdgeListGraph <int, Edge <int> > g) { Graph msaglGraph = g.ToMsaglGraph(); AssertAreEquivalent(g, msaglGraph); var expectedVerticesAdded = new HashSet <int>(g.Vertices); msaglGraph = g.IsVerticesEmpty ? g.ToMsaglGraph(NoNodeAdded) : g.ToMsaglGraph(NodeAdded); AssertAreEquivalent(g, msaglGraph); CollectionAssert.IsEmpty(expectedVerticesAdded); expectedVerticesAdded = new HashSet <int>(g.Vertices); msaglGraph = g.IsVerticesEmpty ? g.ToMsaglGraph(VertexIdentity, NoNodeAdded) : g.ToMsaglGraph(VertexIdentity, NodeAdded); AssertAreEquivalent(g, msaglGraph); CollectionAssert.IsEmpty(expectedVerticesAdded); var expectedEdgesAdded = new HashSet <Edge <int> >(g.Edges); msaglGraph = g.IsEdgesEmpty ? g.ToMsaglGraph(edgeAdded: NoEdgeAdded) : g.ToMsaglGraph(edgeAdded: EdgeAdded); AssertAreEquivalent(g, msaglGraph); CollectionAssert.IsEmpty(expectedEdgesAdded); expectedEdgesAdded = new HashSet <Edge <int> >(g.Edges); msaglGraph = g.IsEdgesEmpty ? g.ToMsaglGraph(VertexIdentity, edgeAdded: NoEdgeAdded) : g.ToMsaglGraph(VertexIdentity, edgeAdded: EdgeAdded); AssertAreEquivalent(g, msaglGraph); CollectionAssert.IsEmpty(expectedEdgesAdded); expectedVerticesAdded = new HashSet <int>(g.Vertices); expectedEdgesAdded = new HashSet <Edge <int> >(g.Edges); if (g.IsVerticesEmpty && g.IsEdgesEmpty) { msaglGraph = g.ToMsaglGraph(NoNodeAdded, NoEdgeAdded); } else if (g.IsVerticesEmpty) { msaglGraph = g.ToMsaglGraph(NoNodeAdded, EdgeAdded); } else if (g.IsEdgesEmpty) { msaglGraph = g.ToMsaglGraph(NodeAdded, NoEdgeAdded); } else { msaglGraph = g.ToMsaglGraph(NodeAdded, EdgeAdded); } AssertAreEquivalent(g, msaglGraph); CollectionAssert.IsEmpty(expectedVerticesAdded); CollectionAssert.IsEmpty(expectedEdgesAdded); expectedVerticesAdded = new HashSet <int>(g.Vertices); expectedEdgesAdded = new HashSet <Edge <int> >(g.Edges); if (g.IsVerticesEmpty && g.IsEdgesEmpty) { msaglGraph = g.ToMsaglGraph(VertexIdentity, NoNodeAdded, NoEdgeAdded); } else if (g.IsVerticesEmpty) { msaglGraph = g.ToMsaglGraph(VertexIdentity, NoNodeAdded, EdgeAdded); } else if (g.IsEdgesEmpty) { msaglGraph = g.ToMsaglGraph(VertexIdentity, NodeAdded, NoEdgeAdded); } else { msaglGraph = g.ToMsaglGraph(VertexIdentity, NodeAdded, EdgeAdded); } AssertAreEquivalent(g, msaglGraph); CollectionAssert.IsEmpty(expectedVerticesAdded); CollectionAssert.IsEmpty(expectedEdgesAdded); #region Local functions string VertexIdentity(int vertex) { return($"id{vertex}"); } void NoNodeAdded(object sender, MsaglVertexEventArgs <int> args) { Assert.Fail($"{nameof(MsaglGraphPopulator<object, Edge<object>>.NodeAdded)} event called."); } void NodeAdded(object sender, MsaglVertexEventArgs <int> args) { Assert.IsTrue(expectedVerticesAdded.Remove(args.Vertex)); } void NoEdgeAdded(object sender, MsaglEdgeEventArgs <int, Edge <int> > args) { Assert.Fail($"{nameof(MsaglGraphPopulator<object, Edge<object>>.EdgeAdded)} event called."); } void EdgeAdded(object sender, MsaglEdgeEventArgs <int, Edge <int> > args) { Assert.IsTrue(expectedEdgesAdded.Remove(args.Edge)); } #endregion } #endregion }
protected static void Compute_Test <TPopulator>( [NotNull, InstantHandle] Func <IEdgeListGraph <int, Edge <int> >, TPopulator> createPopulator) where TPopulator : MsaglGraphPopulator <int, Edge <int> > { // Empty graph var graph = new AdjacencyGraph <int, Edge <int> >(); MsaglGraphPopulator <int, Edge <int> > populator = createPopulator(graph); populator.Compute(); AssertAreEquivalent(graph, populator.MsaglGraph); // Only vertices graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVertexRange(new[] { 1, 2, 3 }); populator = createPopulator(graph); populator.Compute(); AssertAreEquivalent(graph, populator.MsaglGraph); // With vertices and edges graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 3) }); graph.AddVertexRange(new[] { 5, 6 }); populator = createPopulator(graph); populator.Compute(); AssertAreEquivalent(graph, populator.MsaglGraph); // With cycles graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 4), new Edge <int>(3, 1), new Edge <int>(4, 1) }); populator = createPopulator(graph); populator.Compute(); AssertAreEquivalent(graph, populator.MsaglGraph); // With self edge graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 2), new Edge <int>(3, 1) }); populator = createPopulator(graph); populator.Compute(); AssertAreEquivalent(graph, populator.MsaglGraph); // Undirected graph var undirectedGraph = new UndirectedGraph <int, Edge <int> >(); undirectedGraph.AddVerticesAndEdgeRange(new[] { new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 4), new Edge <int>(3, 1) }); populator = createPopulator(undirectedGraph); populator.Compute(); AssertAreEquivalent(undirectedGraph, populator.MsaglGraph); }
/// <summary> /// Добавить грани и прилегающие к ним вершины в граф /// </summary> /// <param name="edges"></param> /// <returns></returns> internal int AddVerticesAndEdgeRange(IEnumerable <Edge <T> > edges) { lock (GraphLocker) return(Graph.AddVerticesAndEdgeRange(edges)); }
public void Attach() { // Undirected DFS is used for tests but result may change if using another search algorithm // or another starting point { var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >(); var graph = new UndirectedGraph <int, Edge <int> >(); var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph); using (recorder.Attach(dfs)) { dfs.Compute(); CollectionAssert.IsEmpty(recorder.VerticesPredecessors); } } { var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >(); var graph = new UndirectedGraph <int, Edge <int> >(); graph.AddVertexRange(new[] { 1, 2 }); var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph); using (recorder.Attach(dfs)) { dfs.Compute(); CollectionAssert.IsEmpty(recorder.VerticesPredecessors); } } { var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >(); var edge12 = new Edge <int>(1, 2); var edge14 = new Edge <int>(1, 4); var edge31 = new Edge <int>(3, 1); var edge33 = new Edge <int>(3, 3); var edge34 = new Edge <int>(3, 4); var edge42 = new Edge <int>(4, 2); var graph = new UndirectedGraph <int, Edge <int> >(); graph.AddVerticesAndEdgeRange(new[] { edge12, edge14, edge31, edge33, edge34, edge42 }); var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph); using (recorder.Attach(dfs)) { dfs.Compute(); CollectionAssert.AreEqual( new Dictionary <int, Edge <int> > { [2] = edge12, [3] = edge34, [4] = edge42 }, recorder.VerticesPredecessors); } } }