Esempio n. 1
0
        /// <summary>
        /// Finds all pairs of blocks with non-empty intersection and merges them. Iterated until no overlapping pairs remain.
        /// </summary>
        /// <param name="semipartition">The semipartition to be processed.</param>
        /// <returns>The resulting partition.</returns>
        public static Partition <T> MergeOverlappingBlocks(Semipartition <T> semipartition)
        {
            HashSet <HashSet <T> > blocks = new HashSet <HashSet <T> >();

            foreach (HashSet <T> block in semipartition.blocks)
            {
                HashSet <T> newBlock = new HashSet <T>();
                foreach (T element in block)
                {
                    newBlock.Add(element);
                }
                blocks.Add(newBlock);
            }

            int      N             = semipartition.blocks.Count;
            int      newIndexStart = N;
            List <T> inoverlaps    = new List <T>();

            for (int i = 0; i < N; i++)
            {
                for (int j = i + 1; j < N; j++)
                {
                    if (blocks.ElementAt(i).Overlaps(blocks.ElementAt(j)))
                    {
                        HashSet <T> newBlock = new HashSet <T>();
                        newBlock.UnionWith(blocks.ElementAt(i));
                        newBlock.UnionWith(blocks.ElementAt(j));
                        foreach (T element in newBlock)
                        {
                            if (!inoverlaps.Contains(element))
                            {
                                inoverlaps.Add(element);
                            }
                        }
                        // remove the higher-number block first
                        blocks.Remove(blocks.ElementAt(j));
                        blocks.Remove(blocks.ElementAt(i));
                        blocks.Add(newBlock);
                        // i stays the same (but is decremented here to do so), N is decremented by 1
                        N--;
                        i--;
                        break;
                    }
                }
            }

            Partition <T> partition = new Partition <T>();

            foreach (HashSet <T> block in blocks)
            {
                partition.AddBlock(block);
            }

            return(partition);
        }
Esempio n. 2
0
        /// <summary>
        /// Places the union of all the blocks in the argument into a single block. Removes all the initial blocks,
        /// retaining only the merged block.
        /// </summary>
        /// <param name="semipartition">The semipartition to be processed.</param>
        public static void MergeAllBlocks(Semipartition <T> semipartition)
        {
            semipartition.assignments = new Dictionary <T, List <HashSet <T> > >();
            semipartition.blocks      = new HashSet <HashSet <T> >();
            HashSet <T> block = new HashSet <T>();

            foreach (T element in semipartition.elements)
            {
                block.Add(element);
                semipartition.assignments.Add(element, new List <HashSet <T> >()
                {
                    block
                });
            }
            semipartition.blocks.Add(block);
        }
Esempio n. 3
0
        /// <summary>
        /// Finds the nonoverlapping blocks and places them into a partition
        /// places the remaining overlapping blocks into a semipartition
        /// </summary>
        /// <param name="semipartition">The semipartition to be processed.</param>
        /// <returns>A tuple containing a semipartition and a partition. The two have no elements in common, and
        /// every element in the original semipartition is in one or the other item of the tuple.</returns>
        public static Tuple <Semipartition <T>, Partition <T> > Decompose(Semipartition <T> semipartition)
        {
            Semipartition <T> newSemipartition = new Semipartition <T>();
            Partition <T>     partition        = new Partition <T>();

            List <HashSet <T> > overlaps = new List <HashSet <T> >();

            foreach (HashSet <T> block1 in semipartition.blocks)
            {
                foreach (HashSet <T> block2 in semipartition.blocks)
                {
                    if (block1 == block2)
                    {
                        break;
                    }

                    if (block2.Overlaps(block1))
                    {
                        if (!overlaps.Contains(block1))
                        {
                            overlaps.Add(block1);
                        }

                        if (!overlaps.Contains(block2))
                        {
                            overlaps.Add(block2);
                        }
                    }
                }
            }

            foreach (HashSet <T> block in semipartition.blocks)
            {
                if (overlaps.Contains(block))
                {
                    newSemipartition.AddBlock(block);
                }
                else
                {
                    partition.AddBlock(block);
                }
            }

            return(new Tuple <Semipartition <T>, Partition <T> >(newSemipartition, partition));
        }
Esempio n. 4
0
        /// <summary>
        /// Checks to see if any pair of blocks has non-null intersection.
        /// </summary>
        /// <param name="semipartition">The semipartition to be examined.</param>
        /// <returns>True if any pair of blocks has non-null intersection. False otherwise.</returns>
        public static bool ContainsOverlappingBlocks(Semipartition <T> semipartition)
        {
            foreach (HashSet <T> block1 in semipartition)
            {
                foreach (HashSet <T> block2 in semipartition)
                {
                    if (block1 == block2)
                    {
                        break;
                    }

                    if (block1.Overlaps(block2))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Esempio n. 5
0
        /// <summary>
        /// Removes from the partition any blocks completely contained within another block.
        /// </summary>
        /// <param name="semipartition">The semipartition to process.</param>
        public static void PurgeSubblocks(Semipartition <T> semipartition)
        {
            List <HashSet <T> > toRemove = new List <HashSet <T> >();

            foreach (HashSet <T> block1 in semipartition.blocks)
            {
                foreach (HashSet <T> block2 in semipartition.blocks)
                {
                    if (block1 == block2)
                    {
                        continue;
                    }

                    if (block1.IsSubsetOf(block2))
                    {
                        if (!toRemove.Contains(block1) && !toRemove.Contains(block2))
                        {
                            toRemove.Add(block1);
                        }
                        break;
                    }
                }
            }

            foreach (HashSet <T> block in toRemove)
            {
                foreach (T element in block)
                {
                    if (semipartition.assignments[element].Contains(block))
                    {
                        semipartition.assignments[element].Remove(block);
                    }
                }
                semipartition.blocks.Remove(block);
            }
        }