예제 #1
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            int firstArgument = (OpCode != OpCode.NewObj && !Method.IsStatic) ? 1 : 0;

            Debug.Assert(Method.Parameters.Count + firstArgument == Arguments.Count);
            Debug.Assert(Method.Parameters.Count + firstArgument == ArgumentToParameterMap.Length);
            if (firstArgument == 1)
            {
                Debug.Assert(Arguments[0].ResultType == ExpectedTypeForThisPointer(ConstrainedTo ?? Method.DeclaringType),
                             $"Stack type mismatch in 'this' argument in call to {Method.Name}()");
                Debug.Assert(ArgumentToParameterMap[0] == -1, "'this' argument must always be mapped at position 0");
            }
            int paramCount = Method.Parameters.Count;

            if (paramCount > 0)
            {
                BitSet bitSet = new BitSet(paramCount);
                for (int i = 0; i < paramCount; ++i)
                {
                    int mappedTo = ArgumentToParameterMap[firstArgument + i];
                    Debug.Assert(mappedTo >= 0 && mappedTo < paramCount, $"mapping out of [0..{paramCount}[, was: {mappedTo}");
                    Debug.Assert(!bitSet[mappedTo], $"argument {mappedTo} is already mapped to a different parameter");
                    bitSet.Set(mappedTo);
                    Debug.Assert(Arguments[firstArgument + i].ResultType == Method.Parameters[mappedTo].Type.GetStackType(),
                                 $"Stack type mismatch in parameter {mappedTo} (argument {firstArgument + i}) in call to {Method.Name}()");
                }
                Debug.Assert(bitSet.All(0, paramCount - 1), "Not all arguments are mapped to a parameter");
            }
        }
예제 #2
0
        public void AllInRange()
        {
            var bitset = new BitSet(300);

            bitset.Set(1, 299);
            Assert.IsTrue(bitset.All(1, 299));
            Assert.IsTrue(bitset.All(10, 290));
            Assert.IsTrue(bitset.All(100, 200));
            Assert.IsFalse(bitset.All(0, 200));
            Assert.IsFalse(bitset.All(0, 1));
            Assert.IsFalse(bitset.All(1, 300));
            bitset[200] = false;
            Assert.IsFalse(bitset.All(1, 299));
        }
예제 #3
0
        /// <summary>
        /// Tests if the graph can be separated with a safe separator of size 2. If so, the separator is saved in the "separator" member variable
        /// </summary>
        /// <returns>true iff a size 2 separator exists</returns>
        public bool FindSize2Separator()
        {
            BitSet notIgnoredVertices = BitSet.All(graph.vertexCount);

            // loop over every pair of vertices
            for (int u = 0; u < graph.vertexCount; u++)
            {
                notIgnoredVertices[u] = false;
                foreach (int a in ArticulationPoints(graph, notIgnoredVertices))
                {
                    separator     = new BitSet(graph.vertexCount);
                    separator[u]  = true;
                    separator[a]  = true;
                    separatorType = SeparatorType.Size2;
                    return(true);
                }
                notIgnoredVertices[u] = true;
            }
            return(false);
        }
