private UndirectedGraph<int, UndirectedEdge<int>> BuildGraph(int[] verticies, int[] edges) { var graph = new UndirectedGraph<int, UndirectedEdge<int>>(); graph.AddVertexRange(verticies); var convEdges = new UndirectedEdge<int>[edges.Length / 2]; for (int i = 0; i < edges.Length; i += 2) { convEdges[i / 2] = new UndirectedEdge<int>(edges[i], edges[i + 1]); } graph.AddEdgeRange(convEdges); return graph; }
private int CalcBicliqueCount(int[] verticies, int[] edges) { var g = new UndirectedGraph<int, IEdge<int>>(); g.AddVertexRange(verticies); var convEdges = new Edge<int>[edges.Length / 2]; for (int i = 0; i < edges.Length; i += 2) { convEdges[i / 2] = new Edge<int>(edges[i], edges[i + 1]); } g.AddEdgeRange(convEdges); var algo = new BipartiteDimensionAlgorithm(g); algo.Compute(); return algo.BipartiteDimensionValue; }
private List<List<int>> InducedPaths(int[] verticies, int[] edges) { var graph = new UndirectedGraph<int, IEdge<int>>(); graph.AddVertexRange(verticies); var graphEdges = new Edge<int>[edges.Length / 2]; for (int i = 0; i < edges.Length; i += 2) { graphEdges[i / 2] = new Edge<int>(edges[i], edges[i + 1]); } graph.AddEdgeRange(graphEdges); return InducedPathAlgorithm.findInducedPaths(graph); }
// weird subset of testgraph14 with added edges, where findcycle2 finds cycle and 3 does not public static UndirectedGraph <int, Edge <int> > TestGraph15() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 22, 39, 95, 48, 73, 29, 65, 3, 68, 25, 30, 89, 85, 67, 18, 94, 72, 66, 62, 81, 20 }); var edges = new List <Edge <int> > { new Edge <int>(3, 22), new Edge <int>(73, 22), new Edge <int>(39, 29), new Edge <int>(39, 20), new Edge <int>(95, 85), new Edge <int>(30, 95), new Edge <int>(48, 66), new Edge <int>(48, 62), new Edge <int>(18, 48), new Edge <int>(3, 73), new Edge <int>(73, 62), new Edge <int>(89, 73), new Edge <int>(29, 85), new Edge <int>(94, 65), new Edge <int>(89, 65), new Edge <int>(65, 68), new Edge <int>(65, 3), new Edge <int>(68, 72), new Edge <int>(25, 66), new Edge <int>(18, 25), new Edge <int>(89, 25), new Edge <int>(81, 30), new Edge <int>(89, 94), new Edge <int>(72, 67), new Edge <int>(67, 20), new Edge <int>(18, 66), new Edge <int>(66, 62), new Edge <int>(81, 20) }; g.AddEdgeRange(edges); return(g); }
// Graph 8 as chordal, k = 0 public static UndirectedGraph <int, Edge <int> > TestGraph9() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 0, 1, 2, 3, 4 }); var edges = new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(0, 2), new Edge <int>(0, 3), new Edge <int>(0, 4), new Edge <int>(1, 4), new Edge <int>(2, 4), new Edge <int>(3, 4), }; g.AddEdgeRange(edges); return(g); }
public HashSet<HashSet<int>> GetMaxDomaticPartition(int[] vertices, Tuple<int, int>[] edges) { var graph = new UndirectedGraph<int, Edge<int>>(); graph.AddVertexRange(vertices); foreach (var edge in edges) { graph.AddVerticesAndEdge(new Edge<int>(edge.Item1, edge.Item2)); } var algo = new DomaticPartition<int, Edge<int>>(graph); IEnumerable<IEnumerable<int>> partition = algo.GetMaxSizePartition(); var hashsetPartition = new HashSet<HashSet<int>>(); foreach (var set in partition) { var curSet = new HashSet<int>(set); hashsetPartition.Add(curSet); } return hashsetPartition; }
// two disjoint four cycles public static UndirectedGraph <int, Edge <int> > TestGraph12() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }); var edges = new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(0, 2), new Edge <int>(1, 3), new Edge <int>(2, 3), new Edge <int>(4, 5), new Edge <int>(4, 6), new Edge <int>(5, 7), new Edge <int>(6, 7) }; g.AddEdgeRange(edges); return(g); }
private static UndirectedGraph <int, Edge <int> > GetGraph2() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new List <int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 }); g.AddEdgeRange(new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(0, 3), new Edge <int>(1, 2), new Edge <int>(1, 4), new Edge <int>(2, 4), new Edge <int>(3, 4), new Edge <int>(4, 5), new Edge <int>(4, 6), new Edge <int>(4, 8), new Edge <int>(6, 7), new Edge <int>(7, 8), }); return(g); }
public HashSet <HashSet <int> > GetMaxDomaticPartition(int[] vertices, Tuple <int, int>[] edges) { var graph = new UndirectedGraph <int, Edge <int> >(); graph.AddVertexRange(vertices); foreach (var edge in edges) { graph.AddVerticesAndEdge(new Edge <int>(edge.Item1, edge.Item2)); } var algo = new DomaticPartition <int, Edge <int> >(graph); IEnumerable <IEnumerable <int> > partition = algo.GetMaxSizePartition(); var hashsetPartition = new HashSet <HashSet <int> >(); foreach (var set in partition) { var curSet = new HashSet <int>(set); hashsetPartition.Add(curSet); } return(hashsetPartition); }
private UndirectedGraph <int, Edge <int> > GetSampleForest(out int[] levels) { var forest = new UndirectedGraph <int, Edge <int> >(); int vertexCount = 19; levels = new int[vertexCount]; forest.AddVertexRange(Enumerable.Range(0, vertexCount)); levels[2] = levels[11] = levels[12] = 0; levels[1] = levels[3] = levels[13] = 1; levels[0] = levels[4] = levels[14] = 2; levels[5] = levels[7] = levels[9] = levels[15] = levels[17] = 3; levels[6] = levels[8] = levels[10] = levels[16] = levels[18] = 4; forest.AddEdgeRange(new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(2, 1), new Edge <int>(2, 3), new Edge <int>(4, 3), new Edge <int>(4, 5), new Edge <int>(4, 7), new Edge <int>(4, 9), new Edge <int>(5, 6), new Edge <int>(7, 8), new Edge <int>(9, 10), new Edge <int>(12, 13), new Edge <int>(13, 14), new Edge <int>(14, 15), new Edge <int>(14, 17), new Edge <int>(17, 18), new Edge <int>(18, 16), new Edge <int>(15, 16), }); return(forest); }
public static int FindVStar(Edge <int> missingEdge, HashSet <int> neighbourhood, UndirectedGraph <int, Edge <int> > graph) { var x = missingEdge.Source; var y = missingEdge.Target; var component = new UndirectedGraph <int, Edge <int> >(); var visited = new HashSet <int> { x }; var complete = new List <List <int> >(); component.AddVertexRange(neighbourhood); foreach (var v in neighbourhood) { component.AddEdgeRange(graph.AdjacentEdges(v).Where(e => component.ContainsVertex(e.GetOtherVertex(v)))); //adds edges not in component, however, since no target vertices will exist if not in the component, these edges will be ignored by QuickGraph } Queue <List <int> > q = new Queue <List <int> >(); foreach (var e in component.AdjacentEdges(x)) { var n = e.GetOtherVertex(x); var l = new List <int> { x, n }; q.Enqueue(l); } while (q.Count > 0) { var l = q.Dequeue(); var n = l.Last(); if (visited.Contains(n)) // What if they have same iteration number? { continue; // l is not cordless. } if (n == y) { complete.Add(l); // The coordless path is complete continue; } visited.Add(n); foreach (var e in graph.AdjacentEdges(n)) { var v = e.GetOtherVertex(n); if (visited.Contains(v)) { continue; } var l2 = CloneList(l); l2.Add(v); q.Enqueue(l2); } } complete.ForEach(l => l.Remove(y)); List <int> vStars = complete.Select(l => l.Last()).ToList(); if (vStars.Any()) { int vStar = vStars.First(); if (vStars.TrueForAll(v => v == vStar)) { return(vStar); } } return(-1); }
public void RemoveEdges() { int verticesRemoved = 0; int edgesRemoved = 0; var graph = new UndirectedGraph <int, Edge <int> >(); graph.VertexRemoved += v => { Assert.IsNotNull(v); ++verticesRemoved; }; graph.EdgeRemoved += e => { Assert.IsNotNull(e); // ReSharper disable once AccessToModifiedClosure ++edgesRemoved; }; var edge12 = new Edge <int>(1, 2); var edge13 = new Edge <int>(1, 3); var edge13Bis = new Edge <int>(1, 3); var edge14 = new Edge <int>(1, 4); var edge24 = new Edge <int>(2, 4); var edge31 = new Edge <int>(3, 1); var edge33 = new Edge <int>(3, 3); var edgeNotInGraph = new Edge <int>(3, 2); graph.AddVertexRange(new[] { 1, 2, 3, 4 }); graph.AddEdgeRange(new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 }); Assert.AreEqual(0, graph.RemoveEdges(Enumerable.Empty <Edge <int> >())); CheckCounters(0); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertHasEdges(graph, new[] { edge12, edge13, edge13Bis, edge14, edge24, edge31, edge33 }); Assert.AreEqual(2, graph.RemoveEdges(new[] { edge12, edge13Bis })); CheckCounters(2); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertHasEdges(graph, new[] { edge13, edge14, edge24, edge31, edge33 }); Assert.AreEqual(2, graph.RemoveEdges(new[] { edge13, edge14, edgeNotInGraph })); CheckCounters(2); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertHasEdges(graph, new[] { edge24, edge31, edge33 }); Assert.AreEqual(3, graph.RemoveEdges(new[] { edge24, edge31, edge33 })); CheckCounters(3); AssertHasVertices(graph, new[] { 1, 2, 3, 4 }); AssertNoEdge(graph); #region Local function void CheckCounters(int expectedRemovedEdges) { Assert.AreEqual(0, verticesRemoved); Assert.AreEqual(expectedRemovedEdges, edgesRemoved); edgesRemoved = 0; } #endregion }
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); } } }
private static List <Edge <int> > LiftingV2(List <Edge <int> > augmentingPath, List <Edge <int> > blossom, UndirectedGraph <int, Edge <int> > g, Edge <int> edgeBetweenTrees, int superVertex, List <Edge <int> > currentMatching) { var liftedAugmentingPath = new List <Edge <int> >(); var blossomVertices = new HashSet <int>(); foreach (var edge in blossom) { blossomVertices.Add(edge.Source); blossomVertices.Add(edge.Target); } var pathInFirstTree = new List <Edge <int> >(); var pathInSecondTree = new List <Edge <int> >(); bool isFirstTree = true; foreach (var edge in augmentingPath) { if (new EdgeComparer().Equals(edge, edgeBetweenTrees)) { isFirstTree = false; continue; } if (isFirstTree) { pathInFirstTree.Add(edge); } else { pathInSecondTree.Add(edge); } } int edgeBetweenVertexInFirstTree = GetTargetVertex(edgeBetweenTrees, superVertex); Edge <int> edgeBetweenInFullGraph = null; foreach (var edge in g.AdjacentEdges(edgeBetweenVertexInFirstTree)) { int targetVertex = GetTargetVertex(edge, edgeBetweenVertexInFirstTree); if (blossomVertices.Contains(targetVertex)) { edgeBetweenInFullGraph = edge; break; } } if (edgeBetweenInFullGraph == null) { throw new ArgumentException(); } int edgeBetweenVertexInSecondTree = GetTargetVertex(edgeBetweenInFullGraph, edgeBetweenVertexInFirstTree); var pathFromBlossom = new List <Edge <int> >(blossom); //Edge<int> edgeToRemove = null; foreach (var edge in blossom) { if (edge.Source == edgeBetweenVertexInSecondTree && edge.Target == superVertex || edge.Target == edgeBetweenVertexInSecondTree && edge.Source == superVertex) { pathFromBlossom.Remove(edge); //edgeToRemove = edge; break; } } var blossomGraph = new UndirectedGraph <int, Edge <int> >(); blossomGraph.AddVertexRange(g.Vertices); foreach (var edge in pathFromBlossom) { blossomGraph.AddEdge(edge); } var pathStack = new Stack <Edge <int> >(); pathFromBlossom.Clear(); DFSSearch(edgeBetweenVertexInSecondTree, superVertex, blossomGraph, out pathFromBlossom); while (pathStack.Count != 0) { pathFromBlossom.Add(pathStack.Pop()); } //if (pathFromBlossom.Count == blossom.Count) // throw new ArgumentException(); foreach (var edge in pathInFirstTree) { liftedAugmentingPath.Add(edge); } liftedAugmentingPath.Add(edgeBetweenInFullGraph); foreach (var edge in pathFromBlossom) { liftedAugmentingPath.Add(edge); } foreach (var edge in pathInSecondTree) { liftedAugmentingPath.Add(edge); } return(liftedAugmentingPath); }
public IUndirectedGraph <Cluster <T>, ClusterEdge <T> > GenerateClusters(IEnumerable <T> dataObjects) { var tree = new BidirectionalGraph <Cluster <T>, ClusterEdge <T> >(false); var clusters = new List <Cluster <T> >(); foreach (T dataObject in dataObjects) { var cluster = new Cluster <T>(dataObject) { Description = dataObject.ToString() }; clusters.Add(cluster); tree.AddVertex(cluster); } var distances = new Dictionary <UnorderedTuple <Cluster <T>, Cluster <T> >, double>(); for (int i = 0; i < clusters.Count; i++) { for (int j = i + 1; j < clusters.Count; j++) { double distance = _getDistance(clusters[i].DataObjects.First(), clusters[j].DataObjects.First()); if (double.IsNaN(distance) || double.IsInfinity(distance) || distance < 0) { throw new ArgumentException("Invalid distance between data objects.", "dataObjects"); } distances[UnorderedTuple.Create(clusters[i], clusters[j])] = distance; } } while (clusters.Count > 2) { Dictionary <Cluster <T>, double> r = clusters.ToDictionary(c => c, c => clusters.Where(oc => oc != c).Sum(oc => distances[UnorderedTuple.Create(c, oc)] / (clusters.Count - 2))); int minI = 0, minJ = 0; double minDist = 0, minQ = double.MaxValue; for (int i = 0; i < clusters.Count; i++) { for (int j = i + 1; j < clusters.Count; j++) { double dist = distances[UnorderedTuple.Create(clusters[i], clusters[j])]; double q = dist - r[clusters[i]] - r[clusters[j]]; if (q < minQ) { minQ = q; minDist = dist; minI = i; minJ = j; } } } Cluster <T> iCluster = clusters[minI]; Cluster <T> jCluster = clusters[minJ]; distances.Remove(UnorderedTuple.Create(iCluster, jCluster)); var uCluster = new Cluster <T>(); tree.AddVertex(uCluster); double iLen = (minDist / 2) + ((r[iCluster] - r[jCluster]) / 2); if (iLen <= 0 && !tree.IsOutEdgesEmpty(iCluster)) { foreach (ClusterEdge <T> edge in tree.OutEdges(iCluster)) { tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length)); } tree.RemoveVertex(iCluster); } else { tree.RemoveInEdgeIf(iCluster, edge => true); tree.AddEdge(new ClusterEdge <T>(uCluster, iCluster, Math.Max(iLen, 0))); } double jLen = minDist - iLen; if (jLen <= 0 && !tree.IsOutEdgesEmpty(jCluster)) { foreach (ClusterEdge <T> edge in tree.OutEdges(jCluster)) { tree.AddEdge(new ClusterEdge <T>(uCluster, edge.Target, edge.Length)); } tree.RemoveVertex(jCluster); } else { tree.RemoveInEdgeIf(jCluster, edge => true); tree.AddEdge(new ClusterEdge <T>(uCluster, jCluster, Math.Max(jLen, 0))); } foreach (Cluster <T> kCluster in clusters.Where(c => c != iCluster && c != jCluster)) { UnorderedTuple <Cluster <T>, Cluster <T> > kiKey = UnorderedTuple.Create(kCluster, iCluster); UnorderedTuple <Cluster <T>, Cluster <T> > kjKey = UnorderedTuple.Create(kCluster, jCluster); distances[UnorderedTuple.Create(kCluster, uCluster)] = (distances[kiKey] + distances[kjKey] - minDist) / 2; distances.Remove(kiKey); distances.Remove(kjKey); } clusters.RemoveAt(minJ); clusters.RemoveAt(minI); clusters.Add(uCluster); } if (clusters.Count == 2) { tree.AddEdge(new ClusterEdge <T>(clusters[1], clusters[0], distances[UnorderedTuple.Create(clusters[0], clusters[1])])); clusters.RemoveAt(0); } var unrootedTree = new UndirectedGraph <Cluster <T>, ClusterEdge <T> >(false); unrootedTree.AddVertexRange(tree.Vertices); unrootedTree.AddEdgeRange(tree.Edges); return(unrootedTree); }
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 }); }
private static List <List <int> > FindMoplexes( UndirectedGraph <int, Edge <int> > graph, Dictionary <int, int> revOrdering, Dictionary <int, int> ordering, Dictionary <int, List <int> > labels, List <Edge <int> > newlyAddedEdges, List <List <int> > prevMoplexes) { var moplexes = new List <List <int> >(); var hasBeenChecked = new List <int>(); if (newlyAddedEdges != null) //newly added edge means that the moplexes effected must be recalculated. { if (prevMoplexes != null) { foreach (var e in newlyAddedEdges) { var validMoplexes = prevMoplexes.Where(moplex => //this should not work!?!?! We add moplexes if they are not effected by the first edge e.Source != moplex.First() && e.Target != moplex.First() && graph.AdjacentEdges(moplex.First()) .Select(edge => edge.GetOtherVertex(moplex.First())) .All(v => v != e.Source && v != e.Target) ).ToList(); moplexes.AddRange(validMoplexes); hasBeenChecked.AddRange(validMoplexes.SelectMany(i => i).Distinct()); } } } else if (prevMoplexes != null) // no newly added edge, so previously calculated moplex must still be relevant. { moplexes.AddRange(prevMoplexes); hasBeenChecked.AddRange(prevMoplexes.SelectMany(m => m).ToList()); } // Start finding new moplexes foreach (var v in labels.Keys) { if (hasBeenChecked.Contains(v)) // no vertex can be part of multiple moplexes { continue; } //equal neighbourhood check var potMoplex = new List <int>(); foreach (var i in labels.Keys) { if (labels[i] != null && labels[i].SequenceEqual(labels[v])) { potMoplex.Add(i); } } //find neighbourhood excl. the potential moplex, i.e. the seperator var seperator = labels[v].Select(l => revOrdering[l]).Except(potMoplex).ToList(); // Check that the seperator is minimal - i.e. check all vertices in the seperator is connected to all components // First: Remove seperator and moplex from graph (temporarily) var tempRemove = new List <Edge <int> >(); foreach (int mv in potMoplex) { tempRemove.AddRange(graph.AdjacentEdges(mv)); graph.RemoveVertex(mv); } foreach (var sv in seperator) { tempRemove.AddRange(graph.AdjacentEdges(sv)); graph.RemoveVertex(sv); } // Find connected components in the new graph var a = new QuickGraph.Algorithms.ConnectedComponents.ConnectedComponentsAlgorithm <int, Edge <int> >(graph); a.Compute(); var nodeToComponentDic = a.Components; // Add the seperator and potential moplex again graph.AddVertexRange(seperator); graph.AddVertexRange(potMoplex); graph.AddEdgeRange(tempRemove); var isMoplex = false; foreach (var sepNode in seperator) // Find the components connected to each of the seperator vertices { HashSet <int> connectedComponents = new HashSet <int>(); foreach (var e in graph.AdjacentEdges(sepNode)) { var neighbour = e.GetOtherVertex(sepNode); if (potMoplex.Contains(neighbour)) { continue; //not a component, since it was removed at the time } if (nodeToComponentDic.ContainsKey(neighbour)) //else neighbour is also seperator TODO: error here, Not anymore I think { int c; nodeToComponentDic.TryGetValue(neighbour, out c); connectedComponents.Add(c); } } if (connectedComponents.Count < a.ComponentCount || a.ComponentCount == 0) { isMoplex = false; break; } isMoplex = true; } if (isMoplex) { moplexes.Add(potMoplex); } // To ensure no dublicates foreach (var n in potMoplex) { hasBeenChecked.Add(n); } } return(moplexes); }