Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
生成集合的所有子集,使它们的重聚等于整个集合 我有一个问题,我试图在C++中实现。给定一组数字,我想生成所有的子集,这样这些子集的重聚等于整个集合_C++_R_Vector_Rcpp - Fatal编程技术网

生成集合的所有子集,使它们的重聚等于整个集合 我有一个问题,我试图在C++中实现。给定一组数字,我想生成所有的子集,这样这些子集的重聚等于整个集合

生成集合的所有子集,使它们的重聚等于整个集合 我有一个问题,我试图在C++中实现。给定一组数字,我想生成所有的子集,这样这些子集的重聚等于整个集合,c++,r,vector,rcpp,C++,R,Vector,Rcpp,例如,对于A={1,2,3},我希望获得: (1,2,3) (1,2)(3) (1,3)(2) (1) (2,3) (1)(2)(3) 我获取这些子集的顺序并不重要 我试图在C++/RCpp中实现这一点,因为在R中,它往往是我拥有的代码的瓶颈。我目前的想法是有一个结构 X向量其中我一个接一个地添加所有向量。 在集合A中循环 对于1,我将{[(1)]}添加到X{1} 我以这种方式添加接下来的元素;假设我在X{1}=[(1)(2)]和X{2}=[(1,2)],下一个加起来的数字是3。然后我在X的

例如,对于A={1,2,3},我希望获得: (1,2,3)
(1,2)(3)
(1,3)(2)
(1) (2,3)
(1)(2)(3) 我获取这些子集的顺序并不重要

我试图在C++/RCpp中实现这一点,因为在R中,它往往是我拥有的代码的瓶颈。我目前的想法是有一个结构
X向量
其中我一个接一个地添加所有向量。 在集合A中循环

  • 对于1,我将{[(1)]}添加到X{1}
  • 我以这种方式添加接下来的元素;假设我在X{1}=[(1)(2)]和X{2}=[(1,2)],下一个加起来的数字是3。然后我在X的元素之间做一个循环。如果我遇到一个只有一个向量的元素(比如X{2}),那么我返回[(1,2)(3)]和[(1,2,3)]。如果我遇到一个有两个向量的元素(比如X{1}),那么我循环遍历向量,对于1我返回[(1,3)(2)],对于2我返回[(1),(2,3)],最后我加上[(1)(2),(3)]
问题是,这个实现被证明比纯R中的类似实现要慢,后者已经相当慢了

有没有一种稍微有效的方法来生成这些子集? 也许先生成所有子集(在R中很容易做到),然后按此顺序对它们进行分组(但我还没有弄清楚如何进行)

编辑:C++代码(相当长)

std::vector>push_one(std::vector x,int add){
std::vectorres;
res.push_back(x);
std::vector newvec;
newvec.push_back(添加);
res.push_back(新向量);
返回res;
}
std::vector push_二(std::vector x,int add){
std::vector newvec;
std::vector>res;
res.push_back(push_one(x,add));
x、 推回(添加);
newvec.push_back(x);
res.push_back(新向量);
返回res;
}
//push_one_rest的作用与push_one相同,只是它采用了一个“rest”参数,在末尾添加另一个(向量向量)。
std::vector>push_one_rest(std::vector x,int add,std::vector rest){
std::vectorres;
res.push_back(x);
std::vector newvec;
newvec.push_back(添加);
res.push_back(新向量);
res.insert(res.end(),rest.begin(),rest.end());
返回res;
}
//push_two_rest的作用与push_two相同,但它需要在每个元素的末尾添加rest参数。
std::vector push_two_rest(std::vector x,int add,std::vector rest){
std::vector newvec;
std::vector>res;
//res.push_back(push_one_rest(x,add,rest));
x、 推回(添加);
newvec.push_back(x);
insert(newvec.end(),rest.begin(),rest.end());
res.push_back(新向量);
返回res;
}
//additref添加一个新数字。
void additref(std::vector&x,int-add){
int xsize=x.size();
对于(int i=0;i1){
std::vector addvec;
添加。推回(添加);

对于(int i=0;i我认为最好使用位集。给定一组由N个元素组成的S,可以将S的每个元素映射到一个位,然后通过includin elemnst生成与“1”对应的子集

例如,给定S={A,B,C}你会得到

000 -> {}
001 -> {C}
010 -> {B}
011 -> {B, C}
100 -> {A}
101 -> {A, C}
110 -> {A, B}
111 -> {A, B, C}

“partitions”包中的
listParts
函数似乎可以工作:

> require(partitions)

> listParts(4)
[[1]]
[1] (1,2,3,4)

[[2]]
[1] (1,2,4)(3)

[[3]]
[1] (1,2,3)(4)

[[4]]
[1] (1,3,4)(2)

[[5]]
[1] (2,3,4)(1)

[[6]]
[1] (1,4)(2,3)

[[7]]
[1] (1,2)(3,4)

[[8]]
[1] (1,3)(2,4)

[[9]]
[1] (1,4)(2)(3)

[[10]]
[1] (1,2)(3)(4)

[[11]]
[1] (1,3)(2)(4)

[[12]]
[1] (2,4)(1)(3)

[[13]]
[1] (2,3)(1)(4)

[[14]]
[1] (3,4)(1)(2)

[[15]]
[1] (1)(2)(3)(4)

> 

我想了一下。但是我不知道如何将100与(010,001)和(011)进行分组。例如,当我用长度为4的集合进行分组时,我会得到(1000),它应该与[(0100),(0010),(0001)]配对,但也与[(0100),(0011)]配对等等。所以你想要不相交的子集,其并集是原始集,对吗?你想要全部还是部分?准确地说。全部。谢谢,我不知道这个函数。但是,似乎非常慢:例如,对于1:9(称为listParts(9))我使用microbenchmark平均每次运行1.25秒,而在我文章中代码的R实现中,大约需要84毫秒。你只对3的集合感兴趣吗?或者集合可以任意大?此外,你似乎不允许空集合……集合可以任意大(但假设集合中有
n
元素,那么就有
2^(n-1)-1
将其拆分为两个非空子集的不同方法,但每个方法都可以再次拆分…等等。因此,拆分初始集的可能方法的总数大于此。是的,你是对的。即使我不以我认为的格式存储所有这些值,我仍然会很高兴(如果我能以某种方式列出所有这些子集组合)
> require(partitions)

> listParts(4)
[[1]]
[1] (1,2,3,4)

[[2]]
[1] (1,2,4)(3)

[[3]]
[1] (1,2,3)(4)

[[4]]
[1] (1,3,4)(2)

[[5]]
[1] (2,3,4)(1)

[[6]]
[1] (1,4)(2,3)

[[7]]
[1] (1,2)(3,4)

[[8]]
[1] (1,3)(2,4)

[[9]]
[1] (1,4)(2)(3)

[[10]]
[1] (1,2)(3)(4)

[[11]]
[1] (1,3)(2)(4)

[[12]]
[1] (2,4)(1)(3)

[[13]]
[1] (2,3)(1)(4)

[[14]]
[1] (3,4)(1)(2)

[[15]]
[1] (1)(2)(3)(4)

>