예제 #1
0
        public void NumberOfElementsTest()
        {
            Partition p = new Partition();

            p.AddCell(0, 1);
            p.AddCell(2, 3);
            Assert.AreEqual(4, p.NumberOfElements());
        }
예제 #2
0
        public void SizeTest()
        {
            Partition p = new Partition();

            p.AddCell(0, 1);
            p.AddCell(2, 3);
            Assert.AreEqual(2, p.Count);
            Assert.AreEqual(2, p.GetCell(0).Count);
            Assert.AreEqual(2, p.GetCell(1).Count);
        }
예제 #3
0
        public void CopyConstructor()
        {
            Partition p = new Partition();

            p.AddCell(0, 1);
            p.AddCell(2, 3);
            Partition q = new Partition(p);

            Assert.IsTrue(Compares.AreDeepEqual(p, q));
        }
예제 #4
0
        public void AddCell_VarArgsTest()
        {
            Partition p = new Partition();

            p.AddCell(0, 1, 2);
            Assert.AreEqual(1, p.Count);
            Assert.AreEqual(3, p.NumberOfElements());
        }
예제 #5
0
        public void AddCell_CollectionTest()
        {
            Partition  p    = new Partition();
            List <int> cell = new List <int>();

            cell.Add(0);
            cell.Add(1);
            cell.Add(2);
            p.AddCell(cell);
            Assert.AreEqual(1, p.Count);
            Assert.AreEqual(3, p.NumberOfElements());
        }
예제 #6
0
        /// <summary>
        /// Splits this partition by taking the cell at cellIndex and making two
        /// new cells - the first with the rest of the elements from that cell
        /// and the second with the singleton splitElement.
        /// </summary>
        /// <param name="cellIndex">the index of the cell to split on</param>
        /// <param name="splitElement">the element to put in its own cell</param>
        /// <returns>a new (finer) Partition</returns>
        public Partition SplitAfter(int cellIndex, int splitElement)
        {
            Partition r = new Partition();

            // copy the blocks up to blockIndex
            for (int j = 0; j < cellIndex; j++)
            {
                r.AddCell(this.CopyBlock(j));
            }

            // split the block at block index
            SortedSet <int> splitBlock = this.CopyBlock(cellIndex);

            splitBlock.Remove(splitElement);
            r.AddCell(splitBlock);
            r.AddSingletonCell(splitElement);

            // copy the blocks after blockIndex, shuffled up by one
            for (int j = cellIndex + 1; j < this.Count; j++)
            {
                r.AddCell(this.CopyBlock(j));
            }
            return(r);
        }
        /// <summary>
        /// The automorphism partition is a partition of the elements of the group.
        ///
        /// <returns>a partition of the elements of group</returns>
        /// </summary>
        public Partition GetAutomorphismPartition()
        {
            int n = group.Count;
            DisjointSetForest forest = new DisjointSetForest(n);

            group.Apply(new AutomorphismPartitionBacktracker(n, forest));

            // convert to a partition
            Partition partition = new Partition();

            foreach (var set in forest.GetSets())
            {
                partition.AddCell(set);
            }

            // necessary for comparison by string
            partition.Order();
            return(partition);
        }
예제 #8
0
        /// <summary>
        /// Get the element partition from an atom container, which is simply a list
        /// of sets of atom indices where all atoms in one set have the same element
        /// symbol.
        ///
        /// So for atoms [C0, N1, C2, P3, C4, N5] the partition would be
        /// [{0, 2, 4}, {1, 5}, {3}] with cells for elements C, N, and P.
        /// </summary>
        /// <returns>a partition of the atom indices based on the element symbols</returns>
        public virtual Partition GetInitialPartition()
        {
            if (ignoreElements)
            {
                int n = atomContainer.Atoms.Count;
                return(Partition.Unit(n));
            }

            var cellMap       = new Dictionary <string, SortedSet <int> >();
            int numberOfAtoms = atomContainer.Atoms.Count;

            for (int atomIndex = 0; atomIndex < numberOfAtoms; atomIndex++)
            {
                string          symbol = atomContainer.Atoms[atomIndex].Symbol;
                SortedSet <int> cell;
                if (cellMap.ContainsKey(symbol))
                {
                    cell = cellMap[symbol];
                }
                else
                {
                    cell            = new SortedSet <int>();
                    cellMap[symbol] = cell;
                }
                cell.Add(atomIndex);
            }

            var atomSymbols = new List <string>(cellMap.Keys);

            atomSymbols.Sort();

            var elementPartition = new Partition();

            foreach (string key in atomSymbols)
            {
                var cell = cellMap[key];
                elementPartition.AddCell(cell);
            }

            return(elementPartition);
        }
