微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决什么是二次筛提取阶段最有效的分解算法?

在二次筛算法中,使用对数逼近法找到bSmooth值后,您需要将数字分解,将其称为B,以构造bSmooth向量。

一个常见的解决方案是使用在因子库中使用质数的试除法。与随机数不同,在这种情况下,由于大多数因素都位于素数基数中,因此试验划分效率很高。我之所以说“最多”,是因为常见的优化操作允许一个较小的阈值来包含1-3个素数,其乘积最大为2 ^ 30左右,这被称为部分关系。

在我的current implementation中,此向量提取阶段花费大部分时间。我一直在尝试的另一种解决方案是接收,再次遍历素数基,然后将向量记录在已知为b平滑的索引中,但结果变得更慢。

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

  1. 对于素数2,我检查B的最后一个设置位并向右移动以提取它。
  2. 我正在使用BigInteger divideAndRemainder,它通过将除法和mod动作组合为1来优化内存和性能
  3. 如果B小于因数库中的最大素数,则它必须在因数库中,因此我使用哈希图来定位其索引
  4. 如果没有B.bitLenght() / 2之前的素数除以B,那么它必须是部分关系,只有当它是素数时,我才会将其包括在内。
    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;
    }

bSmoothVectorData用于区分完全关系和部分关系。如果调用isPrime的情况极少发生,并且这种方法的整体性能不到0.001%,则瓶颈是divideAndRemainder调用性能的72%。

解决方法

通过切换接收与试用部门,我能够将性能提高近80%。现在,我已经在问题中提到我以前尝试过此方法,但没有成功。好吧,这一次它起作用了。

我用整数运算BigInteger.mod(x).equals(ZERO)代替了(bSmoothData.localX - delta) % prime == startingPosition测试,它可能对我的实现非常特定,但是这个想法是要检查素数是否应该在筛分数组中划分bSmooth索引。

接下来,我构造所有这些质数的乘积,然后将实际的bSmooth值除以它,然后提醒我,可能会陷入Java漫长的时期。然后,我将继续使用试验划分法提取它。如果您对我的实施方式感兴趣,我会制作一个关于它的视频here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。