コード例 #1
0
        /// <summary>
        /// Factoriza o polinómio aplicando os métodos conhecidos.
        /// </summary>
        /// <param name="polynomial">O polinómio a ser factorizado.</param>
        /// <param name="primeNumber">O número primo.</param>
        /// <param name="bound">O limite dos coeficientes que podem representar números inteiros.</param>
        /// <param name="iterationsNumber">O número de iterações para o algoritmo do levantamento multifactor.</param>
        /// <param name="factorsList">A lista de factores.</param>
        /// <returns>O coeficiente independente.</returns>
        private CoeffType FactorizePolynomial(
            UnivariatePolynomialNormalForm <CoeffType> polynomial,
            CoeffType primeNumber,
            CoeffType bound,
            int iterationsNumber,
            List <UnivariatePolynomialNormalForm <CoeffType> > factorsList)
        {
            var modularField       = this.modularSymmetricFactory.CreateInstance(primeNumber);
            var linearSystemSolver = new DenseCondensationLinSysAlgorithm <CoeffType>(
                modularField);
            var finiteFieldFactAlg = new FiniteFieldPolFactorizationAlgorithm <CoeffType>(
                linearSystemSolver,
                this.integerNumber);
            var finiteFieldFactorizationResult = finiteFieldFactAlg.Run(
                polynomial,
                modularField);
            var multiFactorLiftingStatus = new MultiFactorLiftingStatus <CoeffType>(
                polynomial,
                finiteFieldFactorizationResult,
                primeNumber);
            var multiFactorLiftingResult = this.multiFactorLiftingAlg.Run(
                multiFactorLiftingStatus,
                iterationsNumber);
            var searchResult = this.searchFactorizationAlgorithm.Run(
                multiFactorLiftingResult,
                bound,
                3);

            if (searchResult.IntegerFactors.Count > 0)
            {
                factorsList.AddRange(searchResult.IntegerFactors);
                if (searchResult.NonIntegerFactors.Count > 0) // É necessário factorizar.
                {
                    var currentFactor = searchResult.IntegerFactors[0];
                    for (int i = 1; i < searchResult.IntegerFactors.Count; ++i)
                    {
                        currentFactor = currentFactor.Multiply(
                            searchResult.IntegerFactors[i],
                            this.integerNumber);
                    }

                    var nonFactored = MathFunctions.GetIntegerDivision(
                        searchResult.MainPolynomial,
                        currentFactor,
                        this.integerNumber);
                }
            }
            else
            {
            }

            throw new NotImplementedException();
        }
コード例 #2
0
        /// <summary>
        /// Aplica o algoritmo um número especificado de vezes ou até ser encontrada uma factorização.
        /// </summary>
        /// <param name="multiFactorLiftingStatus">O estado do levantamento multifactor actual.</param>
        /// <param name="numberOfIterations">O número de iterações a ser efectuado.</param>
        /// <returns>A lista com os factores.</returns>
        public MultiFactorLiftingResult <CoeffType> Run(
            MultiFactorLiftingStatus <CoeffType> multiFactorLiftingStatus,
            int numberOfIterations)
        {
            if (multiFactorLiftingStatus.Factorization.Factors.Count > 1)
            {
                var modularField = this.linearLiftAlg.ModularFieldFactory.CreateInstance(
                    multiFactorLiftingStatus.LiftedFactorizationModule);
                var factorTree = this.MountFactorTree(
                    multiFactorLiftingStatus,
                    modularField);
                factorTree.RootNode.NodeObject.Polynom = multiFactorLiftingStatus.Polynom;
                if (factorTree == null)
                {
                    // Não existem factores suficientes para elevar
                    var result = new List <UnivariatePolynomialNormalForm <CoeffType> >();
                    result.AddRange(multiFactorLiftingStatus.Factorization.Factors);
                    return(new MultiFactorLiftingResult <CoeffType>(
                               multiFactorLiftingStatus.Polynom,
                               result,
                               multiFactorLiftingStatus.LiftedFactorizationModule));
                }
                else
                {
                    // A árvore contém factores para elevar
                    var factorQueue        = new Queue <TreeNode <LinearLiftingStatus <CoeffType> > >();
                    var factorTreeRootNode = factorTree.RootNode.NodeObject.Polynom;

                    factorQueue.Enqueue(factorTree.InternalRootNode);
                    while (factorQueue.Count > 0)
                    {
                        var dequeued = factorQueue.Dequeue();
                        if (dequeued.Count == 2)
                        {
                            this.linearLiftAlg.Run(dequeued.NodeObject, numberOfIterations);
                            if (this.linearLiftAlg.IntegerNumber.Compare(
                                    multiFactorLiftingStatus.LiftedFactorizationModule,
                                    dequeued.NodeObject.LiftedFactorizationModule) < 0)
                            {
                                multiFactorLiftingStatus.LiftedFactorizationModule = dequeued.NodeObject.LiftedFactorizationModule;
                            }

                            var firstChild  = dequeued.ChildsList[0];
                            var secondChild = dequeued.ChildsList[1];
                            firstChild.NodeObject.Polynom  = dequeued.NodeObject.UFactor;
                            secondChild.NodeObject.Polynom = dequeued.NodeObject.WFactor;
                            factorQueue.Enqueue(firstChild);
                            factorQueue.Enqueue(secondChild);
                        }
                    }

                    var treeSolution = this.GetSolutionFromTree(factorTree, this.linearLiftAlg.IntegerNumber);

                    return(new MultiFactorLiftingResult <CoeffType>(
                               factorTreeRootNode,
                               treeSolution,
                               multiFactorLiftingStatus.LiftedFactorizationModule));
                }
            }
            else
            {
                return(new MultiFactorLiftingResult <CoeffType>(
                           multiFactorLiftingStatus.Polynom,
                           multiFactorLiftingStatus.Factorization.Factors,
                           multiFactorLiftingStatus.LiftedFactorizationModule));
            }
        }
