public TreeGroup(TreePart a, TreePart[] b) { this.Parts = new TreePart[b.Length]; this.Smallest = a; this.Edges = EdgeSetFactory.NewSet(a.Edges); this.Size = a.Size; int index = 0; for (int i = 0; i < b.Length; ++i) { this.Size += b[i].Size; this.Edges.Merge(b[i].Edges); if (b[i].Size < Smallest.Size) { this.Parts[index++] = Smallest; this.Smallest = b[i]; } else { this.Parts[index++] = b[i]; } } }
/// <inheritdoc/> public override string GetPart(TreePart part) { return(part switch { TreePart.SiblingConnector => "│ ", TreePart.ChildBranch => "├── ", TreePart.BottomChildBranch => "└── ", _ => throw new ArgumentOutOfRangeException(nameof(part), part, "Unknown tree part."), });
private List <TreePart> SolveSimpleGraph(Dictionary <ushort, Dictionary <ushort, int> > graph, IEnumerable <ushort> solveSet, int maxSize) { BucketQueue <TreeGroup> groups = new BucketQueue <TreeGroup>(); List <TreePart> initialParts = new List <TreePart>(); { foreach (ushort node in solveSet) { initialParts.Add(new TreePart(node)); } } TreeGroup initialGroup = new TreeGroup(initialParts.ToArray()); groups.Enqueue(initialGroup, initialGroup.Size); int generation = 0; HashSet <TreePart> solutions = new HashSet <TreePart>(EqualityComparer <TreePart> .Default); // DO WORK. while (!groups.IsEmpty()) { generation++; TreeGroup group = groups.Dequeue(); if (group.Size > maxSize) { break; } if (generation % 100000 == 0) { Console.WriteLine(generation + " " + group.Size); } TreePart smallest = group.Smallest; foreach (ushort node in smallest.Nodes.ToList()) { int remaining = maxSize - group.Size; foreach (var next in graph[node]) { if (smallest.Nodes.Contains(next.Key)) { continue; } if (next.Value > remaining) { continue; } TreePart part = new TreePart(smallest); Edge edge = new Edge(node, next.Key); part.Nodes.Add(next.Key); part.Edges.Add(edge); part.Size += next.Value; TreePart mergePart = group.Containing(next.Key); TreeGroup newGroup; if (mergePart != null) { part.merge(mergePart); TreePart[] other = new TreePart[group.Parts.Length - 1]; int index = 0; for (int i = 0; i < group.Parts.Length; ++i) { if (group.Parts[i] != mergePart) { other[index++] = group.Parts[i]; } } newGroup = new TreeGroup(part, other); } else { newGroup = new TreeGroup(part, group.Parts); } if (newGroup.Parts.Length == 0) { if (newGroup.Size < maxSize) { solutions.Clear(); maxSize = newGroup.Size; } solutions.Add(newGroup.Smallest); // groups.CapPriority(maxSize); continue; } if (newGroup.Size >= maxSize) { continue; } groups.Enqueue(newGroup, newGroup.Size); } } group.Recycle(); } return(solutions.ToList()); }
/// <summary> /// Get the set of characters used to render the corresponding <see cref="TreePart"/>. /// </summary> /// <param name="part">The part of the tree to get rendering string for.</param> /// <returns>Rendering string for the tree part.</returns> public abstract string GetPart(TreePart part);
public TreeNode(TreePart a, TreePart b, TreePart c) { childParts = new TreePart[3] { a, b, c }; }