public override DecompositionTree Construct(Graph graph, WidthParameter widthparameter) { DecompositionTree tree = new DecompositionTree(graph, widthparameter); // Create the leaves. DecompositionNode[] nodes = new DecompositionNode[graph.Vertices.Count]; for (int i = 0; i < nodes.Length; i++) { tree.Nodes[i] = nodes[i] = new DecompositionNode(new BitSet(nodes.Length, graph.Vertices[i].Index), i, tree); } int size = nodes.Length; while (size > 1) { // Find the pair of nodes whose combination is of minimal width. double min = double.PositiveInfinity; int first = -1, second = -1; for (int i = 0; i < size; i++) { for (int j = i + 1; j < size; j++) { double width = widthparameter.GetWidth(graph, nodes[i].Set | nodes[j].Set); if (width < min) { min = width; first = i; second = j; } } } // Create the parent and connect it to its children. DecompositionNode node = new DecompositionNode(nodes[first].Set | nodes[second].Set, nodes.Length * 2 - size, tree); tree.Attach(node, nodes[first], Branch.Left); tree.Attach(node, nodes[second], Branch.Right); tree.Nodes[node.Index] = node; // Update the active set of nodes. nodes[first] = node; nodes[second] = nodes[size - 1]; size--; } tree.Attach(null, nodes[0], Branch.Left); tree.ComputeWidth(); return(tree); }
/// <summary> /// Construct a linear decomposition tree from the given starting vertex. /// </summary> protected DecompositionTree construct(Graph graph, WidthParameter widthparameter, Vertex start) { DecompositionTree result = new DecompositionTree(graph, widthparameter); int index = 0; BitSet leftbits = new BitSet(graph.Vertices.Count, start.Index); BitSet rightbits = ~leftbits; BitSet neighborhood = new BitSet(start.Neighborhood); this.add(result, start, index++); while (!rightbits.IsEmpty) { Vertex selected = null; double best = double.PositiveInfinity; var candidates = this.candidates(graph, rightbits, leftbits, neighborhood); foreach (var candidate in candidates) { BitSet left = new BitSet(leftbits); left[candidate.Index] = true; BitSet right = new BitSet(rightbits); right[candidate.Index] = false; double width = widthparameter.GetWidth(graph, left, right); if (width < best) { best = width; selected = candidate; } } leftbits[selected.Index] = true; rightbits[selected.Index] = false; neighborhood.Or(selected.Neighborhood); neighborhood[selected.Index] = false; this.add(result, selected, index); index += 2; } return(result); }