コード例 #1
0
ファイル: dNeighborhood.cs プロジェクト: FrankvH/BooleanWidth
        // Builds a neighborhood for a set X from the ground on up, without relying on what has been saved previously in O(n^2) time
        public dNeighborhood(BitSet X, BitSet vector, Graph graph)
        {
            // O(n) time copy
            Vector = vector.Copy();
            Occurrences = new Dictionary<int, int>();

            // Loops in O(|Vector|) time over all vertices in the vector
            foreach (int v in Vector)
            {
                // Bitset operation of O(n) time
                BitSet nv = graph.OpenNeighborhood(v) * X;
                Occurrences[v] = Math.Min(nv.Count, dValue);
            }
        }
コード例 #2
0
        // Returns all connected components in a certain subgraph, where we define a subgraph by the vertices that are contained in it
        // We apply multiple dfs searches to find all connected parts of the graph
        public static List<BitSet> ConnectedComponents(Graph graph, BitSet subgraph)
        {
            // Each connected component is defined as a bitset, thus the result is a list of these bitsets
            List<BitSet> result = new List<BitSet>();

            // Working stack for the dfs algorithm
            Stack<int> stack = new Stack<int>();

            // Each vertex of the subgraph will either be explored, or it will be the starting point of a new dfs search
            BitSet todo = subgraph.Copy();

            while (!todo.IsEmpty)
            {
                int s = todo.First();
                stack.Push(s);

                // Start tracking the new component
                BitSet component = new BitSet(0, graph.Size);

                // Default dfs exploring part of the graph
                while (stack.Count > 0)
                {
                    int v = stack.Pop();

                    // If we have not encountered this vertex before (meaning it isn't in this component), then we check for all neighbors if they are part of the subgraph
                    // If a neighbor is part of the subgraph it means that we have to push it on the stack to explore it at a later stage for this component
                    if (!component.Contains(v))
                    {
                        component.Add(v);

                        // Remove this vertex from the 'todo' list, since it can never be the starting point of a new component
                        todo.Remove(v);

                        foreach (int w in graph.OpenNeighborhood(v))
                            if (subgraph.Contains(w))
                                stack.Push(w);
                    }
                }
                // The whole connected component has been found, so we can add it to the list of results
                result.Add(component);
            }
            return result;
        }
コード例 #3
0
ファイル: BronKerbosch.cs プロジェクト: FrankvH/BooleanWidth
        // 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.Copy();

            // 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.Remove(v);
                X.Add(v);
            }

            return count;
        }
コード例 #4
0
ファイル: Heuristics.cs プロジェクト: FrankvH/BooleanWidth
 /*************************/
 // Candidate strategy
 /*************************/
 public static BitSet Candidates(Graph graph, BitSet left, BitSet right, CandidateStrategy candidateStrategy)
 {
     BitSet nl = graph.Neighborhood(left) * right;
     return candidateStrategy == CandidateStrategy.All ?
         right.Copy() : (nl + graph.Neighborhood(nl)) * right;
 }
コード例 #5
0
        private void FillTable(Graph graph, List<int> sequence)
        {
            int n = graph.Size;

            // Processed vertices
            BitSet left = new BitSet(0, n);

            // Unprocessed vertices
            BitSet right = graph.Vertices;

            // Lists of representatives that we keep track of on each level of the algorithm
            LinearRepresentativeList reps = new LinearRepresentativeList();

            // Initial insertions, the empty set always has the empty neighborhood set as a representative initially
            reps.Update(new BitSet(0, n), new BitSet(0, n));

            for (int i = 0; i < sequence.Count; i++)
            {
                /// We give v the possibility to be a representative instead of being contained in neighborhoods
                int v = sequence[i];

                // Actually move v from one set to the other set
                left.Add(v);
                right.Remove(v);

                // We don't want to disturb any pointers so we create new empty datastructures to save everything for the next iteration
                LinearRepresentativeList nextReps = new LinearRepresentativeList();

                // We are iterating over all representatives saved inside the list of the previous step. For each entry there are only two possibilities to create a new neighborhood
                foreach (BitSet representative in reps)
                {
                    // Case 1: The neighborhood possibly contained v (thus v has to be removed), but is still valid
                    BitSet neighborhood = reps.GetNeighborhood(representative) - v;
                    nextReps.Update(representative, neighborhood);

                    // Case 2: The union of the old neighborhood, together with v's neighborhood, creates a new entry. The representative is uniond together with v and saved.
                    BitSet representative_ = representative + v;
                    BitSet neighborhood_ = neighborhood + (graph.OpenNeighborhood(v) * right);
                    nextReps.Update(representative_, neighborhood_);
                }

                // Update the values for the next iteration
                reps = nextReps;

                // Save the maximum size that we encounter during all iterations; this will be the boolean dimension of the graph.
                MaxDimension = Math.Max(MaxDimension, reps.Count);

                // Save the representatives at the current cut in the table
                Table[left.Copy()] = reps;
            }
        }
