/// <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)); } }
/// <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); } }
/// <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); } } }
/// <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); }
/// <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); } }
/// <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> /// 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); } } }