Пример #1
0
        public void ChangeBaseTest()
        {
            int size = 4;
            PermutationGroup group = new PermutationGroup(size);

            group.Enter(new Permutation(1, 0, 3, 2));
            group.ChangeBase(new Permutation(size));
            Assert.AreEqual(2, group.Order());
        }
        /// <summary>
        /// Does the work of the class, that refines a coarse partition into a finer
        /// one using the supplied automorphism group to prune the search.
        /// </summary>
        /// <param name="group">the automorphism group of the graph</param>
        /// <param name="coarser">the partition to refine</param>
        private void Refine(PermutationGroup group, Partition coarser)
        {
            int vertexCount = GetVertexCount();

            Partition finer = equitableRefiner.Refine(coarser);

            int firstNonDiscreteCell = finer.GetIndexOfFirstNonDiscreteCell();

            if (firstNonDiscreteCell == -1)
            {
                firstNonDiscreteCell = vertexCount;
            }

            Permutation pi1 = new Permutation(firstNonDiscreteCell);

            Result result = Result.Better;

            if (bestExist)
            {
                pi1    = finer.SetAsPermutation(firstNonDiscreteCell);
                result = CompareRowwise(pi1);
            }

            // partition is discrete
            if (finer.Count == vertexCount)
            {
                if (!bestExist)
                {
                    best      = finer.ToPermutation();
                    first     = finer.ToPermutation();
                    bestExist = true;
                }
                else
                {
                    if (result == Result.Better)
                    {
                        best = new Permutation(pi1);
                    }
                    else if (result == Result.Equal)
                    {
                        group.Enter(pi1.Multiply(best.Invert()));
                    }
                }
            }
            else
            {
                if (result != Result.Worse)
                {
                    var blockCopy = finer.CopyBlock(firstNonDiscreteCell);
                    for (int vertexInBlock = 0; vertexInBlock < vertexCount; vertexInBlock++)
                    {
                        if (blockCopy.Contains(vertexInBlock))
                        {
                            Partition nextPartition = finer.SplitBefore(firstNonDiscreteCell, vertexInBlock);

                            this.Refine(group, nextPartition);

                            int[] permF = new int[vertexCount];
                            int[] invF  = new int[vertexCount];
                            for (int i = 0; i < vertexCount; i++)
                            {
                                permF[i] = i;
                                invF[i]  = i;
                            }

                            for (int j = 0; j <= firstNonDiscreteCell; j++)
                            {
                                int x = nextPartition.GetFirstInCell(j);
                                int i = invF[x];
                                int h = permF[j];
                                permF[j] = x;
                                permF[i] = h;
                                invF[h]  = i;
                                invF[x]  = j;
                            }
                            Permutation pPermF = new Permutation(permF);
                            group.ChangeBase(pPermF);
                            for (int j = 0; j < vertexCount; j++)
                            {
                                Permutation g = group[firstNonDiscreteCell, j];
                                if (g != null)
                                {
                                    blockCopy.Remove(g[vertexInBlock]);
                                }
                            }
                        }
                    }
                }
            }
        }