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

如何在R中高效生成黄石序列(A098550)?

优化R语言生成黄石序列(A098550)的速度方案

我通过Numberphile的YouTube视频了解到黄石序列(OEIS编号A098550),该序列以1和2起始,后续项需遵循以下规则生成:

  • 无重复项
  • 始终选取最小整数
  • gcd(aₙ, aₙ₋₁) = 1
  • gcd(aₙ, aₙ₋₂) > 1

其前15项为:1 2 3 4 9 8 15 14 5 6 25 12 35 16 7

我用R写了一个快速粗糙(Q&D)的实现,但生成更长序列时速度极慢,而且代码还假设了序列的最大数值(注:10000项的序列数值不超过5000)。原始代码如下:

library(DescTools)
a <- c(1, 2, 3)
p <- length(a)

# all natural numbers
all_ints <- 1:5000

for (n in p:1000) {
    # rule 1 - remove all number that are in sequence already
    next_a_set <- all_ints[which(!all_ints %in% a)]

    # rule 3 - search the remaining set for numbers that have gcd == 1
    next_a_option <- next_a_set[which(
        sapply(
            next_a_set,
            function(x) GCD(a[n], x)
        ) == 1
    )]

    # rule 4 - search the remaining number for gcd > 1
    next_a <- next_a_option[which(
        sapply(
            next_a_option,
            function(x) GCD(a[n - 1], x)
        ) > 1
    )]

    # select the lowest
    a <- c(a, min(next_a))
    n <- n + 1
}

核心优化思路

原始代码效率低下的核心问题:频繁复制向量、低效的已使用数查询、逐元素sapply计算。针对这些问题,给出以下优化方案:

1. 预分配向量,避免频繁内存复制

每次用c(a, ...)扩展向量会触发内存复制,预分配足够长度的向量直接赋值能大幅减少开销:

target_length <- 10000
a <- integer(target_length)
a[1:3] <- c(1, 2, 3)

2. 用逻辑向量跟踪已使用数,实现O(1)查询

用logical向量标记已使用的整数,替代!all_ints %in% a这种O(n)级别的低效查询:

max_val <- 5000
used <- logical(max_val)
used[a[1:3]] <- TRUE

3. 内置gcd替代第三方包,提前终止判断

R 4.0+版本内置了base::gcd函数,无需加载DescTools;同时从最小未使用数开始检查,找到符合条件的就停止遍历,不用计算所有候选。


优化后的完整代码

target_length <- 10000
max_val <- 5000

# 预分配序列存储向量
a <- integer(target_length)
a[1:3] <- c(1, 2, 3)

# 标记已使用的数值
used <- logical(max_val)
used[a[1:3]] <- TRUE

for (n in 3:(target_length - 1)) {
    prev1 <- a[n]
    prev2 <- a[n - 1]
    
    # 从最小整数开始遍历,找到第一个符合所有规则的数
    for (x in seq_len(max_val)) {
        if (used[x]) next
        if (gcd(x, prev1) == 1 && gcd(x, prev2) > 1) {
            a[n + 1] <- x
            used[x] <- TRUE
            break
        }
    }
}

进阶优化建议

  • 动态扩展数值范围:如果不确定max_val,可以在循环中检查是否所有数都已使用,动态扩展used向量;
  • 预计算质因数:提前为每个数计算质因数集合,判断gcd条件时只需检查质因数交集,进一步提升效率;
  • Rcpp实现核心循环:将内层判断逻辑用C++实现,能把速度提升10-100倍,适合生成十万级以上的序列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:52:40