// Counts the number of independent sets in a graph, such that: // - The vertices in P are legal choices for our IS, initially set to all vertices in the graph // - None of the vertices in X are used, initially empty // The performDFS boolean is used to check if we should perform a check for connectedness on this level of the recursion private static long Compute(Graph graph, BitSet p, BitSet x, bool performDfs) { // Base case, when P and X are both empty we cannot expand the IS if (p.IsEmpty && x.IsEmpty) return 1; // Base case, if a vertex w in X has no neighbor in P, then it means that this IS will never get maximal // since we could always include w. Thus, the IS will not be valid and we return 0. foreach (int w in x) if ((graph.OpenNeighborhood(w) * p).IsEmpty) return 0; long count = 0; // If a DFS is needed we check if the graph induced by (P + X) is still connected. // If the graph is disconnected, in components c1,...,cn then we can simply count the IS of all these components // after which we simply multiply these numbers. if (performDfs) { if (!DepthFirstSearch.Connected(graph, p + x)) { count = 1; foreach (BitSet component in DepthFirstSearch.ConnectedComponents(graph, p + x)) count *= Compute(graph, component * p, component * x, false); return count; } } // Select a pivot in P to branch on // In this case we pick the vertex with the largest degree int maxDegree = -1; ; int pivot = -1; foreach (int u in p) { int deg = graph.Degree(u); if (deg > maxDegree) { maxDegree = deg; pivot = u; } } // There should always be a pivot after the selection procedure if (pivot == -1) throw new Exception("Pivot has not been selected"); // We branch on the pivot, one branch we include the pivot in the IS. // This might possibly disconnect the subgraph G(P + X), thus we set the performDFS boolean to true. count = Compute(graph, p - graph.ClosedNeighborhood(pivot), x - graph.OpenNeighborhood(pivot), true); // One branch we exclude the pivot of the IS. This will not cause the graph to get possibly disconnected count += Compute(graph, p - pivot, x + pivot, false); return count; }
// Counts the number of independent sets in a graph, such that: // - All vertices in R are included in the independent set, initially empty // - Some of the vertices in P are included in the independent set, initially all vertices of the graph // - None of the vertices in X are included in the independent set, initially empty private static long Compute(Graph graph, BitSet r, BitSet p, BitSet x) { // Base case, when P and X are both empty we cannot expand the IS if (p.IsEmpty && x.IsEmpty) return 1; long count = 0; int pivot = -1; int min = int.MaxValue; // Procedure to find a pivot // The idea is that in any maximal IS, either vertex u or a neighbor of u is included (else we could expand by adding u to the IS) // We find the u with the smallest neighborhood, so that we will keep the number of branches low foreach (int u in (p + x)) { int size = (p * graph.OpenNeighborhood(u)).Count; if (size < min) { min = size; pivot = u; } } // There should always be a pivot after the selection procedure, else P and X should both have been empty if (pivot == -1) throw new Exception("Pivot has not been selected"); // Foreach vertex v in the set containing the legal choices of the the closed neighborhood of the pivot, // we include each choice in the IS and compute how many maximal IS will include v by going into recursion foreach (int v in (p * graph.ClosedNeighborhood(pivot))) { count += Compute(graph, r + v, p - graph.ClosedNeighborhood(v), x - graph.OpenNeighborhood(v)); p -=v; x += v; } return count; }
// Counts the number of independent sets in a graph, such that: // - All vertices in R are included in the independent set, initially empty // - Some of the vertices in P are included in the independent set, initially all vertices of the graph // - None of the vertices in X are included in the independent set, initially empty private static int Compute(Graph graph, BitSet r, BitSet p, BitSet x) { // Base case, when P and X are both empty we cannot expand the IS if (p.IsEmpty && x.IsEmpty) return 1; int count = 0; BitSet copy = p; // Foreach vertex v in P we include it in the IS and compute how many maximal IS will include v by going into recursion. foreach (int v in copy) { count += Compute(graph, r + v, p - graph.ClosedNeighborhood(v), x - graph.OpenNeighborhood(v)); p -= v; x += v; } return count; }