Java 二次筛萃取阶段最有效的分解算法是什么?

Java 二次筛萃取阶段最有效的分解算法是什么?,java,algorithm,factorization,Java,Algorithm,Factorization,在二次筛选算法中,在使用对数近似法找到B平滑值后,需要对数字进行因子化,我们称之为B,以构造B平滑向量 一个常见的解决方案是使用因子库中的素数进行试除法。与随机数不同,在这种情况下,试验除法是超级有效的,因为大多数因素都在素数基中。我之所以说“大多数”,是因为一个常见的优化将允许一个小的阈值包含1-3个prim,其乘积高达2^30左右,这称为部分关系 在我的示例中,这个向量提取阶段占用了大部分时间。我一直在尝试的另一个解决方案是接收,再次遍历素数基,并记录索引中的向量,已知为b-平滑,但这变得更

在二次筛选算法中,在使用对数近似法找到B平滑值后,需要对数字进行因子化,我们称之为
B
,以构造B平滑向量

一个常见的解决方案是使用因子库中的素数进行试除法。与随机数不同,在这种情况下,试验除法是超级有效的,因为大多数因素都在素数基中。我之所以说“大多数”,是因为一个常见的优化将允许一个小的阈值包含1-3个prim,其乘积高达2^30左右,这称为部分关系

在我的示例中,这个向量提取阶段占用了大部分时间。我一直在尝试的另一个解决方案是接收,再次遍历素数基,并记录索引中的向量,已知为b-平滑,但这变得更慢

下面是我当前的代码,我为试用版添加了4个优化,请告诉我是否有更好的解决方案

  • 对于素数2,我检查
    B
    的最后一个设置位,然后右移以提取它
  • 我使用的是BigInteger
    divideandMainder
    它通过将除法和mod操作组合成1来优化内存和性能
  • 如果
    B
    小于因子库中的最大素数,那么它必须在因子库中,因此我使用哈希映射来定位它的索引
  • 如果在
    B.bitLenght()/2
    之前没有素数除以
    B
    ,那么它必须是一个偏关系,只有当它是素数时,我才会包含它
  • private VectorData extractVector(BigInteger值){
    比特集向量=新比特集(PrimeBase.instance.PrimeBase.size());
    if(value.compareTo(BigInteger.ZERO)<0){
    向量集(0);
    value=value.abs();
    }
    值=提取功率2(值,向量);
    对于(int i=2;i}else if(value.compareTo(PrimeBase.instance.maxPrimeBigInteger)通过将试用除法切换为接收除法,我能够实现近80%的性能提升。现在,我在问题中已经提到,我以前尝试过,但没有成功。嗯,这次成功了

    我用整数运算替换了
    biginger.mod(x).equals(ZERO)
    测试
    (bSmoothData.localX-delta)%prime==startingPosition
    ,它可能非常特定于我的实现,但其思想是检查prime是否应该在筛选数组中分割bSmooth索引


    接下来,我构造了一个所有这些素数的乘积,并将实际的bSmooth值除以它,然后我留下了一个提示,它可以被转换为Java long。我继续使用试用除法提取它。如果你对我的实现感兴趣,我制作了一个关于它的视频。

    维基百科建议使用另一种在smo上运行良好的分解算法其他数字一旦最小的素数被试用除法消除:@DavidEisenstat这将是我的最后一个else if案例,这是非常罕见的。我认为wiki只提供了一个高层次的概述,他们不太谈论优化。想法是在你达到像P这样的平滑度之前从试用除法中切换过来ollard的rho。我不确定java中有什么可用的,但是,我确实知道,一般来说,精确除法可能很昂贵。例如,在
    C
    gmp
    中,有一个名为
    mpz\u divisible\u ui\p
    的函数专门为您的任务而构建。来自
    gmp
    手册:“他们使用的算法比mpz_tdiv_ui快,但不提供有关实际余数的有用信息,只提供余数是否为零(或特定值)。”该语句正下方还建议:然而,当测试几个小整数的可除性时,最好将它们的乘积取模,以保存多精度运算。例如,要测试一个数字是否可被23、29或31中的任何一个整除,请取一个模为23×29×31=20677的余数,然后进行测试。"…这看起来真的很有希望,因为一般来说,在你的素数库中,你有许多小素数需要测试。我看了部分视频。你的想法真的很棒。如果我成功实现了它,我会在我的
    R
    包中表扬你:。@JosephWood我很高兴你喜欢它。祝你的项目好运!经过大量的尝试和测试错误,我放弃了这个想法有一段时间了,但最近我重新考虑了它,并取得了成功。它将包含在下一个版本中。正如承诺的那样,我相信你:@JosephWood this is great.Tnx
        private VectorData extractVector(BigInteger value) {
            BitSet vector = new BitSet(PrimeBase.instance.primeBase.size());
            if(value.compareTo(BigInteger.ZERO) < 0){
                vector.set(0);
                value = value.abs();
            }
            value = extractPower2(value, vector);
            for (int i = 2; i < PrimeBase.instance.primeBase.size(); i++) {
                BigInteger p = PrimeBase.instance.primeBaseBigInteger.get(i);
                int count = 1;
        
                BigInteger[] results = value.divideAndRemainder(p);
                if (results[1].equals(BigInteger.ZERO)) {
                    value = results[0];
                    while (true) {
                        results = value.divideAndRemainder(p);
                        if(!results[1].equals(BigInteger.ZERO)){
                            break;
                        }
                        value = results[0];
                        count++;
                    }
                    if(count % 2 == 1) {
                        vector.set(i);
                    }
        
                    if (value.equals(BigInteger.ONE)) {
                        bSmoothVectorData.vector = vector;
                        return bSmoothVectorData;
                    } else if (value.compareTo(PrimeBase.instance.maxPrimeBigInteger) <= 0) {
                        int index = PrimeBase.instance.primeBaseMap.get(value);
                        vector.set(index);
                        bSmoothVectorData.vector = vector;
                        return bSmoothVectorData;
                    } else if (value.bitLength() / 2 < p.bitLength()) {
                        if (isPrime(value.longValue())) {
                            return new VectorData(vector, value);
                        }
                        return null;
                    }
                }
            }
            return null;
        }