예제 #4
0
        /// <summary>
        /// lists all articulation points of the graph
        /// This method can also be used to test for separators of size n by passing a set of n-1 vertices as
        /// ignoredVertices. and combining the result with the ignoredVertices.
        /// Code adapated from https://slideplayer.com/slide/12811727/
        /// </summary>
        /// <param name="availableVertices">a list of vertices to treat as existent</param>
        /// <returns>an iterator over all articulation points</returns>
        public static IEnumerable <int> ArticulationPoints(Graph graph, BitSet availableVertices = null)
        {
            if (graph.vertexCount == 0) // exit early if there are no vertices
            {
                yield break;
            }

            availableVertices = availableVertices ?? BitSet.All(graph.vertexCount);   // create an empty list if the given one is null in order to prevent NullReferenceExceptions

            int start = availableVertices.First();

            int[]         count     = new int[graph.vertexCount];          // TODO: make member variable
            int[]         reachBack = new int[graph.vertexCount];          // TODO: make member variable
            Queue <int>[] children  = new Queue <int> [graph.vertexCount]; // TODO: make member variable
            for (int i = 0; i < graph.vertexCount; i++)
            {
                count[i]     = int.MaxValue;
                reachBack[i] = int.MaxValue;
                children[i]  = new Queue <int>();
            }
            count[start] = 0;
            int numSubtrees = 0;

            for (int i = 0; i < graph.adjacencyList[start].Count; i++)
            {
                int rootNeighbor = graph.adjacencyList[start][i];
                if (count[rootNeighbor] == int.MaxValue && availableVertices[rootNeighbor])
                {
                    Stack <(int, int, int)> stack = new Stack <(int, int, int)>();
                    stack.Push((rootNeighbor, 1, start));
                    while (stack.Count > 0)
                    {
                        (int node, int timer, int fromNode) = stack.Peek();
                        if (count[node] == int.MaxValue)
                        {
                            count[node]     = timer;
                            reachBack[node] = timer;

                            List <int> neighbors = graph.adjacencyList[node];
                            for (int j = 0; j < neighbors.Count; j++)
                            {
                                int neighbor = neighbors[j];
                                if (neighbor != fromNode && availableVertices[neighbor])
                                {
                                    children[node].Enqueue(neighbor);
                                }
                            }
                        }
                        else if (children[node].Count > 0)
                        {
                            int child = children[node].Dequeue();
                            if (count[child] < int.MaxValue)
                            {
                                if (reachBack[node] > count[child])
                                {
                                    reachBack[node] = count[child];
                                }
                            }
                            else
                            {
                                stack.Push((child, timer + 1, node));
                            }
                        }
                        else
                        {
                            if (node != rootNeighbor)
                            {
                                if (reachBack[node] >= count[fromNode])
                                {
                                    yield return(fromNode);
                                }
                                if (reachBack[fromNode] > reachBack[node])
                                {
                                    reachBack[fromNode] = reachBack[node];
                                }
                            }
                            stack.Pop();
                        }
                    }

                    numSubtrees++;
                }
            }
            if (numSubtrees > 1)
            {
                yield return(start);
            }
        }
예제 #5
0
        /// <summary>
        /// finds candidate safe separators using a heuristic. This is Tamaki's code.
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static List <BitSet> Tamaki_HeuristicVerticesAndNeighbors(Graph graph, Heuristic mode)
        {
            // code adapted from https://github.com/TCS-Meiji/PACE2017-TrackA/blob/master/tw/exact/GreedyDecomposer.java

            List <BitSet> separators = new List <BitSet>();

            // ----- lines 62 to 64 -----

            // copy fields so that we can change them locally
            Graph copy = new Graph(graph);

            List <BitSet> frontier  = new List <BitSet>();
            BitSet        remaining = BitSet.All(graph.vertexCount);

            // ----- lines 66 to 80 -----

            while (!remaining.IsEmpty())
            {
                // ----- lines 67 to 80 -----

                int vmin = FindMinCostVertex(remaining, copy, mode);

                // ----- line 82 -----

                List <BitSet> joined = new List <BitSet>();

                // lines 84 and 85 -----

                BitSet toBeAclique = new BitSet(graph.vertexCount);
                toBeAclique[vmin] = true;

                // ----- lines 87 to 93 -----

                foreach (BitSet s in frontier)
                {
                    if (s[vmin])
                    {
                        joined.Add(s);
                        toBeAclique.UnionWith(s);
                    }
                }

                // ----- lines 97 to 119 -----

                if (joined.Count == 0)
                {
                    toBeAclique[vmin] = true;
                }
                else if (joined.Count == 1)
                {
                    BitSet uniqueSeparator = joined[0];
                    BitSet test            = new BitSet(copy.openNeighborhood[vmin]);
                    test.IntersectWith(remaining);
                    if (uniqueSeparator.IsSupersetOf(test))
                    {
                        uniqueSeparator[vmin] = false;
                        if (uniqueSeparator.IsEmpty())
                        {
                            separators.Remove(uniqueSeparator);

                            frontier.Remove(uniqueSeparator);
                        }
                        remaining[vmin] = false;
                        continue;
                    }
                }

                // ----- line 121 -----

                BitSet temp = new BitSet(copy.openNeighborhood[vmin]);
                temp.IntersectWith(remaining);
                toBeAclique.UnionWith(temp);

                // ----- line 129 -----

                copy.MakeIntoClique(toBeAclique.Elements());

                // ----- lines 131 and 132 -----
                BitSet sep = new BitSet(toBeAclique);
                sep[vmin] = false;

                // ----- lines 134 to 147 -----

                if (!sep.IsEmpty())
                {
                    BitSet separator = new BitSet(sep);
                    separators.Add(separator);

                    frontier.Add(separator);
                }

                // ----- lines 153 to 161 -----
                foreach (BitSet s in joined)
                {
                    Debug.Assert(!s.IsEmpty());

                    frontier.Remove(s);
                }
                remaining[vmin] = false;
            }

            return(separators);
        }