您将如何测试一组给定数字的所有可能的添加组合,以便它们加起来给定的最终数字?
例:
在比较检查列表是否包含R中的另一个列表时,比较两个函数的效率,我偶然发现了一个有趣的结果.排序大大提高了duplicated矢量大时的效率.这是一个惊喜,因为我从未注意到我自己的工作使用时有相当大的差异duplicated.事实上,对于我每天工作的尺寸,没有区别.注意:
set.seed(1007)
s1 <- sample(10^2, 10^3, replace = TRUE)
s1_sort <- sort(s1)
library(microbenchmark)
microbenchmark(dp=duplicated(s1), dp_sort=duplicated(s1_sort), times=1000)
Unit: microseconds
expr min lq mean median uq max neval cld
dp 16.459 16.9425 22.06371 17.2965 22.5050 1541.137 1000 a
dp_sort 17.007 17.5005 25.54953 17.8200 23.3655 1549.198 1000 a
Run Code Online (Sandbox Code Playgroud)
如您所见,向量排序时的时间没有明显差异.然而,在非常大的向量上,结果是非常不同的.注意:
s2 <- sample(10^6, 10^7, replace = TRUE)
s2_sort <- sort(s2)
microbenchmark(dp=duplicated(s2), dp_sort=duplicated(s2_sort), times=100)
Unit: milliseconds
expr min lq mean median uq max neval cld
dp 816.6883 847.9231 869.6829 …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个函数,它返回一个向量的无序组合.例如
x<-c('red','blue','black')
uncomb(x)
[1]'red'
[2]'blue'
[3]'black'
[4]'red','blue'
[5]'blue','black'
[6]'red','black'
[7]'red','blue','black'
Run Code Online (Sandbox Code Playgroud)
我想在某个库中有一个函数可以执行此操作,但是找不到它.我正在尝试permutations,gtool但它不是我正在寻找的功能.
有没有办法加快combn命令,以获得从矢量中取出的2个元素的所有独特组合?
通常这将设置如下:
# Get latest version of data.table
library(devtools)
install_github("Rdatatable/data.table", build_vignettes = FALSE)
library(data.table)
# Toy data
d <- data.table(id=as.character(paste0("A", 10001:15000)))
# Transform data
system.time({
d.1 <- as.data.table(t(combn(d$id, 2)))
})
Run Code Online (Sandbox Code Playgroud)
但是,combn使用data.table计算所有可能的组合要慢10倍(23秒对比我的计算机3秒).
system.time({
d.2 <- d[, list(neighbor=d$id[-which(d$id==id)]), by=c("id")]
})
Run Code Online (Sandbox Code Playgroud)
处理非常大的向量,我正在寻找一种通过仅计算唯一组合(如combn)来节省内存的方法,但是使用data.table的速度(参见第二个代码片段).
我感谢任何帮助.
我正在将一些主要使用数字数据(即双打)的代码转换为整数,并做了一个快速的基准测试,看看我获得了多少效率.
令我惊讶的是它慢了......大约20%.我以为自己做错了什么,但是原始代码只是对中等大小的矢量进行了几次基本的算术运算,所以我知道不是那样的.也许我的环境搞砸了?我重新开始新鲜,同样的结果......整数效率较低.
这开始了一系列测试和潜入兔子洞.这是我的第一次测试.我们使用基数R总计一百万个元素sum.请注意,对于R版本3.5.0,时序有点不同,对于v 3.5.1,时序大致相同(仍然不是人们所期望的):
set.seed(123)
int1e6 <- sample(1:10, 1e6, TRUE)
dbl1e6 <- runif(1e6, 1, 10)
head(int1e6)
# [1] 5 3 6 8 6 2
class(int1e6)
# [1] "integer"
head(dbl1e6)
# [1] 5.060628 2.291397 2.992889 5.299649 5.217105 9.769613
class(dbl1e6)
#[1] "numeric"
mean(dbl1e6)
# [1] 5.502034
mean(int1e6)
# [1] 5.505185
## R 3.5.0
library(microbenchmark)
microbenchmark(intSum = sum(int1e6), dblSum = sum(dbl1e6), times = 1000)
Unit: microseconds
expr min lq mean median uq max neval
intSum 1033.677 1043.991 1147.9711 1111.438 …Run Code Online (Sandbox Code Playgroud) 例如,考虑数字96.可以用以下方式编写:
1. 96
2. 48 * 2
3. 24 * 2 * 2
4. 12 * 2 * 2 * 2
5. 6 * 2 * 2 * 2 * 2
6. 3 * 2 * 2 * 2 * 2 * 2
7. 4 * 3 * 2 * 2 * 2
8. 8 * 3 * 2 * 2
9. 6 * 4 * 2 * 2
10. 16 * 3 * 2
11. 4 * 4 * …Run Code Online (Sandbox Code Playgroud) 我有一种非常低效的方法来计算N/2大小为N的数组中的项组合.我所做的是先对数组进行排序,然后循环遍历数组的排列,创建具有一半元素的多重集并将其插入到一套.最后我得到了集合的计数.
long GetCombinations(std::vector<double> nums) {
long combinations = 0;
std::sort(nums.begin(), nums.end());
std::set<std::multiset<double>> super_set;
do {
std::multiset<double> multi_set;
for (unsigned int i = 0; i < nums.size() / 2; ++i)
multi_set.insert(nums[i]);
auto el = (super_set.insert(multi_set));
if (el.second)
++combinations;
} while (std::next_permutation(nums.begin(), nums.end()));
return combinations;
}
Run Code Online (Sandbox Code Playgroud)
代码有效,但效率很低.对于给定的数组[0.5, 0.5, 1, 1],有3种大小为2的组合:
0.5,0.5
1,1
1,0.5
是否有不同的算法或方法可以提高此代码的速度?
我的目标是获取通过省略号传递的附加参数...(请参阅?dots参考资料 获取更多信息),并使用已设置的参数构建一个新的通用函数,并将其传递给另一个函数。
例如,给定两个函数:
foo <- function(v, FUN, ...) {
## code here to build NEWFUN
SomeFun(v, NEWFUN)
}
bar <- function(v, FUN) {
SomeFun(v, FUN)
}
Run Code Online (Sandbox Code Playgroud)
我希望能够在以下位置执行此操作foo:
bar(x, FUN = \(x) paste(x, collapse = ", "))
Run Code Online (Sandbox Code Playgroud)
通过调用foo(x, paste, collapse = ", ").
我们从一个简单的函数开始,它采用一个基R函数(此处paste)并将其应用于向量。请注意,我试图使其尽可能简单,因此我删除了健全性检查。另外,我写这个只是为了用基本R函数来演示paste。
FunAssign <- function(f, x) f(x)
Run Code Online (Sandbox Code Playgroud)
这是我天真的尝试:
foo <- function(v, FUN, ...) {
FUN <- \(x) FUN(x, ...)
FunAssign(FUN, v)
} …Run Code Online (Sandbox Code Playgroud) 我制作了一个如下所示的向量:
v1 <- c("1 1","1 2","1 3",
"2 1","2 2","2 3",
"3 1","3 2","3 3",
"4 1","4 2","4 3",
"5 1","5 2","5 3",
"6 1","6 2","6 3")
Run Code Online (Sandbox Code Playgroud)
它可以被称为v1。
我想要的结果是 "1 1 1 1" "1 1 1 2" .... "6 6 6 6" (总共应该是 6x3x6x3=360-36=324 到一个新的向量 v2 中)
然而,我已经尝试过apply(combn(v1, 2), 2, paste0, collapse=" "),但还不完整。
我怎样才能实现目标?
我无法弄清楚滤波器功能如何如此快速地工作.我已经对所有类型的数据使用过滤器,无论数据类型如何,Filter都会删除我使用的任何替代方法.我经常使用二进制搜索算法和Stephen Bullen编写的QuickArraySort算法(在专业Excel开发中找到).二进制搜索是快速的(与Filter函数一样快,因为数组已经排序),Quick Sort算法是已知最快的排序算法之一.
我在下面编写了一些测试代码,比较了在一个非常大的数组中查找随机元素的速度(大小= 2,000,000).我故意以无序的方式填充数组(应该注意我已经尝试了各种无序的分配方法,并且无论分配方法如何,结果都是相似的).
Sub SearchTest()
Dim i As Long, strMyArray() As String, lngSize As Long, strTest As String
Dim TimeBinarySearch As Long, TimeFilterSearch As Long
Dim lngResultBinary As Long, lngResultFilter As Long
Dim StartHour As Long, StartMinute As Long, StartSecond As Long
Dim StartMiliSecond As Long, StartTime As Long
Dim EndHour As Long, EndMinute As Long, EndSecond As Long
Dim EndMiliSecond As Long, EndTime As Long
lngSize = 2000000
strTest = CStr(1735674 * 987)
ReDim strMyArray(lngSize) …Run Code Online (Sandbox Code Playgroud) r ×7
combinations ×5
algorithm ×3
c++ ×2
performance ×2
permutation ×2
sorting ×2
arrays ×1
c ×1
combn ×1
data.table ×1
duplicates ×1
ellipsis ×1
excel ×1
function ×1
parameters ×1
rcpp ×1
search ×1
string ×1
subset-sum ×1
vba ×1
vector ×1