逐个生成大小为n的子集以降低复杂度
To generate a subset of size n one by one to reduce the complexity?
void AlgoMMPCbar::subs(const std::vector<unsigned int>& org, const std::vector<unsigned int>& pre, size_t k, size_t n, SubSets& c){
if (n <= 1) {
for(size_t i = k; i < org.size(); i++){
std::vector<unsigned int> v(pre);// instead of printing...
v.push_back(org.at(i));
c.push_back(v);
}
} else {
size_t n1 = n - 1;
for(size_t i = k; i != org.size() - n1; i++){ //
std::vector<unsigned int> s(pre);
s.push_back(org.at(i));
subs(org,s,i+1,n1,c);
}
}
}
void AlgoMMPCbar::computeSubSets(const std::vector<unsigned int>& org, size_t& n, SubSets& c){
c.clear(); // clear previous data
std::vector<unsigned int> pre;
pre.reserve(n+1); // for performance
if (n==0)
c.push_back(pre);
else
subs(org,pre,0, n, c);
}
以上代码用于生成大小为n的子集以供进一步测试/处理。但我从不需要测试所有这些生成的子集(在最坏的情况下,它会检查所有子集)。程序中最耗时的部分是子集的生成。现在我想将上面的功能转换为一个接一个地生成子集(不是一次全部生成,因此,我可以随时停止进一步的子集生成)。
请分享您的专业知识,将上述功能转换为子集。next()这样的函数,以节省计算时间。
表示ind
以递增的顺序维护子集中元素的索引,即
ind[0] < ind[1] < ... < ind[n-1]
找到满足
的最小j
j == n-1 || ind[j] + 1 < ind[j+1]
可以通过
转到下一个子集ind[j]++
ind[0] = 0; ind[1] = 1; ... ind[j-1] = j-1
注意,新的ind
数组仍然排序。您可以很容易地从
ind[] = [0, 1, ..., n-1]
将生成所有通过上述过程迭代的子集。如果你使用一些技巧来"维护"上面的j
的值,而不是做线性搜索,你可以有一个快速的代码。
您可以让subs
函数返回bool
。在if
的n<=1
分支中,您可以运行各自的检查,如果当前子集匹配,则保存它并返回true
。在另一个分支中,用if (subs(..)) return true;
之类的东西替换subs
调用。最后加一个return false
。如果你可能需要多个子集,我不知道该怎么做,而且你也不知道合适的子集有多少。
我将创建某种排序状态向量并按字典顺序遍历它。所以如果你有一组M
元素,你想要n
大小的子集,你会有一个向量n
整数对应于所选的索引。然后你做一个算法next_subset(std::vector<bool> &)
,它得到下一个子集。例如,对于5的大小为3的子集:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
我相信你可以发现模式(增加最后一个位置;如果它在末尾,将其移回并增加最后两个位置,等等等等)。
如果想要更高效一点,可以将迭代器存储在原始容器中,如果容器不是随机访问的,也可以将整数对和迭代器存储在一起。
相关文章:
- 函数复杂度分析
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- while循环中while循环的时间复杂度是多少
- 我可以创建一个包含两个变量的 for 循环,但时间复杂度仍然为 O(n) 吗?
- 函数的时间复杂度是多少?
- 如何检查两个 std::向量在小于 O(n) 的时间复杂度内是否相等
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 如何计算此排序函数的时间复杂度?
- 计算两个代码块的时间复杂度
- 当 A 在 for 循环中调用函数 B 时,如何计算函数 A 的空间复杂度?
- C++ 中具有 O(1) 搜索时间复杂度的数据结构
- 具有嵌套 if-else 的循环的时间复杂度
- C++中 std::map 的运行时复杂度是多少?
- 将树节点添加到向量向量中的 n 元树遍历的平均和最坏情况时间复杂度是多少?
- 如何计算函数的时间复杂度?
- 求解包含"variables"的 T(n) 时间复杂度
- 确定 for 循环的不同大 O 复杂度
- 此print_star函数的运行时复杂度是多少?
- 查找数字是否为 2 的幂的时间复杂度
- 逐个生成大小为n的子集以降低复杂度