C++ 高效计算向量组合
出于好奇,我正在研究一个问题,我不知道如何编程我所想的逻辑。让我向你解释一下: 我有四个向量,比如说C++ 高效计算向量组合,c++,algorithm,vector,combinations,C++,Algorithm,Vector,Combinations,出于好奇,我正在研究一个问题,我不知道如何编程我所想的逻辑。让我向你解释一下: 我有四个向量,比如说 v1 = 1 1 1 1 v2 = 2 2 2 2 v3 = 3 3 3 3 v4 = 4 4 4 4 现在我想做的是把它们组合起来,就是 v12 = v1+v2 v13 = v1+v3 v14 = v1+v4 v23 = v2+v3 v24 = v2+v4 v34 = v3+v4 直到这一步,一切都很好。现在的问题是,我想将这些向量中的每一个都添加到v1、v2、v3、v4中的一个向量中,这
v1 = 1 1 1 1
v2 = 2 2 2 2
v3 = 3 3 3 3
v4 = 4 4 4 4
现在我想做的是把它们组合起来,就是
v12 = v1+v2
v13 = v1+v3
v14 = v1+v4
v23 = v2+v3
v24 = v2+v4
v34 = v3+v4
直到这一步,一切都很好。现在的问题是,我想将这些向量中的每一个都添加到v1、v2、v3、v4中的一个向量中,这是它以前没有添加过的。例如:
v3和v4还没有添加到v12中,所以我想创建v123和v124。类似地,对于所有向量
v12 should become:
v123 = v12+v3
v124 = v12+v4
v13 should become:
v132 // This should not occur because I already have v123
v134
v14 should become:
v142 // Cannot occur because I've v124 already
v143 // Cannot occur
v23 should become:
v231 // Cannot occur
v234 ... and so on.
重要的是,我不要一开始就一步到位。例如,我可以做(4选择3)4C3并完成它,但我想在每次迭代中一步一步地做
我该如何编程
注:我正在尝试数据挖掘中apriori算法的改进版本
import itertools
l1 = ['v1','v2','v3','v4']
res = []
for e in itertools.combinations(l1,2):
res.append(e)
fin = []
for e in res:
for l in l1:
aset = set((e[0],e[1],l))
if aset not in fin and len(aset) == 3:
fin.append(aset)
print fin
这将导致:
[set(['v1', 'v2', 'v3']), set(['v1', 'v2', 'v4']), set(['v1', 'v3', 'v4']), set(['v2', 'v3', 'v4'])]
这与4C3的结果相同。也许我有误解,但这不等于生成1、2、3、4的所有子集(幂集),然后对幂集的每个元素求和向量吗?例如:
//This is pseudo C++ since I'm too lazy to type everything
//push back the vectors or pointers to vectors, etc.
vector< vector< int > > v = v1..v4;
//Populate a vector with 1 to 4
vector< int > n = 1..4
//Function that generates the power set {nil, 1, (1,2), (1,3), (1,4), (1,2,3), etc.
vector< vector < int > > power_vec = generate_power_set(n);
//One might want to make a string key by doing a Perl-style join of the subset together by a comma or something...
map< vector < int >,vector< int > > results;
//For each subset, we sum the original vectors together
for subset_iter over power_vec{
vector<int> result;
//Assumes all the vecors same length, can be modified carefully if not.
result.reserve(length(v1));
for ii=0 to length(v1){
for iter over subset from subset_iter{
result[ii]+=v[iter][ii];
}
}
results[*subset_iter] = result;
}
<代码> //这是伪C++,因为我太懒了,不能把所有的东西都打出来。
//向后推向量或指向向量的指针等。
向量v=v1..v4;
//用1到4填充向量
向量.我认为这个问题可以通过标记发生的组合来解决 我的第一个想法是,你可以使用一个三维数组来标记发生了什么组合。但这不是很好 一个用于标记的位数组(例如整数)怎么样?例如:
Num 1 = 2^0 for vector 1
Num 2 = 2^1 for vector 2
Num 4 = 2^2 for vector 3
Num 8 = 2^3 for vector 4
进行合成时,只需将所有代表性数字相加。例如,向量124的值为:1+2+8=11。该值对于每个组合都是唯一的
这只是我的想法,希望能对你有所帮助
编辑:也许我对我的想法不够清楚。我会尽量解释得更清楚一些:
1) 为每个向量指定一个代表性数字。这个数字是向量的id,并且是唯一的。此外,这些数字的每个子集的和是唯一的,这意味着如果我们有k个代表性数字的和是M,我们可以很容易地知道哪些向量参与了和
我们通过赋值:2^0表示向量1;2^1表示向量2;2^2表示向量3,依此类推
每M=sum(2^x+2^y+2^z+…)=(2^x或2^y或2^z或…)。我们知道向量(x+1)、(y+1)、(z+1)参与求和。这可以通过以二进制模式表示数字来轻松检查
例如,我们知道:
2^0=1(二进制)
2^1=10(二进制)
2^2=100(二进制)
所以如果我们的和是10010(二进制),我们知道向量(数:10)和向量(数:10000)在和中连接
最好的情况是,这里的和可以用“或”运算符计算,如果用二进制表示数字,这也很容易理解
< P > 2)利用上述事实,每次计数矢量之前,可以先添加或代表其代表性的数字,然后可以像查找数组一样跟踪它们。如果查找数组中已经存在了,则可以解决这个问题。C++中的< P>,给出以下例程:
template <typename Iterator>
inline bool next_combination(const Iterator first,
Iterator k,
const Iterator last)
{
/* Credits: Thomas Draper */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator itr1 = first;
Iterator itr2 = last;
++itr1;
if (last == itr1)
return false;
itr1 = last;
--itr1;
itr1 = k;
--itr2;
while (first != itr1)
{
if (*--itr1 < *itr2)
{
Iterator j = k;
while (!(*itr1 < *j)) ++j;
std::iter_swap(itr1,j);
++itr1;
++j;
itr2 = k;
std::rotate(itr1,j,last);
while (last != j)
{
++j;
++itr2;
}
std::rotate(k,itr2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}
模板
内联bool next_组合(常量迭代器优先,
迭代器k,
常量迭代器(最后)
{
/*字幕:托马斯·德雷珀*/
if((first==last)| |(first==k)| |(last==k))
返回false;
迭代器itr1=第一个;
迭代器itr2=最后一个;
++itr1;
if(last==itr1)
返回false;
itr1=最后一个;
--itr1;
itr1=k;
--itr2;
while(第一个!=itr1)
{
如果(*-itr1<*itr2)
{
迭代器j=k;
而(!(*itr1<*j))++j;
标准:国际热核实验堆交换(itr1,j);
++itr1;
++j;
itr2=k;
标准:旋转(itr1,j,最后);
while(last!=j)
{
++j;
++itr2;
}
标准:旋转(k,itr2,最后);
返回true;
}
}
标准::旋转(第一,k,最后);
返回false;
}
然后,您可以继续执行以下操作:
int main()
{
unsigned int vec_idx[] = {0,1,2,3,4};
const std::size_t vec_idx_size = sizeof(vec_idx) / sizeof(unsigned int);
{
// All unique combinations of two vectors, for example, 5C2
std::size_t k = 2;
do
{
std::cout << "Vector Indicies: ";
for (std::size_t i = 0; i < k; ++i)
{
std::cout << vec_idx[i] << " ";
}
}
while (next_combination(vec_idx,
vec_idx + k,
vec_idx + vec_idx_size));
}
std::sort(vec_idx,vec_idx + vec_idx_size);
{
// All unique combinations of three vectors, for example, 5C3
std::size_t k = 3;
do
{
std::cout << "Vector Indicies: ";
for (std::size_t i = 0; i < k; ++i)
{
std::cout << vec_idx[i] << " ";
}
}
while (next_combination(vec_idx,
vec_idx + k,
vec_idx + vec_idx_size));
}
return 0;
}
intmain()
{
无符号int-vec_idx[]={0,1,2,3,4};
常量std::size\t vec\u idx\u size=sizeof(vec\u idx)/sizeof(unsigned int);
{
//两个向量的所有唯一组合,例如5C2
标准:尺寸k=2;
做
{
std::难道我不能确切地理解你想说的话吗?你能详细解释一下吗?Th