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