/// <summary> /// Test the specified graph. /// </summary> /// <param name="graph">Graph to be tested.</param> public static void Test(Graph graph) { var graph_2 = (Graph)graph.Clone(); var edges = graph.E .Select(e => new WeightedEdge <Vertex> (e.U, e.V, e.W)) .ToList(); var quickGraph = new UndirectedGraph <Vertex, WeightedEdge <Vertex> > (); quickGraph.AddVertexRange(graph.V); quickGraph.AddEdgeRange(edges); var customBoruvkaMst = BoruvkaMST.FindMST(graph); var customKruskalMst = KruskalMST.FindMST(graph_2); var quickGraphMst = quickGraph.MinimumSpanningTreeKruskal(e => e.Weight); if (!(customBoruvkaMst.Length == customKruskalMst.Length && customKruskalMst.Length == quickGraphMst.Count())) { throw new Exception("Something wrong with the number of edges."); } var boruvkaWeight = customBoruvkaMst.Select(e => new BigInteger(e.W)).Aggregate(BigInteger.Add); var kruskalWeight = customKruskalMst.Select(e => new BigInteger(e.W)).Aggregate(BigInteger.Add); var quickGraphWeight = quickGraphMst.Select(e => new BigInteger(e.Weight)).Aggregate(BigInteger.Add); if (!(boruvkaWeight == kruskalWeight && kruskalWeight == quickGraphWeight)) { throw new Exception("Something wrong with MST weight."); } }
//Graph from Separability Generalizes Dirac's Theorem public static UndirectedGraph <int, Edge <int> > TestGraph1() { 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>(0, 4), new Edge <int>(0, 5), new Edge <int>(1, 2), new Edge <int>(1, 4), new Edge <int>(1, 5), new Edge <int>(2, 5), new Edge <int>(2, 6), new Edge <int>(3, 5), new Edge <int>(3, 6), new Edge <int>(4, 7), new Edge <int>(5, 7), new Edge <int>(6, 7) }; g.AddEdgeRange(edges); return(g); }
// Graph with 3-vertex moplex {0,1,2}, 6-vertex cycle, and "false" moplex triangle public static UndirectedGraph <int, Edge <int> > TestGraph2() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); var edges = new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(0, 2), new Edge <int>(0, 3), new Edge <int>(1, 2), new Edge <int>(1, 3), new Edge <int>(2, 3), new Edge <int>(3, 4), new Edge <int>(3, 10), new Edge <int>(4, 5), new Edge <int>(4, 6), new Edge <int>(5, 6), new Edge <int>(5, 8), new Edge <int>(6, 7), new Edge <int>(8, 9), new Edge <int>(9, 10) }; g.AddEdgeRange(edges); return(g); }
private void Initialize() { _graph = new UndirectedGraph <PointVertex, Edge <PointVertex> >(); _nodes.Clear(); foreach (Obstacle obstacle in _obstacles) { foreach (RotationTreeNode node in obstacle.Nodes) { _nodes.Add(node); _graph.AddVertex(new PointVertex(node.Point)); } _graph.AddEdgeRange(obstacle.Segments.Select(s => new Edge <PointVertex>(new PointVertex(s.Point1.Point), new PointVertex(s.Point2.Point)))); } foreach (Point point in _singlePoints) { Obstacle obstacle = _obstacles.FirstOrDefault(o => o.Contains(point)); var newPoint = new RotationTreeNode(obstacle, point, true); _graph.AddVertex(new PointVertex(point)); _nodes.Add(newPoint); } double maxX = _nodes.Max(p => p.Point.X); _plusInf = new RotationTreeNode(new Point(maxX + 100, double.PositiveInfinity)); _minusInf = new RotationTreeNode(new Point(maxX + 100, double.NegativeInfinity)); _plusInf.AddChild(_minusInf); foreach (RotationTreeNode node in _nodes.OrderByDescending(n => n)) { _minusInf.AddChild(node); } }
public UndirectedGraph <int, Edge <int> > GetFullGraph(int verticesCount) { var edgeSet = new HashSet <Edge <int> >(new EdgeComparer()); if (verticesCount < 1) { throw new ArgumentException("There must be at lest 1 vertex in a graph"); } var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(Enumerable.Range(0, verticesCount)); foreach (var sourceVertex in g.Vertices) { foreach (var targetVertex in g.Vertices) { if (sourceVertex == targetVertex) { continue; } edgeSet.Add(new Edge <int>(sourceVertex, targetVertex)); } } g.AddEdgeRange(edgeSet); return(g); }
public IsEulerianGraphAlgorithm(UndirectedGraph <TVertex, UndirectedEdge <TVertex> > graph) { var newGraph = new UndirectedGraph <TVertex, UndirectedEdge <TVertex> >(false, graph.EdgeEqualityComparer); newGraph.AddVertexRange(graph.Vertices); newGraph.AddEdgeRange(graph.Edges); EdgePredicate <TVertex, UndirectedEdge <TVertex> > isLoop = e => e.Source.Equals(e.Target); newGraph.RemoveEdgeIf(isLoop); this.graph = newGraph; }
public int GetConnectedComponents() { var graph = new UndirectedGraph <Voxel, Edge <Voxel> >(); graph.AddVertexRange(GetVoxels().Where(v => v.IsActive)); graph.AddEdgeRange(GetFaces().Where(f => f.IsActive).Select(f => new Edge <Voxel>(f.Voxels[0], f.Voxels[1]))); Dictionary <Voxel, int> components = new Dictionary <Voxel, int>(); var count = QuickGraph.Algorithms.AlgorithmExtensions.ConnectedComponents(graph, components); return(count); }
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 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; }
public IsHamiltonianGraphAlgorithm(UndirectedGraph <TVertex, UndirectedEdge <TVertex> > graph) { // Create new graph without parallel edges var newGraph = new UndirectedGraph <TVertex, UndirectedEdge <TVertex> >(false, graph.EdgeEqualityComparer); newGraph.AddVertexRange(graph.Vertices); newGraph.AddEdgeRange(graph.Edges); // Remove loops EdgePredicate <TVertex, UndirectedEdge <TVertex> > isLoop = e => e.Source.Equals(e.Target); newGraph.RemoveEdgeIf(isLoop); this.graph = newGraph; threshold = newGraph.VertexCount / 2.0; }
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); }
private UndirectedGraph <object, UndirectedEdge <object> > BuildGraph(int[] verticies, int[] edges) { var graph = new UndirectedGraph <object, UndirectedEdge <object> >(); graph.AddVertexRange(verticies.Cast <object>()); var newEdges = edges.Cast <object>().ToArray(); var convEdges = new UndirectedEdge <object> [edges.Length / 2]; for (int i = 0; i < newEdges.Length; i += 2) { convEdges[i / 2] = new UndirectedEdge <object>(newEdges[i], newEdges[i + 1]); } graph.AddEdgeRange(convEdges); return(graph); }
//chordal graph, k = 0 public static UndirectedGraph <int, Edge <int> > TestGraph7() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 0, 1, 2 }); var edges = new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(0, 2), new Edge <int>(1, 2), }; g.AddEdgeRange(edges); return(g); }
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)); }
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); }
/// <summary> /// Initializes a new instance of the <see cref="IsEulerianGraphAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="graph">Graph to check.</param> public IsEulerianGraphAlgorithm([NotNull] IUndirectedGraph <TVertex, TEdge> graph) { if (graph is null) { throw new ArgumentNullException(nameof(graph)); } // Create new graph without parallel edges var newGraph = new UndirectedGraph <TVertex, TEdge>( false, graph.EdgeEqualityComparer); newGraph.AddVertexRange(graph.Vertices); newGraph.AddEdgeRange(graph.Edges); newGraph.RemoveEdgeIf(edge => edge.IsSelfEdge()); _graph = newGraph; }
//reordered testgraph 8 to test for weird cycle finder behavior public static UndirectedGraph <int, Edge <int> > TestGraph8reorder() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 4, 1, 2, 3, 0 }); var edges = new List <Edge <int> > { new Edge <int>(3, 4), new Edge <int>(2, 4), new Edge <int>(1, 4), new Edge <int>(0, 1), new Edge <int>(0, 2), new Edge <int>(0, 3), }; g.AddEdgeRange(edges); return(g); }
private static UndirectedGraph <int, Edge <int> > GetGraph1() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new List <int> { 0, 1, 2, 3, 4, 5 }); g.AddEdgeRange(new List <Edge <int> > { new Edge <int>(0, 1), new Edge <int>(0, 4), new Edge <int>(1, 2), new Edge <int>(1, 4), new Edge <int>(2, 3), new Edge <int>(2, 5), new Edge <int>(4, 5), }); return(g); }
// 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); }
public static Tuple <int, HashSet <Edge <int> > > FindKKernel(UndirectedGraph <int, Edge <int> > graph, DateTime timeOfInit, Holder kernel) { int ret = -1; if (kernel.CC == 0) //no chordless cycles; i.e. the graph is chordal { if (IsChordal2(MoplexAnalysis.AnalyseGraph(graph, null, null), graph)) //hack - we really need to seperate { return(new Tuple <int, HashSet <Edge <int> > >(0, new HashSet <Edge <int> >())); } } int k = kernel.CC - 1; HashSet <Edge <int> > retEdges = null; while (ret == -1) { k++; Kernel.Phase3(kernel, k); var g = new UndirectedGraph <int, Edge <int> >(false); foreach (var relevantV in kernel.A) { var v = int.Parse(relevantV); g.AddVertex(v); } foreach (var v in g.Vertices) { g.AddEdgeRange(graph.AdjacentEdges(v)); } // todo: connected components var time1 = DateTime.Now; var clone = CloneGraph(g); Console.WriteLine(k); var tup = FasterInner(clone, k, k * 2, new HashSet <int>(), null, null, new HashSet <Edge <int> >()); ret = tup.Item1; retEdges = tup.Item2; Console.WriteLine($"Took {(DateTime.Now - time1):c}"); Console.WriteLine($"Cumulated {(DateTime.Now - timeOfInit):c}"); } return(new Tuple <int, HashSet <Edge <int> > >(k - ret, retEdges)); }
// Graph where all vertices are moplexes public static UndirectedGraph <int, Edge <int> > TestGraph3() { var g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(new int[] { 0, 1, 2, 3, 4, 5 }); var edges = new List <Edge <int> > { new Edge <int>(0, 3), new Edge <int>(0, 4), new Edge <int>(0, 5), new Edge <int>(1, 3), new Edge <int>(1, 4), new Edge <int>(1, 5), new Edge <int>(2, 3), new Edge <int>(2, 4), new Edge <int>(2, 5) }; g.AddEdgeRange(edges); return(g); }
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); }
static void Main(string[] args) { //TestGraphs.testAllGraphs(); TestGraphs.Tests(); //var graph1 = parse(args[0], true); //var graph2 = parseFile(args[0], false); //var graph = TestGraphs.TestGraph8(); //var k1 = Faster.Run(graph1); UndirectedGraph <int, Edge <int> > graph = null; if (args.Length > 0) { graph = ParseFile(args[0], false); } else { graph = ReadGraph(); } DrawGraph.drawGraph(graph, new HashSet <Edge <int> >(), @"C:\Users\Frederik\Downloads\instances\1.dot"); Tuple <int, HashSet <Edge <int> > > a = Faster.Run(graph); var k = a.Item1; var edgeSet = a.Item2; //Idiot check graph.AddEdgeRange(edgeSet); var analysis = MoplexAnalysis.AnalyseGraph(graph, null, null); if (!Faster.IsChordal2(analysis, graph)) { //var x = Faster.FindFourCycle2(graph); throw new Exception("Idiot check went terribly wrong"); } //Console.WriteLine($"Graph: {args[0].Split('\\').Last()} has k={k}"); //Console.ReadLine(); PrintSolution(edgeSet); }
private void Initialize() { _graph = new UndirectedGraph<PointVertex, Edge<PointVertex>>(); _nodes.Clear(); foreach (Obstacle obstacle in _obstacles) { foreach (RotationTreeNode node in obstacle.Nodes) { _nodes.Add(node); _graph.AddVertex(new PointVertex(node.Point)); } _graph.AddEdgeRange(obstacle.Segments.Select(s => new Edge<PointVertex>(new PointVertex(s.Point1.Point), new PointVertex(s.Point2.Point)))); } foreach (Point point in _singlePoints) { Obstacle obstacle = _obstacles.FirstOrDefault(o => o.Contains(point)); var newPoint = new RotationTreeNode(obstacle, point, true); _graph.AddVertex(new PointVertex(point)); _nodes.Add(newPoint); } double maxX = _nodes.Max(p => p.Point.X); _plusInf = new RotationTreeNode(new Point(maxX + 100, double.PositiveInfinity)); _minusInf = new RotationTreeNode(new Point(maxX + 100, double.NegativeInfinity)); _plusInf.AddChild(_minusInf); foreach (RotationTreeNode node in _nodes.OrderByDescending(n => n)) _minusInf.AddChild(node); }
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 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 Test_BronKerbosch() { var zipCodeList = XDocument.Load("XMLFile1.xml") .Root.Element("SimpleCodeList") .Elements("Row") .Elements("Value") .Elements("ComplexValue") .Select(i => new { ZipCode = (string)i.Element(ns3 + "zipCode"), LocationCode = (string)i.Element(ns3 + "locationCode"), CaseType = (string)i.Element(ns3 + "caseType"), CaseCategory = (string)i.Element(ns3 + "caseCategory") }) .ToList(); var categoryList = XDocument.Load("XMLFile2.xml") .Root.Element("SimpleCodeList") .Elements("Row") .Elements("Value") .Where(i => (string)i.Attribute("ColumnRef") == "code") .Elements("SimpleValue") .Select(i => (string)i) .ToList(); var zipCodes = zipCodeList.Select(i => i.ZipCode).Where(i => i != null).Distinct().ToList(); var locations = zipCodeList.Select(i => i.LocationCode).Where(i => i != null).Distinct().ToList(); var types = zipCodeList.Select(i => i.CaseType).Where(i => i != null).Distinct().ToList(); var categories = categoryList.Where(i => i != null).Distinct().ToList(); SEquatableUndirectedEdge <string> CreateEdge(string item1, string item2) { return(Comparer <string> .Default.Compare(item1, item2) <= 0 ? new SEquatableUndirectedEdge <string>(item1, item2) : new SEquatableUndirectedEdge <string>(item2, item1)); } var g = new UndirectedGraph <string, SEquatableUndirectedEdge <string> >(); foreach (var zipCode in zipCodes) { g.AddVertex("ZIPCODE:" + zipCode); } foreach (var location in locations) { g.AddVertex("LOCATION:" + location); } foreach (var type in types) { g.AddVertex("TYPE:" + type); } foreach (var category in categories) { g.AddVertex("CATEGORY:" + category); } foreach (var items in zipCodeList.Where(i => i.CaseType != null).Distinct()) { g.AddVertex("TYPE:" + items.CaseType); } foreach (var items in zipCodeList.Where(i => i.CaseCategory != null).Distinct()) { g.AddVertex("CATEGORY:" + items.CaseCategory); } foreach (var zipcode in zipCodes) { foreach (var zipCode2 in zipCodes) { if (zipcode != zipCode2) { g.AddVerticesAndEdge(CreateEdge("ZIPCODE:" + zipcode, "ZIPCODE:" + zipCode2)); } } } foreach (var location in locations) { foreach (var location2 in locations) { if (location != location2) { g.AddVerticesAndEdge(CreateEdge("LOCATION:" + location, "LOCATION:" + location2)); } } } foreach (var type in types) { foreach (var type2 in types) { if (type != type2) { g.AddVerticesAndEdge(CreateEdge("TYPE:" + type, "TYPE:" + type2)); } } } foreach (var category in categories) { foreach (var category2 in categories) { if (category != category2) { g.AddVerticesAndEdge(CreateEdge("CATEGORY:" + category, "CATEGORY:" + category2)); } } } foreach (var zipCode in zipCodes) { foreach (var item in zipCodeList.Where(i => i.ZipCode == zipCode)) { if (item.LocationCode != null) { g.AddEdge(CreateEdge("ZIPCODE:" + zipCode, "LOCATION:" + item.LocationCode)); } else { g.AddEdgeRange(types.Select(location => CreateEdge("ZIPCODE:" + zipCode, "LOCATION:" + location))); } if (item.CaseType != null) { g.AddEdge(CreateEdge("ZIPCODE:" + zipCode, "TYPE:" + item.CaseType)); } else { g.AddEdgeRange(types.Select(type => CreateEdge("ZIPCODE:" + zipCode, "TYPE:" + type))); } if (item.CaseCategory != null) { g.AddEdge(CreateEdge("ZIPCODE:" + zipCode, "CATEGORY:" + item.CaseCategory)); } else { g.AddEdgeRange(categories.Select(category => CreateEdge("ZIPCODE:" + zipCode, "CATEGORY:" + category))); } } } foreach (var location in locations) { foreach (var item in zipCodeList.Where(i => i.LocationCode == location)) { if (item.ZipCode != null) { g.AddEdge(CreateEdge("LOCATION:" + location, "ZIPCODE:" + item.ZipCode)); } else { g.AddEdgeRange(zipCodes.Select(zipCode => CreateEdge("LOCATION:" + location, "ZIPCODE:" + zipCode))); } if (item.CaseType != null) { g.AddEdge(CreateEdge("LOCATION:" + location, "TYPE:" + item.CaseType)); } else { g.AddEdgeRange(types.Select(type => CreateEdge("LOCATION:" + location, "TYPE:" + type))); } if (item.CaseCategory != null) { g.AddEdge(CreateEdge("LOCATION:" + location, "CATEGORY:" + item.CaseCategory)); } else { g.AddEdgeRange(categories.Select(category => CreateEdge("LOCATION:" + location, "CATEGORY:" + category))); } } } foreach (var type in types) { foreach (var item in zipCodeList.Where(i => i.CaseType == type)) { if (item.ZipCode != null) { g.AddEdge(CreateEdge("TYPE:" + type, "ZIPCODE:" + item.ZipCode)); } else { g.AddEdgeRange(zipCodes.Select(zipCode => CreateEdge("TYPE:" + type, "ZIPCODE:" + zipCode))); } if (item.LocationCode != null) { g.AddEdge(CreateEdge("TYPE:" + type, "LOCATION:" + item.LocationCode)); } else { g.AddEdgeRange(locations.Select(location => CreateEdge("TYPE:" + type, "LOCATION:" + location))); } if (item.CaseCategory != null) { g.AddEdge(CreateEdge("TYPE:" + type, "CATEGORY:" + item.CaseCategory)); } else { g.AddEdgeRange(categories.Select(category => CreateEdge("TYPE:" + type, "CATEGORY:" + category))); } } } foreach (var category in categories) { foreach (var item in zipCodeList.Where(i => i.CaseCategory == category)) { if (item.ZipCode != null) { g.AddEdge(CreateEdge("CATEGORY:" + category, "ZIPCODE:" + item.ZipCode)); } else { g.AddEdgeRange(zipCodes.Select(zipCode => CreateEdge("CATEGORY:" + category, "ZIPCODE:" + zipCode))); } if (item.LocationCode != null) { g.AddEdge(CreateEdge("CATEGORY:" + category, "LOCATION:" + item.LocationCode)); } else { g.AddEdgeRange(locations.Select(location => CreateEdge("CATEGORY:" + category, "LOCATION:" + location))); } if (item.CaseType != null) { g.AddEdge(CreateEdge("CATEGORY:" + category, "TYPE:" + item.CaseType)); } else { g.AddEdgeRange(types.Select(type => CreateEdge("CATEGORY:" + category, "TYPE:" + type))); } } } var sw = new Stopwatch(); sw.Start(); //var r1 = g.BronKerbosh(); sw.Stop(); TestContext.WriteLine($"MaximalCliques took {sw.Elapsed}."); sw.Reset(); sw.Start(); var r2 = g.BronKerboshDegeneracy(); sw.Stop(); TestContext.WriteLine($"MaximalCliquesDegeneracy took {sw.Elapsed}."); sw.Reset(); sw.Start(); var r3 = g.BronKerboshPivot(); sw.Stop(); TestContext.WriteLine($"MaximalCliquesPivot took {sw.Elapsed}."); sw.Reset(); r2 = r2.Where(i => i.Any(j => j.StartsWith("ZIPCODE")) && i.Any(j => j.StartsWith("LOCATION")) && i.Any(j => j.StartsWith("TYPE")) && i.Any(j => j.StartsWith("CATEGORY"))).ToList(); r3 = r3.Where(i => i.Any(j => j.StartsWith("ZIPCODE")) && i.Any(j => j.StartsWith("LOCATION")) && i.Any(j => j.StartsWith("TYPE")) && i.Any(j => j.StartsWith("CATEGORY"))).ToList(); r2.Should().HaveCount(72); r3.Should().HaveCount(72); }
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 }
// troublesome component from instances/5.graph without two single-edge-connected-components which should have no minfil edges public static UndirectedGraph <int, Edge <int> > TestGraph14() { var g = new UndirectedGraph <int, Edge <int> >(); var edges = new List <Edge <int> > { new Edge <int>(29, 9), new Edge <int>(39, 29), new Edge <int>(9, 85), new Edge <int>(39, 20), new Edge <int>(39, 91), new Edge <int>(39, 4), new Edge <int>(47, 39), new Edge <int>(39, 97), new Edge <int>(95, 85), new Edge <int>(67, 20), new Edge <int>(72, 67), new Edge <int>(81, 20), new Edge <int>(68, 72), new Edge <int>(81, 30), new Edge <int>(74, 81), new Edge <int>(48, 75), new Edge <int>(18, 48), new Edge <int>(48, 60), new Edge <int>(75, 62), new Edge <int>(18, 70), new Edge <int>(18, 82), new Edge <int>(18, 66), new Edge <int>(18, 60), new Edge <int>(34, 18), new Edge <int>(18, 49), new Edge <int>(66, 62), new Edge <int>(73, 62), new Edge <int>(25, 66), new Edge <int>(34, 49), new Edge <int>(10, 34), new Edge <int>(25, 49), new Edge <int>(65, 93), new Edge <int>(94, 65), new Edge <int>(65, 3), new Edge <int>(89, 65), new Edge <int>(65, 68), new Edge <int>(46, 93), new Edge <int>(89, 94), new Edge <int>(3, 22), new Edge <int>(89, 25), new Edge <int>(89, 73), new Edge <int>(46, 80), new Edge <int>(77, 46), new Edge <int>(46, 52), new Edge <int>(91, 1), new Edge <int>(4, 91), new Edge <int>(4, 43), new Edge <int>(25, 10), new Edge <int>(73, 22), new Edge <int>(30, 95), new Edge <int>(74, 55), }; foreach (var edge in edges) { if (!g.ContainsVertex(edge.Source)) { g.AddVertex(edge.Source); } if (!g.ContainsVertex(edge.Target)) { g.AddVertex(edge.Target); } } g.AddEdgeRange(edges); return(g); }
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); }
// troublesome component from instances/5.graph public static UndirectedGraph <int, Edge <int> > TestGraph13() { var g = new UndirectedGraph <int, Edge <int> >(); var edges = new List <Edge <int> > { new Edge <int>(29, 9), new Edge <int>(39, 29), new Edge <int>(9, 85), new Edge <int>(39, 20), new Edge <int>(39, 91), new Edge <int>(39, 4), new Edge <int>(47, 39), new Edge <int>(39, 97), new Edge <int>(37, 85), new Edge <int>(95, 85), new Edge <int>(26, 59), new Edge <int>(53, 26), new Edge <int>(24, 53), new Edge <int>(67, 20), new Edge <int>(72, 67), new Edge <int>(81, 20), new Edge <int>(68, 72), new Edge <int>(81, 30), new Edge <int>(74, 81), new Edge <int>(48, 75), new Edge <int>(18, 48), new Edge <int>(48, 60), new Edge <int>(75, 62), new Edge <int>(18, 70), new Edge <int>(18, 82), new Edge <int>(18, 66), new Edge <int>(18, 60), new Edge <int>(34, 18), new Edge <int>(18, 49), new Edge <int>(66, 62), new Edge <int>(73, 62), new Edge <int>(24, 50), new Edge <int>(24, 5), new Edge <int>(24, 47), new Edge <int>(83, 24), new Edge <int>(50, 86), new Edge <int>(13, 83), new Edge <int>(86, 56), new Edge <int>(25, 66), new Edge <int>(34, 49), new Edge <int>(10, 34), new Edge <int>(25, 49), new Edge <int>(65, 93), new Edge <int>(94, 65), new Edge <int>(65, 3), new Edge <int>(89, 65), new Edge <int>(65, 68), new Edge <int>(46, 93), new Edge <int>(89, 94), new Edge <int>(3, 22), new Edge <int>(89, 25), new Edge <int>(89, 73), new Edge <int>(46, 80), new Edge <int>(77, 46), new Edge <int>(46, 52), new Edge <int>(17, 0), new Edge <int>(92, 17), new Edge <int>(17, 45), new Edge <int>(0, 15), new Edge <int>(45, 12), new Edge <int>(45, 8), new Edge <int>(45, 19), new Edge <int>(45, 32), new Edge <int>(15, 54), new Edge <int>(91, 1), new Edge <int>(4, 91), new Edge <int>(4, 43), new Edge <int>(12, 37), new Edge <int>(25, 10), new Edge <int>(73, 22), new Edge <int>(30, 95), new Edge <int>(74, 55), new Edge <int>(56, 21), new Edge <int>(56, 42), new Edge <int>(21, 27), new Edge <int>(42, 99) }; foreach (var edge in edges) { if (!g.ContainsVertex(edge.Source)) { g.AddVertex(edge.Source); } if (!g.ContainsVertex(edge.Target)) { g.AddVertex(edge.Target); } } g.AddEdgeRange(edges); return(g); }