コード例 #3
0
        /// <summary>
        /// Contrói a árvore de factores.
        /// </summary>
        /// <param name="multiFactorLiftingStatus">Contém a factorização que se pretende elevar.</param>
        /// <param name="modularField">O corpo modular sobre o qual são efectuadas as operações.</param>
        /// <returns>A árvore.</returns>
        private Tree <LinearLiftingStatus <CoeffType> > MountFactorTree(
            MultiFactorLiftingStatus <CoeffType> multiFactorLiftingStatus,
            IModularField <CoeffType> modularField)
        {
            var tree             = new Tree <LinearLiftingStatus <CoeffType> >();
            var currentNodes     = new List <TreeNode <LinearLiftingStatus <CoeffType> > >();
            var factorEnumerator = multiFactorLiftingStatus.Factorization.Factors.GetEnumerator();

            if (factorEnumerator.MoveNext())
            {
                var factor = factorEnumerator.Current;
                if (!modularField.IsMultiplicativeUnity(multiFactorLiftingStatus.Factorization.IndependentCoeff))
                {
                    factor = factor.Multiply(multiFactorLiftingStatus.Factorization.IndependentCoeff, modularField);
                }

                currentNodes.Add(new TreeNode <LinearLiftingStatus <CoeffType> >(
                                     new LinearLiftingStatus <CoeffType>(factor, modularField.Module),
                                     tree,
                                     null));

                while (factorEnumerator.MoveNext())
                {
                    factor = factorEnumerator.Current;
                    currentNodes.Add(new TreeNode <LinearLiftingStatus <CoeffType> >(
                                         new LinearLiftingStatus <CoeffType>(factor, modularField.Module),
                                         tree,
                                         null));
                }
            }

            if (currentNodes.Count < 2)
            {
                return(null);
            }
            else
            {
                var temporaryNodes = new List <TreeNode <LinearLiftingStatus <CoeffType> > >();
                var count          = 0;
                while (currentNodes.Count > 1)
                {
                    temporaryNodes.Clear();
                    var i = 0;
                    while (i < currentNodes.Count)
                    {
                        var parentNode = default(TreeNode <LinearLiftingStatus <CoeffType> >);
                        var first      = currentNodes[i];
                        ++i;
                        if (i < currentNodes.Count)
                        {
                            var second  = currentNodes[i];
                            var product = first.NodeObject.Polynom.Multiply(
                                second.NodeObject.Polynom,
                                modularField);

                            var liftingStatus = new LinearLiftingStatus <CoeffType>(
                                product,
                                first.NodeObject.Polynom,
                                second.NodeObject.Polynom,
                                modularField.Module);

                            parentNode = new TreeNode <LinearLiftingStatus <CoeffType> >(
                                liftingStatus,
                                tree,
                                null);

                            first.InternalParent  = parentNode;
                            second.InternalParent = parentNode;
                            parentNode.Add(first);
                            parentNode.Add(second);
                            ++i;
                        }
                        else
                        {
                            parentNode = first;
                        }

                        temporaryNodes.Add(parentNode);
                    }

                    var swap = currentNodes;
                    currentNodes   = temporaryNodes;
                    temporaryNodes = swap;
                    ++count;
                }

                var lastNode = currentNodes[0];
                tree.InternalRootNode = lastNode;
                return(tree);
            }
        }