You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化PARI-GP代码高效计算2ⁿ+3相关估值问题?

数论猜想计算的代码优化请求

我正在研究一个数论猜想,在计算对应序列(1,2,13,22,33,248,269)时遇到性能瓶颈。当前使用的PARI-GP代码如下:

Vmax = -1;
for(n = 1, 10^4,
    V = 0;
    fordiv(2^n + 3, d, V = max(V, valuation(d + 9, 2)));
    if(V > Vmax, Vmax = V; print([n, V]))
)

这段代码的核心问题是2ⁿ+3的整数分解难度随n增长呈指数上升,我的PC运行约2天仍未得到下一个序列值,过程中还频繁出现栈空间不足的警告:

[1, 1]
[2, 4]
[13, 6]
[22, 8]
[33, 10]
  *** fordiv: Warning: increasing stack size to 16000000.
[248, 12]
  *** fordiv: Warning: increasing stack size to 32000000.
  *** fordiv: Warning: increasing stack size to 64000000.
[269, 14]
  *** fordiv: Warning: increasing stack size to 128000000.
  *** fordiv: Warning: increasing stack size to 256000000.

请求优化代码,以高效获取后续的序列数值。


优化方案

1. 跳过完全分解,直接针对目标条件筛选因子

我们的目标是找到d | 2ⁿ+3中使valuation(d+9,2)最大的d,等价于找最大的k,使得存在d整除2ⁿ+3且d ≡ -9 mod 2ᵏ。无需分解所有因子,可直接通过同余判断实现:

Vmax = 14;  # 从已找到的最大值开始迭代
for(n = 270, 10^4,
    N = 2^n + 3;
    current_max = 0;
    # 从比当前最大值大的k往下试,找到第一个满足条件的就停止
    for(k = min(Vmax + 2, 30), 1, -1,
        mod_val = (-9) % (2^k);
        g = gcd(N, 2^k);
        # 检查gcd部分是否满足同余
        if(g % 2^k == mod_val,
            current_max = k;
            break;
        );
        # 检查剩余奇因子部分
        remaining = N // g;
        if(remaining == 1, continue);
        # 尝试部分分解剩余值
        fac = factor(remaining);
        found = 0;
        for(i=1, #fac,
            p = fac[i,1];
            e = fac[i,2];
            # 检查素因子或其幂次是否满足同余
            if(powmod(p, e, 2^k) == mod_val || znlog(mod_val, Mod(p, 2^k)) != -1,
                found = 1;
                break;
            );
        );
        if(found,
            current_max = k;
            break;
        );
    );
    if(current_max > Vmax,
        Vmax = current_max;
        print([n, Vmax]);
    );
)

2. 预计算小素因子,减少大合数分解压力

提前预计算小素因子(如小于1e6的素数),先剔除2ⁿ+3中的小因子,仅对剩余的大合数进行处理,大幅降低分解难度:

small_primes = primes(10^6);  # 预计算小素数表
Vmax = 14;
for(n = 270, 10^4,
    N = 2^n + 3;
    remaining = N;
    # 先剔除所有小素因子
    for(p in small_primes,
        if(remaining % p == 0,
            while(remaining % p == 0, remaining /= p);
        );
        if(remaining == 1, break);
    );
    current_max = 0;
    # 检查剩余大因子的同余条件
    if(remaining != 1,
        for(k = min(Vmax + 2, 30), 1, -1,
            mod_val = (-9) % (2^k);
            fac = factor(remaining);
            found = 0;
            for(i=1, #fac,
                p = fac[i,1];
                if(p % 2^k == mod_val || znlog(mod_val, Mod(p, 2^k)) != -1,
                    found = 1;
                    break;
                );
            );
            if(found,
                current_max = k;
                break;
            );
        );
    );
    # 补充检查小因子组合的同余情况(可选)
    # (此处可添加小因子乘积的同余判断逻辑,进一步覆盖所有可能的d)
    if(current_max > Vmax,
        Vmax = current_max;
        print([n, Vmax]);
    );
)

3. 利用数论性质缩小n的搜索范围

观察已有的序列,可推导n的同余约束:对于目标k,先解同余式2ⁿ ≡ -3 mod 2ᵏ,得到n的同余类,仅在这些类中搜索n,避免遍历所有数值:

Vmax = 14;
# 预计算不同k对应的n的同余条件
for(k = Vmax + 1, 30,
    mod_val = (-3) % (2^k);
    # 解2^n ≡ mod_val mod 2^k,得到n的最小解和周期
    sol = znlog(mod_val, Mod(2, 2^k));
    if(sol == -1, continue);
    period = 2^(k-2);  # 2的幂次模2^k的周期为2^(k-2)(k≥3)
    # 仅在满足n ≡ sol mod period的范围内搜索
    for(n = max(270, sol), 10^4, period,
        N = 2^n + 3;
        current_max = k;
        # 验证是否存在d|N满足d≡-9 mod 2^k
        # 此处复用方案1中的验证逻辑
        # ...
        if(current_max > Vmax,
            Vmax = current_max;
            print([n, Vmax]);
        );
    );
)

内容的提问来源于stack exchange,提问作者Lhachimi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 21:04:49