예제 #9
0
        /// <summary>
        /// Get the bond partition, based on the element types of the atoms at either end
        /// of the bond, and the bond order.
        /// </summary>
        /// <returns>a partition of the bonds based on the element types and bond order</returns>
        public Partition GetInitialPartition()
        {
            var bondCount = atomContainer.Bonds.Count;
            var cellMap   = new Dictionary <string, SortedSet <int> >();

            // make mini-'descriptors' for bonds like "C=O" or "C#N" etc
            for (int bondIndex = 0; bondIndex < bondCount; bondIndex++)
            {
                var    bond = atomContainer.Bonds[bondIndex];
                var    el0  = bond.Atoms[0].Symbol;
                var    el1  = bond.Atoms[1].Symbol;
                string boS;
                if (ignoreBondOrders)
                {
                    // doesn't matter what it is, so long as it's constant
                    boS = "1";
                }
                else
                {
                    var isArom      = bond.IsAromatic;
                    var orderNumber = isArom ? 5 : bond.Order.Numeric();
                    boS = orderNumber.ToString(NumberFormatInfo.InvariantInfo);
                }
                string bondString;
                if (string.CompareOrdinal(el0, el1) < 0)
                {
                    bondString = el0 + boS + el1;
                }
                else
                {
                    bondString = el1 + boS + el0;
                }
                SortedSet <int> cell;
                if (cellMap.ContainsKey(bondString))
                {
                    cell = cellMap[bondString];
                }
                else
                {
                    cell = new SortedSet <int>();
                    cellMap[bondString] = cell;
                }
                cell.Add(bondIndex);
            }

            // sorting is necessary to get cells in order
            var bondStrings = new List <string>(cellMap.Keys);

            bondStrings.Sort();

            // the partition of the bonds by these 'descriptors'
            var bondPartition = new Partition();

            foreach (string key in bondStrings)
            {
                var cell = cellMap[key];
                bondPartition.AddCell(cell);
            }
            bondPartition.Order();
            return(bondPartition);
        }
예제 #10
0
        /// <summary>
        /// Parse a string like "[0,2|1,3]" to form the partition; cells are
        /// separated by '|' characters and elements within the cell by commas.
        /// </summary>
        /// <param name="strForm">the partition in string form</param>
        /// <returns>the partition corresponding to the string</returns>
        /// <exception cref="ArgumentException">thrown if the provided strFrom is null or empty</exception>
        public static Partition FromString(string strForm)
        {
            if (strForm == null || strForm.Length == 0)
            {
                throw new ArgumentException("null or empty string provided");
            }

            Partition p     = new Partition();
            int       index = 0;

            if (strForm[0] == '[')
            {
                index++;
            }
            int endIndex;

            if (strForm[strForm.Length - 1] == ']')
            {
                endIndex = strForm.Length - 2;
            }
            else
            {
                endIndex = strForm.Length - 1;
            }
            int currentCell = -1;
            int numStart    = -1;

            while (index <= endIndex)
            {
                char c = strForm[index];
                if (char.IsDigit(c))
                {
                    if (numStart == -1)
                    {
                        numStart = index;
                    }
                }
                else if (c == ',')
                {
                    int element = int.Parse(strForm.Substring(numStart, index - numStart), NumberFormatInfo.InvariantInfo);
                    if (currentCell == -1)
                    {
                        p.AddCell(element);
                        currentCell = 0;
                    }
                    else
                    {
                        p.AddToCell(currentCell, element);
                    }
                    numStart = -1;
                }
                else if (c == '|')
                {
                    int element = int.Parse(strForm.Substring(numStart, index - numStart), NumberFormatInfo.InvariantInfo);
                    if (currentCell == -1)
                    {
                        p.AddCell(element);
                        currentCell = 0;
                    }
                    else
                    {
                        p.AddToCell(currentCell, element);
                    }
                    currentCell++;
                    p.AddCell();
                    numStart = -1;
                }
                index++;
            }
            int lastElement = int.Parse(strForm.Substring(numStart, endIndex + 1 - numStart), NumberFormatInfo.InvariantInfo);

            p.AddToCell(currentCell, lastElement);
            return(p);
        }