欧拉投影问题1在R -各种方法

i86rm4rw  于 2023-01-06  发布在  其他
关注(0)|答案(1)|浏览(122)

我在社交媒体上看到了这个问题,并研究了一些快速实现。有没有人对什么可以更快有一些投入?
欧拉计划问题1
如果我们列出所有10以下的3或5的倍数的自然数,我们得到3、5、6和9。这些倍数之和是23。
求1000以下所有3或5的倍数之和。
我使用1:1e8作为基本范围,以获得方法之间的显著差异。

# library call only needed for the furrr:future_map_dbl solution
library(furrr)
plan(multisession)

nums <- 1:1e8

t1 <- Sys.time()
sum(nums[which(nums %% 3 == 0 | nums %% 5 == 0)])

t2 <- Sys.time()
sum(sapply(nums, function(x) if (x %% 3 == 0 | x %% 5 == 0) x else 0))

t3 <- Sys.time()
sum(purrr::map_dbl(nums, ~ if (.x %% 3 == 0 | .x %% 5 == 0) .x else 0))

t4 <- Sys.time()
sum(furrr::future_map_dbl(nums, ~ if (.x %% 3 == 0 | .x %% 5 == 0) .x else 0))

t5 <- Sys.time()

times <- c(t1, t2, t3, t4, t5)
t <- times[2:5] - times[1:4]
names(t) <- c("base-r","sapply","map_dbl","future_map_dbl")
t

我电脑上的时间是

Time differences in secs
        base-r         sapply        map_dbl future_map_dbl
      2.745852     186.671004      80.694654      31.161530

使用非基本R方法会增加一些开销,这在较小的范围内是显而易见的,例如nums <- 1:1e6

Time differences in secs
        base-r         sapply        map_dbl future_map_dbl
    0.05106783     0.78388309     1.50676894     0.32907510
3htmauhk

3htmauhk1#

这并不容易推广到两个以上数字的倍数,但要回答这个问题,你可以使用算术级数公式,我们计算每个值的级数之和减去两个值的最小公倍数的级数。

f <- function(x, y, range_max) {
  
  # Function to calculate arithmetic series sum
  as_sum <- function(v) {
    n <- floor(range_max / v)
    n / 2 * (v + n * v)
  }
  # Function to find lowest common multiple
    find_lcm <- function(x, y){
      gcd <- function(x, y) {
        ifelse(x %% y != 0, Recall(y, x %% y), y)
      }
      x * y / gcd(x, y)
    }
    
    lcm <- find_lcm(x, y)
    as_lcm <- as_sum(lcm) * (lcm <= 1000)
    
    sum(as_sum(c(x, y))) - as_lcm 
}

基准:

nums<- 1:1e8
bench::mark(arithmetic_series_sum = f(3, 5, 1e8),
            subset_sum = sum(nums[which(nums %% 3 == 0 | nums %% 5 == 0)]))[1:9]

# A tibble: 2 × 9
  expression                 min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
  <bch:expr>            <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
1 arithmetic_series_sum   13.2µs   14.5µs 65916.           0B    0     10000     0   151.71ms
2 subset_sum               4.56s    4.56s     0.219     3.7GB    0.877     1     4      4.56s

相关问题