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