コード例 #6
0
ファイル: CountIS.cs プロジェクト: FrankvH/BooleanWidth
 public int this[BitSet representative, int k]
 {
     get
     {
         if (!Data[k].ContainsKey(representative))
             return 0;
         return Data[k][representative];
     }
     set
     {
         Data[k][representative.Copy()] = value;
     }
 }
コード例 #7
0
 /*************************/
 // Basic operations
 /*************************/
 // When adding a new entry we check if the neighborhood is already contained in the set
 // If true, then we might replace the previous representative that is not connected to this neighborhood if the new one is lexicographically smaller
 public void Update(BitSet representative, dNeighborhood neighborhood)
 {
     Map.Add(representative.Copy(), neighborhood);
 }
コード例 #8
0
        /*************************/
        // Basic operations
        /*************************/
        // When adding a new entry we check if the neighborhood is already contained in the set
        // If true, then we might replace the previous representative that is not connected to this neighborhood if the new one is lexicographically smaller
        public void Update(BitSet representative, BitSet neighborhood)
        {
            if (Map.ContainsValue(neighborhood))
            {
                BitSet previousRep = Map.Reverse[neighborhood];

                if (representative.IsLexicographicallySmaller(previousRep))
                {
                    Map.Remove(previousRep, neighborhood);
                    Map.Add(representative.Copy(), neighborhood.Copy());
                }
            }
            else
            {
                Map.Add(representative.Copy(), neighborhood.Copy());
            }
        }
コード例 #9
0
 // Basic constructor
 private BipartiteGraph(BitSet _left, BitSet _right, int size)
     : base(size)
 {
     left = _left.Copy();
     right = _right.Copy();
 }
コード例 #10
0
ファイル: CountDS.cs プロジェクト: FrankvH/BooleanWidth
 public int this[BitSet inner, BitSet outer, int k]
 {
     get
     {
         Tuple<BitSet, BitSet> t = new Tuple<BitSet, BitSet>(inner, outer);
         if (!Data[k].ContainsKey(t))
             return 0;
         return Data[k][t];
     }
     set
     {
         Tuple<BitSet, BitSet> t = new Tuple<BitSet, BitSet>(inner.Copy(), outer.Copy());
         Data[k][t] = value;
     }
 }
コード例 #11
0
        // Implementation of Algorithm 1 of 'Fast dynamic programming for locally checkable vertex subset and vertex partitioning problems' (Bui-Xuan et al.)
        // Used to compute the representatives and their corresponding dNeighborhoods for a given node of the decomposition tree
        private void FillTable(Graph graph, BitSet cut)
        {
            int n = graph.Size;
            BitSet _cut = graph.Vertices - cut;

            // Lists of representatives that we keep track of on each level of the algorithm
            RepresentativeList representatives = new RepresentativeList();
            RepresentativeList lastLevel = new RepresentativeList();

            // Initial insertions, the empty set always has the empty neighborhood set as a representative initially
            dNeighborhood dInitial = new dNeighborhood(_cut);
            representatives.Update(new BitSet(0, n), dInitial);
            lastLevel.Update(new BitSet(0, n), dInitial);

            while (lastLevel.Count > 0)
            {
                RepresentativeList nextLevel = new RepresentativeList();
                foreach (BitSet r in lastLevel)
                {
                    foreach (int v in cut)
                    {
                        // avoid that r_ = r, since we already saved all sets of that size
                        if (r.Contains(v))
                            continue;

                        BitSet r_ = r + v;
                        dNeighborhood dn = representatives.GetNeighborhood(r).CopyAndUpdate(graph, v);

                        if (!representatives.ContainsNeighborhood(dn) && !dn.Equals(representatives.GetNeighborhood(r)))
                        {
                            nextLevel.Update(r_, dn);
                            representatives.Update(r_, dn);
                        }
                    }
                }

                // Update the values for the next iteration
                lastLevel = nextLevel;
            }

            // Save the representatives at the current cut in the table
            Table[cut.Copy()] = representatives;

            // Save the maximum size that we encounter during all iterations; this will be the boolean dimension of the graph is d = 1.
            MaxDimension = Math.Max(MaxDimension, representatives.Count);
        }