如何在 Rcpp 中的 n 之间创建 k 个元素的组合?
How to create a combination of k elements between n in Rcpp?
下午好,
我们知道在 R 中,我们可以通过这种方式检索 A = { 1 , 2 , ... , n } 之间的 k 个元素的所有可能组合:
示例: A = { 1 , 2, ,3 ,4 ,5 } 和 K = 3
> C_wo <- combn(1:5, 3)
> C_wo
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 1 1 1 2 2 2 3
[2,] 2 2 2 3 3 4 3 3 4 4
[3,] 3 4 5 4 5 5 4 5 5 5
我的问题:
是否有用于在 rcpp 中创建这些组合的内置函数?
提前致谢!
我不认为有这样的内置 Rcpp 函数,但这些函数在 {RcppAlgos} 中实现。
试试这个。
library(microbenchmark)
z1 <- combncpp(50,5)
z2 <- combn(50,5)
identical(t(z1), z2) # I prefer column-wise so it is transposed
[1] TRUE
microbenchmark(cpp = combncpp(25,10),
r = combn(25,10), times = 5)
Unit: milliseconds
expr min lq mean median uq max neval
cpp 275.882 295.9357 295.4369 299.9468 300.0149 305.4051 5
r 2729.003 2755.1360 2789.3226 2798.6658 2819.9010 2843.9075 5
函数:
#include <Rcpp.h>
#include <algorithm>
using namespace Rcpp;
// [[Rcpp::export]]
uint64_t choosecpp(uint64_t n, uint64_t k) {
if(k == 0) return 1;
return (n * choosecpp(n - 1, k - 1)) / k;
}
// [[Rcpp::export]]
IntegerMatrix combncpp(int N, int K) {
if(K > N) Rcpp::stop("K > N");
std::string bitmask(K, 1);
bitmask.resize(N, 0);
uint64_t n_combos = choosecpp(N,K);
IntegerMatrix results(n_combos, K);
uint64_t row_position = 0;
do {
uint64_t col_position = 0;
for (int i = 0; i < N; ++i) {
if (bitmask[i]) {
results(row_position, col_position) = i+1;
col_position++;
}
}
row_position++;
} while (std::prev_permutation(bitmask.begin(), bitmask.end()));
return results;
}
归功于此,该函数是根据此处列出的算法修改的:Creating all possible k combinations of n items in C++
下午好,
我们知道在 R 中,我们可以通过这种方式检索 A = { 1 , 2 , ... , n } 之间的 k 个元素的所有可能组合:
示例: A = { 1 , 2, ,3 ,4 ,5 } 和 K = 3
> C_wo <- combn(1:5, 3)
> C_wo
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 1 1 1 2 2 2 3
[2,] 2 2 2 3 3 4 3 3 4 4
[3,] 3 4 5 4 5 5 4 5 5 5
我的问题:
是否有用于在 rcpp 中创建这些组合的内置函数?
提前致谢!
我不认为有这样的内置 Rcpp 函数,但这些函数在 {RcppAlgos} 中实现。
试试这个。
library(microbenchmark)
z1 <- combncpp(50,5)
z2 <- combn(50,5)
identical(t(z1), z2) # I prefer column-wise so it is transposed
[1] TRUE
microbenchmark(cpp = combncpp(25,10),
r = combn(25,10), times = 5)
Unit: milliseconds
expr min lq mean median uq max neval
cpp 275.882 295.9357 295.4369 299.9468 300.0149 305.4051 5
r 2729.003 2755.1360 2789.3226 2798.6658 2819.9010 2843.9075 5
函数:
#include <Rcpp.h>
#include <algorithm>
using namespace Rcpp;
// [[Rcpp::export]]
uint64_t choosecpp(uint64_t n, uint64_t k) {
if(k == 0) return 1;
return (n * choosecpp(n - 1, k - 1)) / k;
}
// [[Rcpp::export]]
IntegerMatrix combncpp(int N, int K) {
if(K > N) Rcpp::stop("K > N");
std::string bitmask(K, 1);
bitmask.resize(N, 0);
uint64_t n_combos = choosecpp(N,K);
IntegerMatrix results(n_combos, K);
uint64_t row_position = 0;
do {
uint64_t col_position = 0;
for (int i = 0; i < N; ++i) {
if (bitmask[i]) {
results(row_position, col_position) = i+1;
col_position++;
}
}
row_position++;
} while (std::prev_permutation(bitmask.begin(), bitmask.end()));
return results;
}
归功于此,该函数是根据此处列出的算法修改的:Creating all possible k combinations of n items in C++