问题
I want first 'n' consecutive composite numbers
I searched command for finding consecutive composite numbers, but i got the result proving for that thorem. I didn't get any command for that..please help me to slove this problem in R.
回答1:
Here is another option:
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
}
It uses basic control flows to cycle through positive integers indexing composites.
benchmark
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:
The code of @Pierre Lafortune is neat and not too slow, but I'd like to propose another approach which is substantially faster.
Tackling the problem from another perspective, finding the first n
composite numbers in R can be translated to "get the first n+k
integers and remove the primes". This is fast because generating the sequence 1:(n+k)
takes almost no time and there are very sophisticated algorithms to find primes available, one implementation being numbers::Primes()
.
The sequence needs to end with n+k
because within the first n
integers there will be some (k1
) primes that need to be replaced. Note that the range (n+1):(n+k1)
might also contain k2
primes, which need to be replaced as well. And on, and on, and on, … This will require a recursive structure.
Pierre's answer basically does something similar: He iteratively checks if an integer is a composite number (non-prime) and continues until enough composites are found. However, this has one drawback: The algorithm to find (non-) primes is rather naive (as compared to other algorithms to find primes; no offense intended). One the other hand, that solution doesn't involve the recursive problem of possible primes in any range of integers mentioned above.
The recursive solution I'd like to suggest is the following:
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)
}
This generates a sequence of integers (potential composites), then uses numbers::Primes()
to find the primes in that range and removes them from the sequence. If some numbers have been removed, the function calls itself again, this time computing [number of primes in previous step]
composites and starting the sequence from where the previous step stopped.
If there are doubts whether this actually works, here the check against Pierre's solution (n_composite()
):
> all(n_composite(1e4) == n_composite2(1e4))
[1] TRUE
Comparing both functions, n_composite2()
is approximately 19 times faster:
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
As a final remark: There are many solutions "between" Pierre's approach and the solution presented here. One could use numbers::Primes()
in a while
loop, very similar to what's happening in n_composite()
. One could also start with a "sufficiently long" sequence of integers, remove the primes and then take the first n
remaining numbers. To be efficient, this approach required a good approximation of the numbers of primes in a given range which is also not trivial (for low numbers).
回答3:
That is indeed a lazy way of asking a question, but nevertheless; this should do it:
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)
})
The idea is to consequently check for each number if it has any divisors except 1 and itself. The function I provided finds first 10 000 composite numbers in about 2 seconds. If you want greater speed on large numbers, it will be better to optimize it. For example, by looking for divisors only amongst simple numbers.
来源:https://stackoverflow.com/questions/32397169/how-to-find-consecutive-composite-numbers-in-r