Esempio n. 1
0
    public void TestGraphConnectedComponents1Vertex()
    {
        // Arrange
        var input =
            "1" + "\n" +
            "0" + "\n";

        // Act
        var inputReader  = new StringReader(input);
        var outputWriter = new StringWriter();

        using (outputWriter)
        {
            Console.SetIn(inputReader);
            Console.SetOut(outputWriter);
            GraphConnectedComponents.Main();
        }
        var output = outputWriter.ToString();

        // Assert
        var expectedOutput =
            "Connected component: 0\n";

        output = output.Replace("\r\n", "\n");
        Assert.AreEqual(expectedOutput, output);
    }
        public void FlatGraphTest()
        {
            var flatGraph = GraphConnectedComponents.FlatGraph(graph);

            Assert.AreEqual(19, flatGraph.Nodes.Count, "Expected 19 nodes in flatGraph (14 nodes + 5 clusters)");
            Assert.AreEqual(15, flatGraph.Edges.Count, "Expected 15 edges in flatGraph (5 root edges + 10 cluster edges)");
        }
        // class GeometryGraphComparer : IComparer<GeometryGraph> {
        //    public int Compare(GeometryGraph g1, GeometryGraph g2) {
        //        return g2.Nodes.Count.CompareTo(g1.Nodes.Count);
        //    }
        //}

        /// <summary>
        /// Computes layout for possibly disconnected graphs by putting
        /// the layouts for connected components together.
        /// </summary>
        internal void LayoutConnectedComponents()
        {
            GeometryGraph[] graphs = GraphConnectedComponents.CreateComponents(graph.Nodes, graph.Edges).ToArray();
            // layout components, compute bounding boxes

            if (settings.RunInParallel)
            {
                ParallelOptions options = new ParallelOptions();
#if PPC
                if (this.CancelToken != null)
                {
                    options.CancellationToken = this.CancelToken.CancellationToken;
                }
#endif
                System.Threading.Tasks.Parallel.ForEach(graphs, options, LayoutConnectedGraphWithMds);
            }
            else
            {
                for (int i = 0; i < graphs.Length; i++)
                {
                    LayoutConnectedGraphWithMds(graphs[i]);
                }
            }

            if (graphs.Length > 1)
            {
                PackGraphs(graphs, settings);
                //restore the parents
                foreach (var node in graphs.SelectMany(g => g.Nodes))
                {
                    node.GeometryParent = graph;
                }
            }
        }
        public void CalculateLayout(GeometryGraph geometryGraph)
        {
            var geomGraphComponents = GraphConnectedComponents.CreateComponents(geometryGraph.Nodes, geometryGraph.Edges);
            var settings            = LayoutAlgorithmSettings as RankingLayoutSettings;

            foreach (var components in geomGraphComponents)
            {
                var layout = new RankingLayout(settings, components);
                components.Margins = 30;
                layout.Run();
            }
            Microsoft.Msagl.Layout.MDS.MdsGraphLayout.PackGraphs(geomGraphComponents, settings);
            geometryGraph.UpdateBoundingBox();
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a shallow copy of the root cluster and divides into GeometryGraphs each of which is a connected component with
        /// respect to edges internal to root.
        /// </summary>
        /// <param name="cluster">cluster to break into components</param>
        /// <param name="liftCrossEdges">set this to consider lower-level edges while arranging subclusters</param>
        /// <returns>GeometryGraphs that are each a connected component</returns>
        static IEnumerable <GeometryGraph> GetComponents(Cluster cluster, bool liftCrossEdges, double nodeSeparation)
        {
            // Create a copy of the cluster's nodes. Some or all of these may also be clusters. We call these "top nodes".
            Dictionary <Node, Node> originalToCopyNodeMap = ShallowNodeCopyDictionary(cluster);
            var copiedEdges = new List <Edge>();

            // Iterate on the top nodes.
            foreach (var target in originalToCopyNodeMap.Keys)
            {
                foreach (var e in target.InEdges)
                {
                    // Filippo Polo: I'm not sure what's going on here. This seems to be testing whether the source node of the edge is a child of the cluster. But the edge comes from enumerating the in-edges of the target, so the source node is always the target. And the target comes from enumerating the result of a shallow node copy of the cluster. So how could it ever NOT be a child of the cluster? I.e. it looks to me like the following test is always true. Maybe this is a remnant of an earlier attempt to implement edge lifting (see below)?
                    var sourceAncestorUnderRoot = Ancestor(e.Source, cluster);
                    if (sourceAncestorUnderRoot == e.Source)
                    {
                        //it is a flat edge and we are only interested in flat edges
                        copiedEdges.Add(CopyEdge(originalToCopyNodeMap, e, sourceAncestorUnderRoot, target));
                    }
                }
                copiedEdges.AddRange(target.SelfEdges.Select(e => CopyEdge(originalToCopyNodeMap, e)));

                // If this is a cluster, then lift the edges of contained nodes. This allows me to consider edges that connect cluster components as if they connected the clusters themselves, for the purpose of laying out clusters.
                if (liftCrossEdges && target is Cluster)
                {
                    var targetCluster = target as Cluster;
                    // Iterate on all sub nodes.
                    foreach (var sub in targetCluster.AllSuccessorsWidthFirst())
                    {
                        // Iterate on all the in-edges of the sub node.
                        foreach (var e in sub.InEdges)
                        {
                            // I already know that the target of this edge is contained within the top node. Where is the source of the edge?
                            var sourceAncestorUnderRoot = Ancestor(e.Source, cluster);
                            // If the source of the edge is NOT the current top node, then this is an edge that crosses clusters. Note that this may also be null, if it connects to an entirely different cluster; in this case, it will be considered at a higher level.
                            if (sourceAncestorUnderRoot != null && sourceAncestorUnderRoot != target)
                            {
                                // I'm adding a "virtual" (i.e. not actually in the graph) edge to the list, which serves to make these clusters considered to be connected. Note that the source is necessarily in the set of copied nodes, because it was returned by the Ancestor function, which returns top nodes or null (and null is excluded).
                                var virtualEdge = new Edge(originalToCopyNodeMap[sourceAncestorUnderRoot], originalToCopyNodeMap[target]);
                                copiedEdges.Add(virtualEdge);
                            }
                        }
                    }
                }
            }

            return(GraphConnectedComponents.CreateComponents(originalToCopyNodeMap.Values.ToArray(), copiedEdges, nodeSeparation));
        }
Esempio n. 6
0
        /// <summary>
        /// Executes the algorithm.
        /// </summary>
        protected override void RunInternal()
        {
            GeometryGraph[] graphs = GraphConnectedComponents.CreateComponents(graph.Nodes, graph.Edges).ToArray();
            // layout components, compute bounding boxes

            for (int i = 0; i < graphs.Length; i++)
            {
                Calculate(graphs[i]);
            }

            if (graphs.Length > 1)
            {
                Microsoft.Msagl.Layout.MDS.MdsGraphLayout.PackGraphs(graphs, settings);
                //restore the parents
                foreach (var node in graphs.SelectMany(g => g.Nodes))
                {
                    node.GeometryParent = graph;
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a shallow copy of the root cluster and divides into GeometryGraphs each of which is a connected component with
        /// respect to edges internal to root.
        /// </summary>
        /// <param name="cluster">cluster to break into components</param>
        /// <returns>GeometryGraphs that are each a connected component</returns>
        static IEnumerable <GeometryGraph> GetComponents(Cluster cluster)
        {
            Dictionary <Node, Node> originalToCopyNodeMap = ShallowNodeCopyDictionary(cluster);
            var copiedEdges = new List <Edge>();

            foreach (var target in originalToCopyNodeMap.Keys)
            {
                foreach (var e in target.InEdges)
                {
                    var sourceAncestorUnderRoot = Ancestor(e.Source, cluster);
                    if (sourceAncestorUnderRoot == e.Source)
                    {
                        //it is a flat edge and we are only interested in flat edges
                        copiedEdges.Add(CopyEdge(originalToCopyNodeMap, e, sourceAncestorUnderRoot, target));
                    }
                }
                copiedEdges.AddRange(target.SelfEdges.Select(e => CopyEdge(originalToCopyNodeMap, e)));
            }

            return(GraphConnectedComponents.CreateComponents(originalToCopyNodeMap.Values.ToArray(), copiedEdges));
        }
Esempio n. 8
0
    public void TestGraphConnectedComponents0Vertices()
    {
        // Arrange
        var input =
            "0" + "\n";

        // Act
        var inputReader  = new StringReader(input);
        var outputWriter = new StringWriter();

        using (outputWriter)
        {
            Console.SetIn(inputReader);
            Console.SetOut(outputWriter);
            GraphConnectedComponents.Main();
        }
        var output = outputWriter.ToString();

        // Assert
        var expectedOutput = "";

        Assert.AreEqual(expectedOutput, output);
    }
Esempio n. 9
0
    public void TestGraphConnectedComponents9Vertices()
    {
        // Arrange
        var input =
            "9" + "\n" +
            "3 6" + "\n" +
            "3 4 5 6" + "\n" +
            "8" + "\n" +
            "0 1 5" + "\n" +
            "1 6" + "\n" +
            "1 3" + "\n" +
            "0 1 4" + "\n" +
            "" + "\n" +
            "2" + "\n";

        // Act
        var inputReader  = new StringReader(input);
        var outputWriter = new StringWriter();

        using (outputWriter)
        {
            Console.SetIn(inputReader);
            Console.SetOut(outputWriter);
            GraphConnectedComponents.Main();
        }
        var output = outputWriter.ToString();

        // Assert
        var expectedOutput =
            "Connected component: 6 4 5 1 3 0" + "\n" +
            "Connected component: 8 2" + "\n" +
            "Connected component: 7" + "\n";

        output = output.Replace("\r\n", "\n");
        Assert.AreEqual(expectedOutput, output);
    }
Esempio n. 10
0
 static bool IsConnected(GeometryGraph geometryGraph)
 {
     return(GraphConnectedComponents.CreateComponents(geometryGraph.Nodes, geometryGraph.Edges).Count() == 1);
 }
        private void SetGraph()
        {
            var graph = new Graph();

            graph.AddEdge("a", "b");
            graph.AddEdge("e", "b");
            graph.AddEdge("d", "b");
            graph.AddEdge("b", "c");

            graph.AddEdge("a22", "b22");
            graph.AddEdge("e22", "b22");
            graph.AddEdge("d22", "b22");
            graph.AddEdge("b22", "c22");

            graph.AddEdge("a0", "b0");
            graph.AddEdge("b0", "c0");

            graph.AddEdge("a33", "b33");
            graph.AddEdge("e33", "b33");
            graph.AddEdge("d33", "b33");
            graph.AddEdge("b33", "c33");

            graph.AddEdge("a11", "b11");
            graph.AddEdge("b11", "c11").LabelText = "Test labels!";

            graph.CreateGeometryGraph();
            foreach (Node node in graph.Nodes)
            {
                node.GeometryNode.BoundaryCurve = CreateLabelAndBoundary(node);
            }

            foreach (var edge in graph.Edges)
            {
                if (edge.Label != null)
                {
                    var    geomEdge = edge.GeometryEdge;
                    double width;
                    double height;
                    StringMeasure.MeasureWithFont(edge.LabelText,
                                                  new Font(edge.Label.FontName, (float)edge.Label.FontSize), out width, out height);
                    edge.Label.GeometryLabel = geomEdge.Label = new Label(width, height, geomEdge);
                }
            }

            var geomGraph = graph.GeometryGraph;

            var geomGraphComponents = GraphConnectedComponents.CreateComponents(geomGraph.Nodes, geomGraph.Edges);
            var settings            = new SugiyamaLayoutSettings();

            foreach (var subgraph in geomGraphComponents)
            {
                var layout = new LayeredLayout(subgraph, settings);
                subgraph.Margins = settings.NodeSeparation / 2;
                layout.Run();
            }

            Microsoft.Msagl.Layout.MDS.MdsGraphLayout.PackGraphs(geomGraphComponents, settings);

            geomGraph.UpdateBoundingBox();


            gViewer1.NeedToCalculateLayout = false;
            gViewer1.Graph = graph;
        }