更新std::set,只保留最小的值
Update std::set to keep only the smallest values
对于某些算法,我必须在n
-元素整数集的所有排列上调用函数f
范围从1到n。最后,我对产生最小f
值的100种排列感兴趣。
我能想出的最好的解决方案是下面这个。但它有一个严重的缺点。当n
增加时,fPerm
会消耗大量的内存。
修剪fPerm
的最佳解决方案是什么,以便它只保留迄今为止发现的最好的100个解决方案?
#include <vector>
#include <set>
#include <algorithm>
#include <numeric>
#include <boost/random.hpp>
boost::random::mt19937 rng;
// Actually, f is a very complex function, that I'm not posting here.
double f(const std::vector<int>& perm) {
boost::random::uniform_real_distribution<> gen;
return gen(rng);
}
typedef std::pair<std::vector<int>, double> TValue;
void main(int argc, int args) {
auto comp = [](const TValue& v1, const TValue& v2) { return v1.second < v2.second; };
std::set<TValue, decltype(comp) > fPerm(comp);
int n = 7;
std::vector<int> perm(n);
std::iota(perm.begin(), perm.end(),1);
do {
fPerm.insert(TValue(perm, f(perm)));
} while (std::next_permutation(perm.begin(), perm.end()));
// Get first smallest 100 values, if there are such many.
int m = 100 < fPerm.size() ? 100 : fPerm.size();
auto iterEnd = fPerm.begin();
std::advance(iterEnd, m);
for (auto iter = fPerm.begin(); iter != iterEnd; iter++) {
std::cout << iter->second << std::endl;
}
}
我修改了上面的解决方案,通过实现一种trim函数来擦除集合中最大的元素。正如下面所指出的,std::priority_queue
的使用可能更短。
#include <vector>
#include <set>
#include <algorithm>
#include <numeric>
#include <boost/random.hpp>
boost::random::mt19937 rng;
double f(const std::vector<int>& perm) {
boost::random::uniform_real_distribution<> gen;
return gen(rng);
}
typedef std::pair<std::vector<int>, double> TValue;
void main(int argc, int args) {
auto comp = [](const TValue& v1, const TValue& v2) { return v1.second < v2.second; };
std::set<TValue, decltype(comp) > fPerm(comp);
int n = 7;
std::vector<int> perm(7);
std::iota(perm.begin(), perm.end(),1);
do {
fPerm.insert(TValue(perm, f(perm)));
if (fPerm.size() > 100) {
fPerm.erase(*fPerm.rbegin());
}
} while (std::next_permutation(perm.begin(), perm.end()));
// Get first smallest 100 values, if there are such many.
int m = 100 < fPerm.size() ? 100 : fPerm.size();
auto iterEnd = fPerm.begin();
std::advance(iterEnd, m);
for (auto iter = fPerm.begin(); iter != iterEnd; iter++) {
std::cout << iter->second << std::endl;
}
}
相关文章:
- 当为可变性配置时,boost::heap::d_ary_heap 保留的额外 std::list 的目的是什么?
- std::向量迭代器和调整大小/保留的奇怪/有趣行为
- 如何从 std::optional 中获取 QByteArray<QByteArray>,并在没有其他 malloc 的情况下保留 std::nullopt?
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- 在 push_back() 之前保留非空 std::vector 的正确方法
- 当 std::make_tuple 是 r 值引用时,如何保留 std::string 类型
- std::字符串替换不保留结尾?
- std::vector<std::vector<int>>:调试断言失败。C++矢量下标超出范围保留内存
- 如何使用 std::vector<std::tuple<A,B>> 来管理内存(调整大小、保留,...),但实际上将 As 保留在 B 之前,连续
- std::unordered_set::保留容器内存要求的角色?
- 如何将STD :: String转换为QString保留值,反之亦然
- 为什么 std::unordered_map 有保留方法?
- 写入 std::vector 的保留空间会导致分段错误吗?
- C++,2D std::vector,我是否需要显式保留和推送空矢量
- 应该包含哪些标头才能在 Linux 上的 c++ 代码中保留前缀 std::
- 矢量元素如何在矢量 std::move 之后保留其原始地址
- 保留 std::vector 的前 N 个元素<>并删除其余元素
- 如何在不复制和保留 std::string 对象的情况下获得 C++ std::string 字符数据的所有权
- 保留 std::initializer_list 的副本是否安全?理由是什么
- 调整保留std::vector大小时的c++内存分配