对于x在1到1000的x和y在1-1000中使用R有多少独特的幂

时间:2015-02-23 00:47:39

标签: r

使用R,计算x和y是整数∈[1,1000],存在多少个唯一幂,x ^ y。 这就是我现在所拥有的,只是不知道如何消除重复的数字,

x<-1:1000
y<-1:1000
for (i in x)
{
    for (j in y){
       print(i^j)
    }
}

2 个答案:

答案 0 :(得分:15)

这种组合方法可以将数字从1-1000分成等价类,其中类中的每个数字都是其他数字的幂。例如,我们将数字1-10分成(1),(2,4,8),(3,9),(5),(6),(7),(10)。等价类之间的值的幂都不会重合,所以我们可以分别处理每个等价类。

num.unique.comb <- function(limit) {
  # Count number of powers in each equivalence class (labeled by lowest val)
  num.powers <- rep(0, limit)

  # Handle 1 as special case
  num.powers[1] <- 1

  # Beyond sqrt(limit), all unhandled numbers are in own equivalence class
  handled <- c(T, rep(F, limit-1))
  for (base in 2:ceiling(sqrt(limit))) {
    if (!handled[base]) {
      # Handle all the values in 1:limit that are powers of base
      num.handle <- floor(log(limit, base))
      handled[base^(1:num.handle)] <- T

      # Compute the powers of base that we cover
      num.powers[base] <- length(unique(as.vector(outer(1:num.handle, 1:limit))))
    }
  }
  num.powers[!handled] <- limit

  # Handle sums too big for standard numeric types
  library(gmp)
  print(sum(as.bigz(num.powers)))
}
num.unique.comb(10)
# [1] 76
num.unique.comb(1000)
# [1] 978318

这种组合方法的一个不错的特性是它与蛮力方法相比非常快。例如,在极限设置为1000的情况下计算时间不到0.1秒。这使我们可以计算更大值的结果:

# ~0.15 seconds
num.unique.comb(10000)
# [1] 99357483

# ~4 seconds
num.unique.comb(100000)
# [1] 9981335940

# ~220 seconds
num.unique.comb(1000000)
# [1] 999439867182

这是一个非常简洁的结果 - 在4分钟内,我们可以计算1万亿个数字内的唯一值数量,其中每个数字最多可以有600万个数字!

更新:根据此组合代码,我已更新OEIS entry for this sequence以包含最多10,000个字词。

答案 1 :(得分:7)

蛮力方法是计算所有权力并计算唯一值的数量:

num.unique.bf <- function(limit) {
  length(unique(as.vector(sapply(1:limit, function(x) x^(1:limit)))))
}
num.unique.bf(10)
# [1] 76

这种强力分析的一个问题是你正在处理会产生数值问题的大数字。例如:

1000^1000
# [1] Inf

结果我们得到一个不准确的值:

# Wrong due to numerical issues!
num.unique.bf(1000)
# [1] 119117

然而,像gmp这样的软件包可以让我们计算甚至大到1000 ^ 1000的数字。我的计算机一次将所有100万个数字存储在内存中,因此我将它们写入文件(n = 1000的大小在我的计算机上为1.2 GB),然后计算该文件中唯一值的数量:

library(gmp)
num.unique.bf2 <- function(limit) {
  sink("foo.txt")
  for (x in 1:limit) {
    vals <- as.bigz(x)^(1:limit)
    for (idx in 1:limit) {
      cat(paste0(as.character(vals[idx]), "\n"))
    }
  }
  sink()
  as.numeric(system("sort foo.txt | uniq | wc -l", intern=T))
}
num.unique.bf2(10)
# [1] 76
num.unique.bf2(1000)
# [1] 978318

快速访问OEIS(单击前1000个值的链接)表明这是正确的。这种方法相当慢(在我的计算机上大约40分钟),组合方法应该明显更快。