整数v
的组合是一组K个整数,使得它们的和为v
(并且顺序很重要)。例如,2个3大小的组合物是:
2 0 0
1 1 0
1 0 1
0 2 0
0 1 1
0 0 2
可以找到获取这些组合的简单C ++算法here:
void print(std::vector<int>& a) {
std::ostream_iterator<int> i(std::cout, " ");
std::copy(a.begin(), a.end(), i);
std::cout << "\n";
}
void recurse(std::vector<int>& a, int pos, int remaining) {
if (remaining == 0) { print(a); return; }
if (pos == a.size()) { return; }
for (int i = remaining; i >= 0; --i) {
a[pos] = i;
recurse(a, pos + 1, remaining - i);
}
}
int main() {
int v = 2, k = 3;
std::vector<int> a(k);
recurse(a, 0, v);
return 0;
}
但我需要更复杂的东西:
我需要找到整数 vector 的组合。也就是说,给定矢量v =(v1,v2,v3),我需要找到他们所有的个体成分,然后创建所有可能的组合。如果C是一个矩阵,我在第一行放置v1的分区,在第二行放置v2的分区,在第三行放置v3的分区,那么C中的行f
的总和给出{ {1}}
例如,大小为F = 2的向量(1,2),如果我们设置K = 2,则可以分解为:
v[f]
目标是为每个可能的C应用一些函数。我怎么能用它来做C ++?我不介意使用生成器,递归或迭代算法,只要它尽职尽责(尽可能快)。
的Python
使用递归# all sets of K vectors such that their sum is (1,2)
C_1 = 1,0 C_2 = 1,0 C_3 = 1,0 C_4 = 0,1 C_5 = 0,1 C_6 = 0,1
2,0 1,1 0,2 2,0 1,1 0,2
和yield
库
itertools
答案 0 :(得分:0)
使用递归的解决方案:
我们知道如何生成整数的所有组合(请参阅问题中的代码)。为了生成表示F整数组合的所有组合的矩阵,我们只创建整数f的所有可能组合,并且每次我们找到新组合时,我们再次调用算法以找到整数f + 1的所有可能组合。每当我们在最后一个整数中找到一个合成时,我们就完成了一个有效的矩阵C.
#include <iostream>
#include <armadillo>
using namespace arma;
void recursevec(arma::ivec v, arma::imat& C, int f, int pos, int remaining) {
// If there is no remaining left, we completed a new composition for v[f]
if (remaining == 0) {
// If elements in v left, get the combinations of v[f+1]
if(f < (C.n_rows-1)){
recursevec(v, C, f+1, 0, v[f+1]);
return;
}
// If last f, then we are done and we completed a new C
else {
std::cout << C << std::endl;
return;
}
}
// If position pointer got out of the vector,
// then there is nothing to do
if (pos == C.n_cols) { return; }
// Else, continue allocating the remaining in all possible ways
for (int i = remaining; i >= 0; --i) {
C(f, pos) = i;
recursevec(v, C, f, pos + 1, remaining - i);
}
}
// Test vector compositions
int main() {
arma::ivec v = {1,2};
int F = v.size();
int K = 2;
arma::imat C(F,K);
recursevec(v, C, 0, 0, v[0]);
return 0;
}