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