コード例 #1
0
        /// <summary>
        /// Recursively traverse the tree in preorder starting from a vertex.
        /// (Equivalent of pre_order in Python file)
        /// </summary>
        /// <param name="tree"> The tree to be traversed. </param>
        /// <param name="vertexId"> The identifier of the starting vertex. </param>
        /// <returns> Returns an iterator. </returns>
        public IEnumerable <int> RecursivePreOrder(mtg tree, int vertexId, int complex = -1)
        {
            if (complex != -1 && tree.Complex(vertexId) != complex)
            {
                yield break;
            }

            Dictionary <int, dynamic> edgeType = tree.Property("Edge_Type");

            List <int> successor = new List <int>();

            yield return(vertexId);

            foreach (int vid in tree.Children(vertexId))
            {
                if (edgeType[vid].Equals("<"))
                {
                    successor.Add(vid);
                    continue;
                }

                foreach (int node in RecursivePreOrder(tree, vid, complex))
                {
                    yield return(node);
                }
            }

            foreach (int vid in successor)
            {
                foreach (int node in RecursivePreOrder(tree, vid, complex))
                {
                    yield return(node);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Convert a tree into an MTG of NbScales.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="nbScales"></param>
        /// <returns></returns>
        public mtg RandomMtg(mtg tree, int nbScales)
        {
            int    n = tree.NbVertices();
            Random r = new Random();
            Dictionary <int, List <int> > colors = new Dictionary <int, List <int> >()
            {
            };

            colors.Add(nbScales - 1, tree.Vertices());

            for (int s = nbScales - 2; s > 0; s--)
            {
                n = r.Next(1, n);

                var sample = (IEnumerable <int>)colors[s + 1];

                sample = sample.OrderBy(x => r.Next()).Take(n);

                List <int> l = sample.ToList();

                l.Sort();

                if (!l.Contains(tree.root))
                {
                    l.Insert(0, tree.root);
                }

                colors.Add(s, l);
            }

            return(ColoredTree(tree, colors)[0]);
        }
コード例 #3
0
        /// <summary>
        /// Display the tree structure.
        /// </summary>
        /// <returns> A string that represents the tree structure. </returns>
        public IEnumerable <string> DisplayTree(mtg tree, int vertexId, string tab = "", Dictionary <int, dynamic> labels = null, Dictionary <int, dynamic> edgeType = null)
        {
            if (labels == null)
            {
                labels = tree.Property("label");
            }
            if (edgeType == null)
            {
                edgeType = tree.Property("Edge_Type");
            }

            string edgeT;

            if (edgeType.ContainsKey(vertexId))
            {
                edgeT = edgeType[vertexId];
            }
            else
            {
                edgeT = "/";
            }

            string label;

            if (labels.ContainsKey(vertexId))
            {
                label = labels[vertexId];
            }
            else
            {
                label = vertexId.ToString();
            }

            yield return(tab + edgeT + label);

            foreach (int child in tree.Children(vertexId))
            {
                if (edgeType.ContainsKey(child))
                {
                    if (edgeType[child] == "+")
                    {
                        tab += "\t";
                    }

                    foreach (string s in DisplayTree(tree, child, tab, labels, edgeType))
                    {
                        yield return(s);
                    }

                    if (edgeType[child] == "+")
                    {
                        tab.Remove(tab.Length - 1);
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Compute missing edges on an incomplete MTG at a given scale.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="scale"></param>
        /// <param name="edgeTypeProperty"></param>
        /// <returns> Returns true. </returns>
        bool ComputeMissingEdges(mtg tree, int scale, Dictionary <int, dynamic> edgeTypeProperty = null)
        {
            List <int> roots = tree.Roots(scale);

            foreach (int vid in roots)
            {
                List <int> components = tree.Components(vid);
                if (components == null || components == new List <int>()
                {
                })
                {
                    Console.WriteLine("Error ! Missing component for vertex " + vid);
                    continue;
                }
                else
                {
                    int componentId = components[0];

                    if (tree.Parent(componentId) == null)
                    {
                        continue;
                    }

                    int?parentId = tree.Complex((int)tree.Parent(componentId));

                    if (parentId == null)
                    {
                        Console.WriteLine("Error ! Missing parent for vertex" + vid);
                        continue;
                    }

                    if (edgeTypeProperty != null)
                    {
                        try
                        {
                            string edgeType = edgeTypeProperty[componentId];
                            tree.AddChild((int)parentId, new Dictionary <string, dynamic>()
                            {
                                { "Edge_Type", edgeType }
                            }, vid);
                        }
                        catch (KeyNotFoundException)
                        {
                            tree.AddChild((int)parentId, vid);
                        }
                    }
                    else
                    {
                        tree.AddChild((int)parentId, vid);
                    }
                }
            }
            return(true);
        }
コード例 #5
0
        /// <summary>
        /// Iteratively traverse the tree in preorder starting from a vertex.
        /// (Equivalent of pre_order2 in Python file)
        /// </summary>
        /// <param name="tree"> The tree to be traversed. </param>
        /// <param name="vertexId"> The identifier of the starting vertex. </param>
        /// <returns> Returns an iterator. </returns>
        public IEnumerable <int> IterativePreOrder(mtg tree, int vertexId, int complex = -1)
        {
            if (complex != -1 && tree.Complex(vertexId) != complex)
            {
                yield break;
            }

            Dictionary <int, dynamic> edgeType = tree.Property("Edge_Type");

            Stack <int> stack = new Stack <int>();

            stack.Push(vertexId);

            while (stack.Count != 0)
            {
                List <int> plus      = new List <int>();
                List <int> successor = new List <int>();

                vertexId = stack.Pop();
                yield return(vertexId);

                foreach (int vid in tree.Children(vertexId))
                {
                    if (complex != -1 && tree.Complex(vid) != complex)
                    {
                        continue;
                    }

                    if (!edgeType.ContainsKey(vid))
                    {
                        successor.Add(vid);
                    }
                    else
                    {
                        if (edgeType[vid].Equals("<"))
                        {
                            successor.Add(vid);
                        }
                        else
                        {
                            plus.Add(vid);
                        }
                    }
                }

                plus.AddRange(successor);

                List <int> child = plus;

                child.Reverse();

                child.ForEach(o => stack.Push(o));
            }
        }
コード例 #6
0
        /// <summary>
        /// Return the vertices from the vertex in the parameters up to the root.
        /// </summary>
        /// <param name="g"> The MTG. </param>
        /// <param name="vertexId"> The vertex identifier. </param>
        /// <returns> An iterator on the ancestors of the vertexId up to the root. </returns>
        public IEnumerable <int> FullAncestors(mtg g, int vertexId, string restrictedTo = "NoRestriction", string edgeType = "*", int containedIn = -1)
        {
            Dictionary <int, dynamic> edgeT = g.Property("Edge_Type");
            int cScale;
            int v = vertexId;

            while (v != -1)
            {
                if (edgeType != "*" && edgeT.ContainsKey(v))
                {
                    if (edgeT[v] != edgeType)
                    {
                        yield break;
                    }
                }

                if (restrictedTo == "SameComplex")
                {
                    if (g.Complex(v) != g.Complex(vertexId))
                    {
                        yield break;
                    }
                }
                else
                {
                    if (restrictedTo == "SameAxis")
                    {
                        if (edgeT.ContainsKey(v))
                        {
                            if (edgeT[v] == "+")
                            {
                                yield break;
                            }
                        }
                    }
                }

                if (containedIn != -1)
                {
                    cScale = (int)g.Scale((int)containedIn);

                    if (g.ComplexAtScale(v, cScale) != containedIn)
                    {
                        yield break;
                    }
                }

                yield return(v);

                v = (int)g.Parent(v);
            }
        }
コード例 #7
0
        /// <summary>
        /// Internal method used by MtgIterator.
        /// </summary>
        IEnumerable <int> ScaleIterator(mtg tree, int vertexId, int complexId, Dictionary <int, bool> visited)
        {
            if (vertexId != -1 && !visited.ContainsKey(vertexId) && (tree.ComplexAtScale(vertexId, (int)tree.Scale(complexId)) == complexId))
            {
                foreach (int v in ScaleIterator(tree, (int)tree.Complex(vertexId), complexId, visited))
                {
                    yield return(v);
                }

                visited.Add(vertexId, true);
                yield return(vertexId);
            }
        }
コード例 #8
0
        /// <summary>
        ///  Generates a random tree with a specified number of vertices and children per vertex.
        ///  The generated tree is added to the root in the parameters.
        /// </summary>
        /// <param name="nbVertices"> The number of tree's vertices </param>
        /// <param name="nbChildren"> The maximum number for a vertex </param>
        /// <returns> Returns the generated tree </returns>
        public int RandomTree(mtg t, int root, int nbVertices, int nbChildren = 4)
        {
            int childrenToAdd;

            List <int> randomStack = new List <int>();
            Random     r           = new Random();
            Random     r2          = new Random();

            randomStack.Add(root);

            while (nbVertices > 0)
            {
                // Set a random number of children to add within the specified range.

                int randomInt = r.Next(1, nbChildren);
                childrenToAdd = Math.Min(randomInt, nbVertices);

                // Choose a random vertex among those in the stack of potential parents

                int randomNumber = r2.Next(0, randomStack.Count() - 1);
                int randomVertex = randomStack[randomNumber];

                // Add the specified number of children to the random parent
                for (int i = 0; i < childrenToAdd; ++i)
                {
                    int newChild;

                    if (i == childrenToAdd % 2)
                    {
                        newChild = t.AddChild(randomVertex, new Dictionary <string, dynamic>()
                        {
                            { "Edge_Type", "<" }
                        });
                    }
                    else
                    {
                        newChild = t.AddChild(randomVertex, new Dictionary <string, dynamic>()
                        {
                            { "Edge_Type", "+" }
                        });
                    }

                    randomStack.Add(newChild);
                    nbVertices--;
                }

                randomStack.Remove(randomVertex);
            }

            return(randomStack.Last());
        }
コード例 #9
0
        void LookForCommonAncestor(mtg tree, List <int> commonAncestors, int currentNode)
        {
            while (currentNode != -1)
            {
                for (int i = 0; i < commonAncestors.Count; i++)
                {
                    int node = commonAncestors[i];

                    if (node == currentNode)
                    {
                        for (int j = 0; j < i; j++)
                        {
                            commonAncestors.RemoveAt(0);
                        }
                        return;
                    }
                }

                currentNode = (int)tree.Parent(currentNode);
            }
        }
コード例 #10
0
        /// <summary>
        /// Iterate all components of the vertexId.
        /// </summary>
        /// <param name="tree"> The MTG. </param>
        /// <param name="vertexId"> The vertex from which the iteration begins. </param>
        /// <returns> Iterator on components of the MTG starting from a vertex. </returns>
        public IEnumerable <int> MtgIterator(mtg tree, int vertexId)
        {
            Dictionary <int, bool> visited = new Dictionary <int, bool>();

            visited.Add(vertexId, true);

            int complexId = vertexId;

            int maxScale = tree.MaxScale();

            yield return(vertexId);

            foreach (int vertex in tree.ComponentRootsAtScale(complexId, maxScale))
            {
                foreach (int vid in IterativePreOrder(tree, vertex))
                {
                    foreach (int node in ScaleIterator(tree, vid, complexId, visited))
                    {
                        yield return(node);
                    }
                }
            }
        }
コード例 #11
0
        /// <summary>
        /// Generate and add a regular tree to an existing one at a given vertex.
        /// </summary>
        /// <param name="tree"> The tree that will be modified. </param>
        /// <param name="vertexId"> Vertex on which the subtree will be added. </param>
        /// <param name="NbChildren"> Number of children per parent. </param>
        /// <param name="NbVertices"> Number of vertices of the new tree. </param>
        /// <returns> The tree after being modified. </returns>
        public mtg SimpleTree(mtg tree, int vertexId, int NbChildren = 3, int NbVertices = 20)
        {
            int        vid = vertexId;
            List <int> l   = new List <int>()
            {
                vid
            };

            while (NbVertices > 0)
            {
                int n = Math.Min(NbChildren, NbVertices);
                vid = l[0];
                l.RemoveAt(0);

                for (int i = 0; i < n; i++)
                {
                    int v = tree.AddChild(vid);
                    NbVertices--;
                    l.Add(v);
                }
            }

            return(tree);
        }
コード例 #12
0
        /// <summary>
        /// Add a tree as a child to the specified parent.
        /// </summary>
        /// <param name="parentId"> Parent identifier. </param>
        /// <param name="tree"> The tree to add. </param>
        /// <returns> A dictionary of the correspondance between ids in the tree and the new Ids once the tree is added. </returns>
        public Dictionary <int, int> AddChildTree(int parentId, mtg tree)
        {
            traversal t = new traversal();

            Dictionary <int, int> renumberedTree = new Dictionary <int, int>();
            int vId;

            int root = tree.root;

            int rootId = AddChild(parentId);

            renumberedTree.Add(root, rootId);

            // PreOrder traversal from root and renumbering all subtree vertices

            foreach (int vertexId in t.IterativePreOrder(tree, root))
            {
                if (vertexId == root)
                {
                    continue;
                }

                parentId = (int)Parent(vertexId);

                if (parentId != -1)
                {
                    parentId = renumberedTree[(int)Parent(vertexId)];
                }

                vId = AddChild(parentId);

                renumberedTree.Add(vertexId, vId);
            }

            return(renumberedTree);
        }
コード例 #13
0
        /// <summary>
        /// Display an MTG.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="vertexId"></param>
        /// <returns></returns>
        public IEnumerable <string> DisplayMtg(mtg tree, int vertexId)
        {
            Dictionary <int, dynamic> label    = tree.Property("label");
            Dictionary <int, dynamic> edgeType = tree.Property("Edge_Type");

            traversal t = new traversal();
            string    edgeT;

            int currentVertex = vertexId;

            int tab = 0;

            foreach (int vertex in t.MtgIterator(tree, vertexId))
            {
                edgeT = "/";
                if (vertex != currentVertex)
                {
                    int scale1 = (int)tree.Scale(currentVertex);
                    int scale2 = (int)tree.Scale(vertex);

                    if (scale1 >= scale2)
                    {
                        try
                        {
                            edgeT = edgeType[vertex];
                        }
                        catch (KeyNotFoundException)
                        {
                        }

                        if (scale1 == scale2)
                        {
                            if (tree.Parent(vertex) != currentVertex)
                            {
                                tab   = -1;
                                edgeT = "^" + edgeT;
                            }
                            else
                            {
                                edgeT = "^" + edgeT;
                            }
                        }
                        else
                        {
                            if (scale1 > scale2)
                            {
                                int v = currentVertex;

                                for (int i = 0; i < scale1 - scale2; i++)
                                {
                                    v = (int)tree.Complex(v);
                                }
                                if (tree.Parent(vertex) == v)
                                {
                                    edgeT = "^" + edgeT;
                                }
                                else
                                {
                                    tab  -= 1;
                                    edgeT = "^" + edgeT;
                                }
                            }
                        }
                    }
                    else
                    {
                        Debug.Assert(scale2 - scale1 == 1);
                        tab += 1;
                    }

                    string tabs = "";

                    for (int i = 0; i < tab; i++)
                    {
                        tabs = tabs + "\t";
                    }

                    string labelVertex;

                    if (label.ContainsKey(vertex))
                    {
                        labelVertex = label[vertex];
                    }
                    else
                    {
                        labelVertex = vertex.ToString();
                    }

                    yield return(tabs + edgeT + labelVertex);
                }

                currentVertex = vertex;
            }
        }
コード例 #14
0
        /// <summary>
        /// Compute an mtg from a tree and the list of vertices to be quotiented.
        /// </summary>
        /// <param name="tree"></param>
        /// <param name="colors"></param>
        /// <returns></returns>
        public List <dynamic> ColoredTree(mtg tree, Dictionary <int, List <int> > colors)
        {
            int nbScales = colors.Keys.Max() + 1;

            Dictionary <int, Dictionary <int, int> > mapIndex = new Dictionary <int, Dictionary <int, int> >()
            {
            };

            mtg g = new mtg();

            // Scale 0 : 1 vertex

            int count = 1;

            for (int scale = 1; scale < nbScales; scale++)
            {
                mapIndex.Add(scale, new Dictionary <int, int>());

                foreach (int id in colors[scale])
                {
                    mapIndex[scale].Add(id, count);
                    count++;
                }
            }

            // Build the MTG
            // 1 - Add multiscale info

            Dictionary <int, int> indexScale = mapIndex[1];

            foreach (int id in colors[1])
            {
                g.AddComponent(g.root, componentId: indexScale[id]);
            }

            // 2 - Edit the graph with multiscale info

            for (int scale = 2; scale < nbScales; scale++)
            {
                Dictionary <int, int> previousIndexScale = indexScale;
                indexScale = mapIndex[scale];

                foreach (int id in colors[scale])
                {
                    int complexId   = previousIndexScale[id];
                    int componentId = indexScale[id];

                    if (complexId != -1)
                    {
                        g.AddComponent(complexId, componentId: componentId);
                    }
                    else
                    {
                        if (componentId != -1)
                        {
                            if (g.scale.ContainsKey(componentId))
                            {
                                g.scale[componentId] = scale;
                            }
                            else
                            {
                                g.scale.Add(componentId, scale);
                            }
                        }
                    }
                }
            }

            // 3 - Copy the tree information in the MTG

            if (tree is mtg)
            {
                int maxScale = tree.MaxScale();

                foreach (int vertexId in tree.parent.Keys)
                {
                    int parent = tree.parent[vertexId];

                    if (parent != -1 && tree.Scale(parent) == maxScale)
                    {
                        g.parent.Add(indexScale[vertexId], indexScale[parent]);
                    }
                }

                foreach (int parent in tree.children.Keys)
                {
                    if (tree.Scale(parent) == maxScale)
                    {
                        List <int> childrenToAdd = new List <int>();

                        foreach (int id in tree.children[parent])
                        {
                            childrenToAdd.Add(indexScale[id]);
                        }

                        if (g.children.ContainsKey(indexScale[parent]))
                        {
                            g.children[indexScale[parent]] = childrenToAdd;
                        }
                        else
                        {
                            g.children.Add(indexScale[parent], childrenToAdd);
                        }
                    }
                }
            }
            else
            {
                foreach (int vertexId in tree.parent.Keys)
                {
                    int parent = tree.parent[vertexId];

                    g.parent.Add(indexScale[vertexId], indexScale[parent]);
                }

                foreach (int parent in tree.children.Keys)
                {
                    List <int> childrenToAdd = new List <int>();

                    foreach (int id in tree.children[parent])
                    {
                        childrenToAdd.Add(indexScale[id]);
                    }

                    if (g.children.ContainsKey(indexScale[parent]))
                    {
                        g.children[indexScale[parent]] = childrenToAdd;
                    }
                    else
                    {
                        g.children.Add(indexScale[parent], childrenToAdd);
                    }
                }
            }

            // 4- Copy the properties of the tree

            foreach (string propertyName in tree.Properties().Keys)
            {
                if (!g.properties.ContainsKey(propertyName))
                {
                    g.properties.Add(propertyName, new Dictionary <int, dynamic>());
                }

                Dictionary <int, dynamic> props = tree.properties[propertyName];

                int maxScale = tree.MaxScale();

                foreach (int id in props.Keys)
                {
                    if (tree.Scale(id) == maxScale)
                    {
                        g.properties[propertyName].Add(indexScale[id], props[id]);
                    }
                }
            }

            List <dynamic> returnedValue = new List <dynamic>();

            returnedValue[0] = FatMtg(g);

            returnedValue[1] = indexScale.Values.Zip(indexScale.Keys, (K, V) => new { Key = K, Value = V }).ToDictionary(x => x.Key, x => x.Value);

            return(returnedValue);
        }
コード例 #15
0
        /// <summary>
        /// Compute missing edges at each scale of the slimMtg. It is based
        /// on the explicit edges that are defined at finer scales and
        /// decomposition relantionships.
        /// </summary>
        /// <param name="slimMtg"></param>
        /// <param name="preserveOrder"> If true, the order of the children at the coarsest scales
        /// is deduced from the order of children at finest scale. </param>
        /// <returns> Computed tree. </returns>
        public mtg FatMtg(mtg slimMtg, bool preserveOrder = false)
        {
            int maxScale = slimMtg.MaxScale();

            Dictionary <int, dynamic> edgeTypeProperty = slimMtg.Property("Edge_Type");

            for (int scale = maxScale - 1; scale > 0; scale--)
            {
                ComputeMissingEdges(slimMtg, scale, edgeTypeProperty);

                if (preserveOrder)
                {
                    foreach (int v in slimMtg.Vertices(scale))
                    {
                        List <int> cref = slimMtg.Children(v);

                        if (cref.Count > 1)
                        {
                            List <int> cmp = new List <int>();
                            foreach (int x in cref)
                            {
                                cmp.Add(slimMtg.ComponentRoots(x)[0]);
                            }

                            Dictionary <int, int> cmpDic = cmp.Zip(cref, (K, V) => new { Key = K, Value = V }).ToDictionary(x => x.Key, x => x.Value);

                            traversal t = new traversal();

                            List <int> descendants = t.IterativePostOrder(slimMtg, slimMtg.ComponentRoots(v)[0]).ToList();

                            List <int> orderedChildren = new List <int>();

                            foreach (int x in descendants)
                            {
                                if (cmp.Contains(x))
                                {
                                    orderedChildren.Add(x);
                                }
                            }

                            List <int> ch = new List <int>();

                            foreach (int c in orderedChildren)
                            {
                                if (cmpDic.ContainsKey(c))
                                {
                                    ch.Add(cmpDic[c]);
                                }
                            }

                            if (slimMtg.children.ContainsKey(v))
                            {
                                slimMtg.children[v] = ch;
                            }
                            else
                            {
                                slimMtg.children.Add(v, ch);
                            }
                        }
                    }
                }
            }

            return(slimMtg);
        }
コード例 #16
0
        /// <summary>
        /// Iteratively traverse the tree in postorder starting from a vertex.
        /// (Equivalent of post_order2 in Python file)
        /// </summary>
        /// <param name="tree"> The tree to be traversed. </param>
        /// <param name="vertexId"> The identifier of the starting vertex. </param>
        /// <returns> Returns an iterator. </returns>
        public IEnumerable <int> IterativePostOrder(mtg tree, int vertexId, int complex = -1)
        {
            Dictionary <int, dynamic> edgeType        = tree.Property("Edge_Type");
            Dictionary <int, dynamic> emptyDictionary = new Dictionary <int, dynamic>();

            // Internal function
            Func <int, List <int> > OrderChildren = new Func <int, List <int> >(vid =>
            {
                List <int> plus      = new List <int>();
                List <int> successor = new List <int>();

                foreach (int v in tree.Children(vid))
                {
                    if (complex != -1 && tree.Complex(v) != complex)
                    {
                        continue;
                    }

                    if (!edgeType.ContainsKey(v))
                    {
                        successor.Add(v);
                    }
                    else
                    {
                        if (edgeType[v].Equals("<"))
                        {
                            successor.Add(v);
                        }
                        else
                        {
                            plus.Add(v);
                        }
                    }
                }

                plus.AddRange(successor);
                List <int> child = plus;

                return(child);
            }
                                                                                );

            List <int> visited = new List <int>();

            Stack <int> stack = new Stack <int>();

            stack.Push(vertexId);

            while (stack.Count != 0)
            {
                vertexId = stack.Peek();

                List <int> listOfChildren = OrderChildren(vertexId);

                if (listOfChildren.Count != 0 && (listOfChildren.Intersect(visited).Count() != listOfChildren.Count()))
                {
                    foreach (int vid in listOfChildren)
                    {
                        if (!visited.Contains(vid))
                        {
                            stack.Push(vid);
                            break;
                        }
                    }
                }
                else
                {
                    visited.Add(vertexId);
                    stack.Pop();
                    yield return(vertexId);
                }
            }
        }