Ejemplo n.º 1
0
        /// <summary>
        /// Generates a graph with stars of nodes as close to the desired properties as possible.
        /// Under k-bisimulation it is guaranteed that there are p / (s + 1) * (s + 1) partition blocks.
        /// It is also guaranteed that the number of nodes is at least n.
        /// Hint: choose p as multiple of s + 1, and choose n as multiple of p.
        /// </summary>
        /// <param name="n">Desired number of nodes.</param>
        /// <param name="p">Desired number of partition blocks.</param>
        /// <param name="s">Degree of each star.</param>
        /// <returns></returns>
        public static MultiDirectedGraph <int, int> GenerateStars(int n, int p, int s)
        {
            // Create empty graph and label provider
            var graph = new MultiDirectedGraph <int, int>();

            graph.Name = "Synthetic_" + s + "_Stars_" + p + "_" + n;

            // Node counter for uniqueness
            int node = 0;
            // Number of stars of size s + 1 to satisfy p partition requirement
            int c = p / (s + 1);

            // Keep adding stars while we lack nodes
            while (graph.NumNodes < n)
            {
                // Add c stars
                for (int i = 0; i < c; i++)
                {
                    // Add center node
                    graph.AddNode(node, 0);
                    node += 1;

                    // Add child nodes
                    for (int j = 1; j <= s; j++)
                    {
                        graph.AddNode(node, i * (s + 1) + j);
                        graph.AddEdge(node - j, node, 0);
                        node += 1;
                    }
                }
            }

            return(graph);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generates a graph with chains of nodes as close to the desired properties as possible.
        /// Under k-bisimulation it is guaranteed that there are p / (k + 1) * (k + 1) partition blocks.
        /// It is also guaranteed that the number of nodes is at least n.
        /// Hint: choose p as multiple of k + 1, and choose n as multiple of p.
        /// </summary>
        /// <param name="n">Desired number of nodes.</param>
        /// <param name="p">Desired number of partition blocks.</param>
        /// <param name="k">Depth parameter for bisimulation.</param>
        /// <returns></returns>
        public static MultiDirectedGraph <int, int> GenerateChains(int n, int p, int k)
        {
            // Create empty graph and label provider
            var graph = new MultiDirectedGraph <int, int>();

            graph.Name = "Synthetic_Chains_" + k + "_" + p + "_" + n;

            // Node counter for uniqueness
            int node = 0;
            // Number of chains of length k + 1 to satisfy p partition requirement
            int c = p / (k + 1);

            // Keep adding chains while we lack nodes
            while (graph.NumNodes < n)
            {
                // Add c chains
                for (int i = 0; i < c; i++)
                {
                    // Add initial node
                    graph.AddNode(node, i);
                    node += 1;

                    // Add subsequent nodes with edges
                    for (int j = 1; j <= k; j++)
                    {
                        graph.AddNode(node, i);
                        graph.AddEdge(node - 1, node, i);
                        node += 1;
                    }
                }
            }

            return(graph);
        }
Ejemplo n.º 3
0
        public static void Foo()
        {
            // Process log generator petrinet dot conversion

            var inPath  = Program.Input("In path?", string.Copy);
            var outPath = Program.Input("Out path?", string.Copy);
            var graph   = new MultiDirectedGraph <int, int>();

            var nodeMap = new Dictionary <string, int>();
            int counter = 0;

            var lines = File.ReadAllLines(inPath);

            foreach (var line in lines)
            {
                var tokens = line.Split(new char[] { ' ', '\t', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);

                if (tokens.Length <= 1)
                {
                    continue;
                }

                if (tokens[0][0] == 't')
                {
                    if (!nodeMap.ContainsKey(tokens[0]))
                    {
                        nodeMap.Add(tokens[0], counter++);
                        graph.AddNode(nodeMap[tokens[0]], 0);
                    }
                }

                if (tokens[0][0] == 'p')
                {
                    if (!nodeMap.ContainsKey(tokens[0]))
                    {
                        nodeMap.Add(tokens[0], counter++);
                        graph.AddNode(nodeMap[tokens[0]], 1);
                    }
                }

                if (tokens[1] == "->")
                {
                    var u = nodeMap[tokens[0]];
                    var v = nodeMap[tokens[2]];

                    graph.AddEdge(u, v);
                }
            }

            GraphConverter.SaveToGraphML(graph, outPath);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="n"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        public static MultiDirectedGraph <int, int> ErdosRenyi(int n, double p)
        {
            // Create empty graph and label provider
            var graph = new MultiDirectedGraph <int, int>();

            graph.Name = "Synthetic_ErdosRenyi_" + n + "_" + p;

            // Add n nodes
            for (int i = 0; i < n; i++)
            {
                graph.AddNode(i, 0);
            }

            // Add edges with probability p
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    if (StaticRandom.NextDouble() <= p)
                    {
                        graph.AddEdge(i, j, 0);
                    }
                }
            }

            return(graph);
        }
Ejemplo n.º 5
0
        public static void Bar()
        {
            // Stanford graphs conversion

            var inPath  = Program.Input("In path?", string.Copy);
            var outPath = Program.Input("Out path?", string.Copy);
            var graph   = new MultiDirectedGraph <int, int>();

            var lines = File.ReadAllLines(inPath);

            foreach (var line in lines)
            {
                var tokens = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                if (tokens[0] != "#")
                {
                    int source = int.Parse(tokens[0]);
                    int target = int.Parse(tokens[1]);

                    if (!graph.HasNode(source))
                    {
                        graph.AddNode(source);
                    }

                    if (!graph.HasNode(target))
                    {
                        graph.AddNode(target);
                    }

                    if (!graph.HasEdge(source, target) && !graph.HasEdge(target, source))
                    {
                        graph.AddEdge(source, target);
                    }
                }
            }

            GraphConverter.SaveToGraphML(graph, outPath);
        }
Ejemplo n.º 6
0
        public static void Bla()
        {
            // Merge graphs in a folder with a single source node and sink node

            string path = Program.Input("Please enter the path to folder with graph files", string.Copy);
            var outPath = Program.Input("Out path?", string.Copy);

            string[] filePaths = Directory.GetFiles(path, "*.xml");
            var finalGraph = new MultiDirectedGraph<int, int>();
            var finalSources = new List<int>();
            var finalSinks = new List<int>();
            int count = 0;

            foreach (var filePath in filePaths)
            {
                var graph = GraphLoader.LoadGraphML(filePath, int.Parse, int.Parse);

                foreach (var node in graph.Nodes)
                {
                    finalGraph.AddNode(node + count, graph.NodeLabel(node));
                }

                foreach (var edge in graph.Edges)
                {
                    var s = graph.Source(edge);
                    var t = graph.Target(edge);
                    var l = graph.EdgeLabel(edge);

                    finalGraph.AddEdge(s + count, t + count, l);
                }

                var sources = graph.Nodes.Where(u => graph.In(u).Count() == 0);
                var sinks = graph.Nodes.Where(u => graph.Out(u).Count() == 0);

                if (sources.Count() != 1 || sinks.Count() != 1)
                {
                    throw new Exception();
                }

                finalSources.Add(sources.First() + count);
                finalSinks.Add(sinks.First() + count);

                count += graph.NumNodes;
            }

            finalGraph.MergeNodes(finalSources);
            finalGraph.MergeNodes(finalSinks);

            GraphConverter.SaveToGraphML(finalGraph, outPath);
        }
Ejemplo n.º 7
0
        public static void Bla()
        {
            // Merge graphs in a folder with a single source node and sink node

            string path    = Program.Input("Please enter the path to folder with graph files", string.Copy);
            var    outPath = Program.Input("Out path?", string.Copy);

            string[] filePaths    = Directory.GetFiles(path, "*.xml");
            var      finalGraph   = new MultiDirectedGraph <int, int>();
            var      finalSources = new List <int>();
            var      finalSinks   = new List <int>();
            int      count        = 0;

            foreach (var filePath in filePaths)
            {
                var graph = GraphLoader.LoadGraphML(filePath, int.Parse, int.Parse);

                foreach (var node in graph.Nodes)
                {
                    finalGraph.AddNode(node + count, graph.NodeLabel(node));
                }

                foreach (var edge in graph.Edges)
                {
                    var s = graph.Source(edge);
                    var t = graph.Target(edge);
                    var l = graph.EdgeLabel(edge);

                    finalGraph.AddEdge(s + count, t + count, l);
                }

                var sources = graph.Nodes.Where(u => graph.In(u).Count() == 0);
                var sinks   = graph.Nodes.Where(u => graph.Out(u).Count() == 0);

                if (sources.Count() != 1 || sinks.Count() != 1)
                {
                    throw new Exception();
                }

                finalSources.Add(sources.First() + count);
                finalSinks.Add(sinks.First() + count);

                count += graph.NumNodes;
            }

            finalGraph.MergeNodes(finalSources);
            finalGraph.MergeNodes(finalSinks);

            GraphConverter.SaveToGraphML(finalGraph, outPath);
        }
Ejemplo n.º 8
0
        public static void Bar()
        {
            // Stanford graphs conversion

            var inPath = Program.Input("In path?", string.Copy);
            var outPath = Program.Input("Out path?", string.Copy);
            var graph = new MultiDirectedGraph<int, int>();

            var lines = File.ReadAllLines(inPath);
            foreach (var line in lines)
            {
                var tokens = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                if (tokens[0] != "#")
                {
                    int source = int.Parse(tokens[0]);
                    int target = int.Parse(tokens[1]);

                    if (!graph.HasNode(source))
                    {
                        graph.AddNode(source);
                    }

                    if (!graph.HasNode(target))
                    {
                        graph.AddNode(target);
                    }

                    if (!graph.HasEdge(source, target) && !graph.HasEdge(target, source))
                    {
                        graph.AddEdge(source, target);
                    }
                }
            }

            GraphConverter.SaveToGraphML(graph, outPath);
        }
Ejemplo n.º 9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="n"></param>
        /// <param name="p"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static MultiDirectedGraph <int, int> GenerateTrees(int n, int p, int k)
        {
            // Create empty graph and label provider
            var graph = new MultiDirectedGraph <int, int>();

            graph.Name = "Synthetic_Trees_" + k + "_" + p + "_" + n;

            // Find the degree necessary for a k-depth tree to achieve at least p number of nodes
            int degree = 1;

            while ((int)Math.Pow(degree, k + 1) - 1 < p)
            {
                degree += 1;
            }
            int branchSize = (int)Math.Pow(degree, k + 1) - 1;

            // Keep adding trees while we lack nodes
            for (int treeOffset = 0; treeOffset < n; treeOffset += branchSize)
            {
                int partitionSize = k + 1;

                // Add nodes
                for (int i = 0; i < branchSize; i++)
                {
                    graph.AddNode(treeOffset + i);

                    if (partitionSize < p && Math.Log(i + 1, degree) % 1 != 0)
                    {
                        graph.SetNodeLabel(treeOffset + i, i);
                        partitionSize += 1;
                    }
                    else
                    {
                        graph.SetNodeLabel(treeOffset + i, branchSize);
                    }
                }

                // Add edges
                for (int i = 0; i < branchSize / degree; i++)
                {
                    for (int j = 1; j <= degree; j++)
                    {
                        graph.AddEdge(treeOffset + i, treeOffset + degree * i + j, 0);
                    }
                }
            }

            return(graph);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Collapse a graph which contains parallel edges into a graph without parallel edges.
        /// Node labels are all set to 1.
        /// Edge labels indicate how many parallel edges there originally were from the source to the target.
        /// </summary>
        /// <typeparam name="TNode">Type of node.</typeparam>
        /// <typeparam name="TLabel">Type of label.</typeparam>
        /// <param name="graph">Graph to collapse.</param>
        /// <returns>A copy of the original graph with node labels set to 1 and edge labels indicating how often that edge occurred in the original graph.</returns>
        public static MultiDirectedGraph <TNode, int> Collapse <TNode, TLabel>(MultiDirectedGraph <TNode, TLabel> graph)
        {
            var edgeWeights = new Dictionary <Tuple <TNode, TNode>, int>();
            var transformed = new MultiDirectedGraph <TNode, int>();

            // Copy nodes
            foreach (var u in graph.Nodes)
            {
                transformed.AddNode(u, 1);
            }

            // Count edges from u to v
            foreach (var u in graph.Nodes)
            {
                foreach (var eo in graph.Out(u))
                {
                    var v = graph.Target(eo);
                    var t = Tuple.Create(u, v);

                    if (!edgeWeights.ContainsKey(t))
                    {
                        edgeWeights.Add(t, 0);
                    }

                    edgeWeights[t] += 1;
                }
            }

            // Add weighted edges to the transformed graph
            foreach (var kvp in edgeWeights)
            {
                var u = kvp.Key.Item1;
                var v = kvp.Key.Item2;
                var w = kvp.Value;

                transformed.AddEdge(u, v, w);
            }

            return(transformed);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Computes a reduced graph under some bisimulation equivalence relation.
        /// The input graph must be partitioned by the partitioner modulo said equivalence relation.
        /// </summary>
        /// <typeparam name="TNode">Node type.</typeparam>
        /// <typeparam name="TLabel">Label type.</typeparam>
        /// <param name="graph">Input graph.</param>
        /// <param name="labels">Labels of graph.</param>
        /// <param name="partitioner">Function which partitions the graph modulo some bisimulation equivalence relation.</param>
        /// <returns>A reduced graph where each partition block is a node and edges are reconstructued such that bisimulation equivalence is maintained.</returns>
        public static MultiDirectedGraph <int, TLabel> ReducedGraph <TNode, TLabel>(MultiDirectedGraph <TNode, TLabel> graph, Func <IDictionary <TNode, int> > partitioner)
        {
            var reduced   = new MultiDirectedGraph <int, TLabel>();
            var partition = partitioner();
            var inverted  = Utils.Invert(partition);

            // Add a node for each partition block
            foreach (var kvp in inverted)
            {
                var block = kvp.Key;
                var nodes = kvp.Value.ToArray();
                // var someNode = Utils.Shuffled(nodes).First();
                var someNode = nodes.First();

                reduced.AddNode(block, graph.NodeLabel(someNode));
            }

            // Add the edge going from each partition block to another
            foreach (var kvp in inverted)
            {
                var block = kvp.Key;
                var nodes = kvp.Value.ToArray();
                // var someSource = Utils.Shuffled(nodes).First();
                var someSource = nodes.First();

                foreach (var eo in graph.Out(someSource))
                {
                    var someTarget = graph.Target(eo);
                    var label      = graph.EdgeLabel(eo);

                    if (!reduced.HasEdge(block, partition[someTarget], label))
                    {
                        reduced.AddEdge(block, partition[someTarget], label);
                    }
                }
            }

            return(reduced);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Coarsen a graph based on random matching.
        /// When two nodes collapse, their weights are added up.
        /// The weights on the edges of two collapsed nodes are added up as well.
        /// </summary>
        /// <param name="graph">Graph to coarsen.</param>
        /// <param name="e">Small value which stops the coarsening if the coarser graph is too much like the finer graph.</param>
        /// <param name="M">Minimum number of nodes the coarse graph should have.</param>
        /// <param name="maxWeight">Maximum weight a single collapsed node is allowed to have.</param>
        /// <returns>The coarsened graph along with a list of projections used to obtain the coarsened graph.</returns>
        public static Tuple <MultiDirectedGraph <int, int>, List <Dictionary <int, int> > > Coarsen(MultiDirectedGraph <int, int> graph, double e, int M, int maxWeight)
        {
            // Coarsen the graph incrementally
            var projections = new List <Dictionary <int, int> >();
            var fineGraph   = graph;
            var coarseGraph = graph;

            do
            {
                fineGraph   = coarseGraph;
                coarseGraph = new MultiDirectedGraph <int, int>();

                var partition   = RandomMatching(fineGraph, maxWeight);
                var inverted    = Utils.Invert(partition);
                var edgeWeights = new Dictionary <Tuple <int, int>, int>();

                projections.Add(partition);

                // Add node for each block
                foreach (var match in inverted)
                {
                    int block = match.Key;
                    var nodes = match.Value;
                    int w     = 0;

                    foreach (var u in nodes)
                    {
                        w += fineGraph.NodeLabel(u);
                    }

                    coarseGraph.AddNode(block, w);
                }

                // Sum edge weights, removing parallel edges
                foreach (var match in inverted)
                {
                    int sourceBlock = match.Key;
                    var nodes       = match.Value;

                    foreach (var u in nodes)
                    {
                        foreach (var eo in fineGraph.Out(u))
                        {
                            var v           = fineGraph.Target(eo);
                            var targetBlock = partition[v];
                            int w           = fineGraph.EdgeLabel(eo);
                            var t           = Tuple.Create(sourceBlock, targetBlock);

                            if (!edgeWeights.ContainsKey(t))
                            {
                                edgeWeights.Add(t, 0);
                            }

                            edgeWeights[t] += w;
                        }
                    }
                }

                // Add edges
                foreach (var kvp in edgeWeights)
                {
                    var u = kvp.Key.Item1;
                    var v = kvp.Key.Item2;
                    var w = kvp.Value;

                    coarseGraph.AddEdge(u, v, w);
                }
            } while ((double)fineGraph.NumNodes / (double)coarseGraph.NumNodes > 1.0 + e && coarseGraph.NumNodes > M);

            return(Tuple.Create(coarseGraph, projections));
        }
        /// <summary>
        /// Measures the weighted k-bisimulation partition equivalence between two graphs.
        /// </summary>
        /// <typeparam name="TNode"></typeparam>
        /// <typeparam name="TLabel"></typeparam>
        /// <param name="G1"></param>
        /// <param name="G2"></param>
        /// <param name="L1"></param>
        /// <param name="L2"></param>
        /// <param name="k">A tuple indicating how many nodes of G1 and G2 are in partition blocks that are shared between G1 and G2.</param>
        /// <returns></returns>
        public static Tuple <int, int> WeightedBisimulationEquivalence <TNode, TLabel>(MultiDirectedGraph <TNode, TLabel> G1, MultiDirectedGraph <TNode, TLabel> G2, int k)
        {
            // Create new empty graph and label provider
            var G = new MultiDirectedGraph <Tuple <int, TNode>, TLabel>();

            // Add nodes of G1
            foreach (var node in G1.Nodes.Select(node => Tuple.Create(1, node)))
            {
                G.AddNode(node, G1.NodeLabel(node.Item2));
            }

            // Add nodes of G2
            foreach (var node in G2.Nodes.Select(node => Tuple.Create(2, node)))
            {
                G.AddNode(node, G2.NodeLabel(node.Item2));
            }

            // Add edges of G1
            foreach (var edge in G1.Edges)
            {
                var s = Tuple.Create(1, G1.Source(edge));
                var t = Tuple.Create(1, G1.Target(edge));
                G.AddEdge(s, t, G1.EdgeLabel(edge));
            }

            // Add edges of G2
            foreach (var edge in G2.Edges)
            {
                var s = Tuple.Create(2, G2.Source(edge));
                var t = Tuple.Create(2, G2.Target(edge));
                G.AddEdge(s, t, G2.EdgeLabel(edge));
            }

            // Perform bisimulation reduction
            var partitioner = new GraphPartitioner <Tuple <int, TNode>, TLabel>(G);
            var partition   = partitioner.BoundedExactBisimulationReduction(k);

            // Partition blocks of G1 and G2
            HashSet <int> P1 = new HashSet <int>();
            HashSet <int> P2 = new HashSet <int>();

            foreach (var node in G.Nodes)
            {
                int block = partition[node];

                switch (node.Item1)
                {
                case 1:
                    if (!P1.Contains(block))
                    {
                        P1.Add(block);
                    }
                    break;

                case 2:
                    if (!P2.Contains(block))
                    {
                        P2.Add(block);
                    }
                    break;
                }
            }

            int s1 = 0;
            int s2 = 0;

            foreach (var node in G.Nodes)
            {
                if (P1.Contains(partition[node]) && P2.Contains(partition[node]))
                {
                    switch (node.Item1)
                    {
                    case 1:
                        s1 += 1;
                        break;

                    case 2:
                        s2 += 1;
                        break;
                    }
                }
            }

            return(Tuple.Create(s1, s2));
        }
Ejemplo n.º 14
0
        public static void Foo()
        {
            // Process log generator petrinet dot conversion

            var inPath = Program.Input("In path?", string.Copy);
            var outPath = Program.Input("Out path?", string.Copy);
            var graph = new MultiDirectedGraph<int, int>();

            var nodeMap = new Dictionary<string, int>();
            int counter = 0;

            var lines = File.ReadAllLines(inPath);
            foreach (var line in lines)
            {
                var tokens = line.Split(new char[] { ' ', '\t', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);

                if (tokens.Length <= 1)
                {
                    continue;
                }

                if (tokens[0][0] == 't')
                {
                    if (!nodeMap.ContainsKey(tokens[0]))
                    {
                        nodeMap.Add(tokens[0], counter++);
                        graph.AddNode(nodeMap[tokens[0]], 0);
                    }
                }

                if (tokens[0][0] == 'p')
                {
                    if (!nodeMap.ContainsKey(tokens[0]))
                    {
                        nodeMap.Add(tokens[0], counter++);
                        graph.AddNode(nodeMap[tokens[0]], 1);
                    }
                }

                if (tokens[1] == "->")
                {
                    var u = nodeMap[tokens[0]];
                    var v = nodeMap[tokens[2]];

                    graph.AddEdge(u, v);
                }
            }

            GraphConverter.SaveToGraphML(graph, outPath);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Load a GraphML document.
        /// </summary>
        /// <typeparam name="TNode">Type of the nodes.</typeparam>
        /// <typeparam name="TLabel">Type of the labels.</typeparam>
        /// <param name="path">Path to the GraphML file.</param>
        /// <param name="nodeParser">Function which converts a string to TNode.</param>
        /// <param name="labelParser">Function which converts a string to TLabel.</param>
        /// <returns>The graph and label provider representing the loaded GraphML document.</returns>
        public static MultiDirectedGraph <TNode, TLabel> LoadGraphML <TNode, TLabel>(string path, Func <string, TNode> nodeParser, Func <string, TLabel> labelParser)
        {
            // Read GraphML document
            XmlReaderSettings settings = new XmlReaderSettings();

            settings.ValidationType   = ValidationType.Schema;
            settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;

            using (XmlReader reader = XmlReader.Create(path, settings))
            {
                var document     = XDocument.Load(reader);
                var keys         = document.Root.Elements().Where(element => element.Name.LocalName == "key");
                var graphs       = document.Root.Elements().Where(element => element.Name.LocalName == "graph");
                var xmlGraph     = graphs.First();
                var defaultLabel = default(TLabel);

                // Go through keys
                foreach (var key in keys)
                {
                    // Id of the key
                    var id = (string)key.Attribute("id");

                    switch (id)
                    {
                    case "label":
                        defaultLabel = labelParser(key.Elements().Where(element => element.Name.LocalName == "default").First().Value);
                        break;
                    }
                }

                // Read graph attributes
                string graphName  = (string)xmlGraph.Attribute("id");
                bool   isDirected = (string)xmlGraph.Attribute("edgedefault") == "directed";

                // Construct empty graph and label provider
                // TODO: undirected graph if isDirected is false (for now only use directed graphs)
                var graph = new MultiDirectedGraph <TNode, TLabel>();
                graph.Name = graphName;

                var nodes = xmlGraph.Elements().Where(element => element.Name.LocalName == "node");
                var edges = xmlGraph.Elements().Where(element => element.Name.LocalName == "edge");

                // Go through each node
                foreach (var xmlNode in nodes)
                {
                    string id    = (string)xmlNode.Attribute("id");
                    var    node  = nodeParser(id);
                    var    label = defaultLabel;

                    var data = xmlNode.Elements().Where(element => element.Name.LocalName == "data");
                    foreach (var datum in data)
                    {
                        string key = (string)datum.Attribute("key");

                        switch (key)
                        {
                        case "label":
                            label = labelParser(datum.Value);
                            break;
                        }
                    }

                    graph.AddNode(node, label);
                }

                // Go through each edge
                foreach (var xmlEdge in edges)
                {
                    string xmlSource = (string)xmlEdge.Attribute("source");
                    string xmlTarget = (string)xmlEdge.Attribute("target");
                    var    source    = nodeParser(xmlSource);
                    var    target    = nodeParser(xmlTarget);
                    var    label     = defaultLabel;

                    var data = xmlEdge.Elements().Where(element => element.Name.LocalName == "data");
                    foreach (var datum in data)
                    {
                        string key = (string)datum.Attribute("key");

                        switch (key)
                        {
                        case "label":
                            label = labelParser(datum.Value);
                            break;
                        }
                    }

                    graph.AddEdge(source, target, label);

                    // TODO: replace temporary fix for undirected graphs
                    if (!isDirected)
                    {
                        graph.AddEdge(target, source, label);
                    }
                }

                return(graph);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="D"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static MultiDirectedGraph <int, int> GenerateNiceDAG(int D, int b)
        {
            // Create empty graph and label provider
            var graph = new MultiDirectedGraph <int, int>();

            graph.Name = "Synthetic_DAG_" + D + "_" + b;

            // Define parent function
            Func <int, int> parent = node =>
            {
                // Assume node > 0 (not the root node)
                return(graph.In(node).First());
            };

            // Define level function
            Func <int, int> level = Utils.Y <int, int>(fix => node =>
            {
                if (node == 0)
                {
                    // Root node
                    return(0);
                }
                else
                {
                    return(1 + fix(parent(node)));
                }
            });

            // Create initial tree
            int counter = 0;

            graph.AddNode(counter, 0);
            counter += 1;

            while (graph.Nodes.Select(node => level(node)).Max() < D)
            {
                int max    = graph.Nodes.Select(node => level(node)).Max();
                var lowest = graph.Nodes.Where(node => level(node) == max).ToArray();

                foreach (var node in lowest)
                {
                    int k = StaticRandom.Next(b + 1);

                    for (int i = 0; i < k; i++)
                    {
                        graph.AddNode(counter, 0);
                        graph.AddEdge(node, counter, i);
                        // graph.AddEdge(node, counter, 0);
                        counter += 1;
                    }
                }
            }

            // Transform tree to DAG with nicer partition block distribution
            var copy              = graph.Clone();
            var partitioner       = new GraphPartitioner <int, int>(graph);
            var partition         = partitioner.BoundedExactBisimulationReduction(D);
            var partitionInverted = Utils.Invert(partition);
            var blocks            = partition.Values.Distinct();
            var blockSizes        = Utils.Distribution(partition.Values);
            int blockMax          = blockSizes.Values.Max();

            foreach (var block in blocks)
            {
                int size  = blockSizes[block];
                var nodes = new List <int>(partitionInverted[block]);

                for (int i = size; i < blockMax; i++)
                {
                    // Replicate a random node in this partition block
                    int k = StaticRandom.Next(size);
                    var v = nodes[k];

                    // Replicate the node
                    graph.AddNode(counter, graph.NodeLabel(v));

                    // Replicate its incoming edges
                    foreach (var ei in copy.In(v))
                    {
                        var u = graph.Source(ei);
                        graph.AddEdge(u, counter, graph.EdgeLabel(ei));
                    }

                    // Replicate its outgoing edges
                    foreach (var eo in copy.Out(v))
                    {
                        var w = graph.Target(eo);
                        graph.AddEdge(counter, w, graph.EdgeLabel(eo));
                    }

                    counter += 1;
                }
            }

            return(graph);
        }