【问题标题】:how to find consecutive composite numbers in R如何在R中找到连续的合数
【发布时间】:2015-09-04 11:38:11
【问题描述】:

我想要前 'n' 个连续的合数

我搜索命令以查找连续的合数,但我得到了证明该定理的结果。我没有得到任何命令..请帮助我在 R 中解决这个问题。

【问题讨论】:

  • 您自己已经尝试过什么?为什么它不起作用?
  • 实际上我读到了与理论部分相关的内容,但我不知道如何在 r 中使用
  • 你现在有一个分析器,但是对于任何未来的 SO 问题:阅读如何提问。这不是作为代码编写服务。

标签: r algorithm algebra number-theory


【解决方案1】:

这是另一种选择:

n_composite <- function(n) {

  s <- 4L
  i <- 1L
  vec <- numeric(n)
  while(i <= n) {

    if(any(s %% 2:(s-1) == 0L)) {
      vec[i] <- s
      i <- i + 1L

    }

    s <- s + 1L
  }

  vec
}

它使用基本的控制流在正整数索引组合中循环。

基准测试

all.equal(find_N_composites(1e4), n_composite(1e4))
[1] TRUE

library(microbenchmark)
microbenchmark(

  Mak = find_N_composites(1e4),
  plafort = n_composite(1e4),
  times=5

  )

Unit: milliseconds
    expr       min        lq      mean    median        uq
     Mak 2304.8671 2347.9768 2397.0620 2376.4306 2475.2368
 plafort  508.8132  509.3055  522.1436  509.3608  530.4311
       max neval cld
 2480.7988     5   b
  552.8076     5  a 

【讨论】:

    【解决方案2】:

    @Pierre Lafortune 的代码简洁且不会太慢,但我想提出另一种更快的方法。

    从另一个角度解决问题,在R中找到第一个n复合数可以翻译为“获取第一个n+k整数并删除素数”。这很快,因为生成序列1:(n+k) 几乎不需要时间,并且有非常复杂的算法可以找到可用的素数,其中一种实现是numbers::Primes()。

    序列需要以n+k 结尾,因为在第一个n 整数中会有一些(k1) 素数需要替换。请注意,(n+1):(n+k1) 范围可能还包含 k2 素数,它们也需要被替换。等等等等……这将需要一个递归结构。

    皮埃尔的回答基本上做了类似的事情:他反复检查整数是否是合数(非素数)并继续直到找到足够的复合数。然而,这有一个缺点:寻找(非)素数的算法相当幼稚(与其他寻找素数的算法相比;无意冒犯)。另一方面,该解决方案不涉及上述任何整数范围内可能素数的递归问题。

    我想建议的递归解决方案如下:

    library(numbers)
    
    n_composite2 <- function(n, from = 2) {
    
      endRange <- from + n - 1
      numbers <- seq(from = from, to = endRange)
      primes <- Primes(n1 = from, n2 = endRange)
      composites <- numbers[!(numbers %in% primes)]
      nPrimes <- length(primes)
      if (nPrimes >= 1) return(c(composites, n_composite2(nPrimes, from = endRange + 1)))
    
      return(composites)
    }
    

    这会生成一个整数序列(可能的复合),然后使用numbers::Primes() 查找该范围内的素数并将它们从序列中删除。如果某些数字已被删除,则该函数会再次调用自身,这次计算[number of primes in previous step] 组合并从上一步停止的位置开始序列。

    如果怀疑这是否真的有效,请在此处检查 Pierre 的解决方案 (n_composite()):

    > all(n_composite(1e4) == n_composite2(1e4))
    [1] TRUE
    

    比较这两个函数,n_composite2() 大约快 19 倍:

    library(microbenchmark)
    microbenchmark(
      "n_composite2" = n_composite2(1e4),
      "n_composite" = n_composite(1e4),
      times=5
    )
    
    Unit: milliseconds
             expr       min        lq      mean    median        uq       max neval
     n_composite2  34.44039  34.51352  35.10659  34.71281  35.21145  36.65476     5
      n_composite 642.34106 661.15725 666.02819 662.99657 671.52093 692.12512     5
    

    最后一句话:在 Pierre 的方法和此处介绍的解决方案之间有许多解决方案。可以在while 循环中使用numbers::Primes(),这与n_composite() 中发生的情况非常相似。也可以从“足够长”的整数序列开始,删除素数,然后取第一个 n 剩余数字。为了提高效率,这种方法需要在给定范围内很好地近似素数,这也不是微不足道的(对于小数)。

    【讨论】:

      【解决方案3】:

      这确实是一种懒惰的提问方式,但无论如何;应该这样做:

      is_composite<-function(x){
                  sapply(x,function(y) if(y<3){FALSE}else{any(y%%(2:(y-1))==0)})
      }
      which(is_composite(1:100))
      
      find_N_composites<-function(N){
          which(is_composite(1:(2*N+2)))[1:N]
      }
      find_N_composites(10)
      
      system.time({
              x<-find_N_composites(1e+04)
      })
      

      我们的想法是检查每个数字是否有除 1 和自身之外的任何除数。我提供的函数在大约 2 秒内找到前 10 000 个合数。如果您想在大数字上获得更快的速度,最好对其进行优化。例如,仅在简单数字中寻找除数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-30
        • 2016-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-17
        相关资源
        最近更新 更多