Esempio n. 1
0
        // 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;
        }
        public static Decomposition Compute(Graph graph, Func<Graph, LinearDecomposition> decomposer, params IReductionRule[] rules)
        {
            Graph clone = graph.Clone();
            IReductionRuleCommand[] commands = GraphPreprocessor.ApplyRules(clone, rules).Reverse().ToArray();

            LinearDecomposition ld = decomposer(clone);
            Decomposition dec = Decomposition.FromLinearDecomposition(ld);
            Tree tree = commands.Aggregate(dec.Tree, (current, command) => command.Expand(current));
            return new Decomposition(graph, tree);
        }
Esempio n. 3
0
 public IEnumerable<IReductionRuleCommand> Find(Graph graph)
 {
     foreach (int vertex in graph.Vertices)
     {
         if (graph.Degree(vertex) == 0)
         {
             graph.RemoveVertex(vertex);
             yield return new Command(vertex);
         }
     }
 }
 public IEnumerable<IReductionRuleCommand> Find(Graph graph)
 {
     foreach (int vertex in graph.Vertices)
     {
         // TODO: Count is not O(1)
         if (graph.Degree(vertex) == 1 && graph.Vertices.Count > 1)
         {
             BitSet connection = graph.OpenNeighborhood(vertex);
             graph.RemoveVertex(vertex);
             yield return new Command(vertex, connection);
         }
     }
 }
Esempio n. 5
0
        // 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)
        {
            Vector = vector;
            _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);
            }
        }
Esempio n. 6
0
        // This constructor returns a new bipartite graph by putting all vertices in 'left' on one side, and 'right' on the other side
        // There will be an edge between two vertices if there was an edge in the original graph
        public BipartiteGraph(Graph graph, BitSet left, BitSet right)
            : this(left, right, left.Count + right.Count)
        {
            Dictionary<int, int> mapping = new Dictionary<int, int>();
            int i = 0;

            foreach (int v in Left + Right)
                mapping[v] = i++;

            foreach (int v in Left)
                foreach (int w in graph.OpenNeighborhood(v) * Right)
                    Connect(mapping[v], mapping[w]);
        }
Esempio n. 7
0
        public Graph(Graph graph)
        {
            Vertices = graph.Vertices;

            _adjacencyMatrix = new BitSet[graph.Size];

            Size = graph.Size;

            for (int i = 0; i < Size; i++)
            {
                _adjacencyMatrix[i] = graph._adjacencyMatrix[i];
            }
        }
Esempio n. 8
0
        // Given a vertex w, we can update the dNeighborhood of a set X to reflect the dNeighborhood of the set X + w in O(n) time
        public DNeighborhood CopyAndUpdate(Graph graph, int w)
        {
            // initialize an empty dNeighborhood in O(|Vector|) time
            DNeighborhood nx = new DNeighborhood(Vector);

            // Copy all values in O(|Vector|) time
            foreach (int v in Vector)
                nx._occurrences[v] = _occurrences[v];

            // Foreach vertex in N(w) * Vector they will appear one extra time in the multiset
            // This operation take O(n) time because of the bitset operation
            foreach (int v in graph.OpenNeighborhood(w) * Vector)
                nx._occurrences[v] = Math.Min(dValue, nx._occurrences[v] + 1);

            return nx;
        }
Esempio n. 9
0
        public static IEnumerable<IReductionRuleCommand> ApplyRules(Graph graph, params IReductionRule[] rules)
        {
            bool found;
            do
            {
                found = false;

                foreach (IReductionRule rule in rules)
                {
                    foreach (IReductionRuleCommand command in rule.Find(graph))
                    {
                        found = true;
                        yield return command;
                    }
                }
            }
            while (found);
        }
Esempio n. 10
0
        // 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;
        }
Esempio n. 11
0
 public IEnumerable<IReductionRuleCommand> Find(Graph graph)
 {
     foreach (int v in graph.Vertices)
     {
         foreach (int u in graph.Vertices)
         {
             if (v == u)
             {
                 break;
             }
             // TODO: Count is not O(1)
             if (graph.Vertices.Count > 1 && ((graph.OpenNeighborhood(v) - u).Equals(graph.OpenNeighborhood(u) - v)))
             {
                 graph.RemoveVertex(v);
                 yield return new Command(v, u);
                 break;
             }
         }
     }
 }
Esempio n. 12
0
        // 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;
        }
Esempio n. 13
0
 /*************************/
 // Constructor
 /*************************/
 // Basic constructor
 public GenericSolver(Decomposition decomposition)
 {
     // The graph and binary decomposition tree that we are working on
     _graph = decomposition.Graph;
     _tree = decomposition.Tree;
 }
Esempio n. 14
0
 public static IEnumerable<BooleanChain> FromGraph(Graph graph, BitSet bitSet)
 {
     foreach (int vertex in bitSet)
     {
         yield return new BooleanChain(graph, vertex);
     }
 }
Esempio n. 15
0
 // Initial call
 public static long Compute(Graph graph)
 {
     return Compute(graph, new BitSet(0, graph.Size), graph.Vertices, new BitSet(0, graph.Size));
 }
Esempio n. 16
0
        // Parses a file of DGF format, from which we can build a graph
        public static Graph Read(TextReader reader)
        {
            string line;
            int nVertices = 0;

            // First we parse the number of vertices
            while ((line = reader.ReadLine()) != null)
            {
                // Skip everything until we find the first useful line
                if (!line.StartsWith("p ")) continue;

                // First line always reads 'p edges {n} {e}'
                string[] def = line.Split();
                nVertices = int.Parse(def[2]); // number of vertices
                break;
            }

            // Initialize the graph
            Graph graph = new Graph(nVertices);

            Dictionary<int, int> identifiers = new Dictionary<int, int>();
            int counter = 0;
            bool renamed = false;

            while ((line = reader.ReadLine()) != null)
            {
                // Skip comments
                if (line.StartsWith("c ")) continue;

                // If a line starts with an n it means we do not work with integers [1,...,n], but we use an arbitrary set of integers
                // This means we need to keep track of which edges we should create internally, since we use [0,...,n)
                if (line.StartsWith("n "))
                {
                    renamed = true;
                    string[] node = line.Split();
                    int id = int.Parse(node[1]);    // actual identifier
                    identifiers[id] = counter++;      // counter will be the internal identifier
                }

                // Parsing of the edges
                if (line.StartsWith("e "))
                {
                    string[] edge = line.Split(' ');
                    int i = int.Parse(edge[1]);
                    int j = int.Parse(edge[2]);

                    // If there were arbitrary numbers used, look them up to find what we will use internally
                    if (renamed)
                    {
                        i = identifiers[i];
                        j = identifiers[j];
                    }
                    // If no other identifiers are given, we have only have to an element
                    // DGF files use the range [1...n], while internally we use [0...n), thus a simple minus 1 will suffice
                    else
                    {
                        i--;
                        j--;
                    }

                    // Create the edge
                    graph.Connect(i, j);
                }
            }

            return graph;
        }
Esempio n. 17
0
 public BooleanChain(Graph graph, int vertex)
 {
     this.Graph = graph;
     this.Vertex = vertex;
     this.CalculateBooleanWidth();
 }