/// <summary> /// Add a tree after the children of the parent specified in the parameters. /// </summary> /// <param name="parentId"> Vertex identifier. </param> /// <param name="tree"> A rooted tree. </param> /// <returns> The dictionary which makes a correspondance between old identifier and new identifier. </returns> public Dictionary <int, int> AddChildTree(int parentId, Tree tree) { Dictionary <int, int> renumberedTree = new Dictionary <int, int>(); int root = tree.root; int rootId = AddChild(parentId); renumberedTree.Add(root, rootId); // PreOrder traversal from root and renumbering new children. traversal t = new traversal(); foreach (int vertexId in t.RecursivePreOrder((mtg)tree, root)) { if (vertexId == root) { continue; } parentId = renumberedTree[(int)tree.Parent(vertexId)]; int vid = AddChild(parentId); renumberedTree.Add(vertexId, vid); } return(renumberedTree); }
/// <summary> /// Returns the subtree which is rooted in the vertex in the parameters. /// </summary> /// <param name="vertexId"> The root of the subtree. </param> /// <param name="copy"> If true: A new tree is returned. /// If false: The subtree is created using the original tree. </param> /// <returns> The subtree. </returns> public Tree SubTree(int vertexId, bool copy = true) { traversal t = new traversal(); if (!copy) { // Remove all vertices not in the Sub-tree IEnumerable <int> bunch = t.RecursivePreOrder((mtg)this, vertexId); foreach (int vid in parent.Keys) { if (!bunch.Contains(vid)) { RemoveVertex(vid); } } root = vertexId; if (parent.ContainsKey(root)) { parent[root] = -1; } else { parent.Add(root, -1); } return(this); } else { Dictionary <int, int> renumberedTree = new Dictionary <int, int>(); Tree tree = new Tree(); tree.root = 0; renumberedTree.Add(vertexId, tree.root); IEnumerable <int> subTree = t.RecursivePreOrder((mtg)this, vertexId); foreach (int vid in subTree) { if (vid != vertexId) { int parent = renumberedTree[(int)Parent(vid)]; int v = tree.AddChild(parent); renumberedTree.Add(vid, v); } } return(tree); } }
/// <summary> /// Remove the subtree rooted on the vertex in the parameters. /// </summary> /// <param name="vertexId"> Vertex identifier. </param> /// <returns> A list of the deleted vertices. </returns> public List <int> RemoveTree(int vertexId) { int vid = vertexId; List <int> vertices = new List <int>(); traversal t = new traversal(); foreach (int vertex in t.RecursivePostOrder((mtg)this, vid)) { RemoveVertex(vertex); vertices.Add(vertex); } return(vertices); }
/// <summary> /// Iterate the components of a vertex. /// </summary> /// <param name="vertexId"> Vertex identifier. </param> /// <returns> Iterator over the components. </returns> IEnumerable <int> ComponentsIterator(int vertexId) { traversal t = new traversal(); if (components.ContainsKey(vertexId)) { foreach (int v in ComponentRootsIter(vertexId)) { foreach (int vertex in t.IterativePreOrder(this, v, vertexId)) { yield return(vertex); } } } else { yield break; } }
/// <summary> /// Insert a tree before the specified vertex. /// </summary> /// <param name="vertexId"> Vertex identifier. </param> /// <param name="tree"> The tree to be inserted. </param> /// <returns> The new identifiers after the sibling has been added. </returns> public Dictionary <int, int> InsertSiblingTree(int vertexId, Tree tree) { Dictionary <int, int> renumberedTree = new Dictionary <int, int>(); int root = tree.root; int rootId = InsertSibling(vertexId); renumberedTree.Add(root, rootId); // PreOrder traversal from root and renumbering the sibling's vertices. traversal t = new traversal(); foreach (int vertex in t.RecursivePreOrder((mtg)tree, vertexId)) { int parent = renumberedTree[(int)tree.Parent(vertex)]; int v = AddChild(parent); renumberedTree.Add(vertex, v); } return(renumberedTree); }
/// <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); }
/// <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; } }
/// <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); }
/// <summary> /// Return the subtree rooted on the vertex in the parameters. /// </summary> /// <param name="vertexId"> Vertex identifier. </param> /// <param name="copy"> If true: return a new tree holding the subtree. /// If false: The subtree is created using the original tree. </param> public new PropertyTree SubTree(int vertexId, bool copy = true) { traversal t = new traversal(); if (!copy) { IEnumerable <int> bunch = t.RecursivePreOrder((mtg)this, vertexId); IEnumerable <int> removeBunch = this.Vertices().Except(bunch); foreach (int vid in removeBunch) { RemoveVertexProperties(vid); // Remove parent edge int parentId = (int)Parent(vid); if (parentId != -1) { children[parentId].Remove(vid); parent.Remove(vid); } // Remove children edges foreach (int child in Children(vid)) { parent[child] = -1; } if (children.ContainsKey(vid)) { children.Remove(vid); } } SetRoot(vertexId); return(this); } else { Dictionary <int, int> renumberedTree = new Dictionary <int, int>(); PropertyTree tree = new PropertyTree(); SetRoot(0); foreach (string name in Properties().Keys) { tree.AddProperty(name); } renumberedTree.Add(vertexId, tree.root); tree.AddVertexProperties(tree.root, GetVertexProperties(vertexId)); IEnumerable <int> subTree = t.RecursivePreOrder((mtg)this, vertexId); foreach (int vid in subTree) { if (vid != vertexId) { int parentId = (int)Parent(vid); if (parentId != -1) { int parent = renumberedTree[parentId]; int v = tree.AddChild(parent); renumberedTree.Add(vid, v); } tree.AddVertexProperties(vid, GetVertexProperties(vid)); } } return(tree); } }