Rom*_*dgz 4 c++ algorithm boost intervals boost-icl
我有一个服务,在4个不同的地方停运.我将每个位置中断建模为Boost ICL interval_set.我想知道什么时候至少有N个地点有活动中断.
因此,在这个答案之后,我实现了一个组合算法,因此我可以通过interval_set交集创建elemenets之间的组合.
当这个过程结束时,我应该有一定数量的interval_set,每个interval_set同时定义N个位置的中断,最后一步将加入它们以获得所需的全图.
问题是我正在调试代码,当打印每个交集的时间到了,输出文本变得疯狂(即使我正在逐步使用gdb进行调试),我看不到它们,导致大量CPU使用.
我想我不知何故发送输出的内存比我应该多,但我看不出问题出在哪里.
这是一个SSCCE:
#include <boost/icl/interval_set.hpp>
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
// Initializing data for test
std::vector<boost::icl::interval_set<unsigned int> > outagesPerLocation;
for(unsigned int j=0; j<4; j++){
boost::icl::interval_set<unsigned int> outages;
for(unsigned int i=0; i<5; i++){
outages += boost::icl::discrete_interval<unsigned int>::closed(
(i*10), ((i*10) + 5 - j));
}
std::cout << "[Location " << (j+1) << "] " << outages << std::endl;
outagesPerLocation.push_back(outages);
}
// So now we have a vector of interval_sets, one per location. We will combine
// them so we get an interval_set defined for those periods where at least
// 2 locations have an outage (N)
unsigned int simultaneusOutagesRequired = 2; // (N)
// Create a bool vector in order to filter permutations, and only get
// the sorted permutations (which equals the combinations)
std::vector<bool> auxVector(outagesPerLocation.size());
std::fill(auxVector.begin() + simultaneusOutagesRequired, auxVector.end(), true);
// Create a vector where combinations will be stored
std::vector<boost::icl::interval_set<unsigned int> > combinations;
// Get all the combinations of N elements
unsigned int numCombinations = 0;
do{
bool firstElementSet = false;
for(unsigned int i=0; i<auxVector.size(); i++){
if(!auxVector[i]){
if(!firstElementSet){
// First location, insert to combinations vector
combinations.push_back(outagesPerLocation[i]);
firstElementSet = true;
}
else{
// Intersect with the other locations
combinations[numCombinations] -= outagesPerLocation[i];
}
}
}
numCombinations++;
std::cout << "[-INTERSEC-] " << combinations[numCombinations] << std::endl; // The problem appears here
}
while(std::next_permutation(auxVector.begin(), auxVector.end()));
// Get the union of the intersections and see the results
boost::icl::interval_set<unsigned int> finalOutages;
for(std::vector<boost::icl::interval_set<unsigned int> >::iterator
it = combinations.begin(); it != combinations.end(); it++){
finalOutages += *it;
}
std::cout << finalOutages << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
seh*_*ehe 11
正如我猜测的那样,这里有一种"高级"方法.
提升ICL容器不仅仅是"美化的间隔起点/终点对"的容器.他们的目的是实现这一点相结合,搜索,在一般优化的方式经营.
如果你让图书馆做它应该做的事情:
using TimePoint = unsigned;
using DownTimes = boost::icl::interval_set<TimePoint>;
using Interval = DownTimes::interval_type;
using Records = std::vector<DownTimes>;
Run Code Online (Sandbox Code Playgroud)
使用功能域typedef会引发更高级别的方法.现在,让我们问一下假设的"商业问题":
我们对每个位置停机记录实际上想做些什么?
好吧,我们基本上想要
好的,工程师:实现它!
嗯.清点.它能有多难?
elegant优雅解决方案的关键是选择正确的数据结构
using Tally = unsigned; // or: bit mask representing affected locations?
using DownMap = boost::icl::interval_map<TimePoint, Tally>;
Run Code Online (Sandbox Code Playgroud)
现在它只是批量插入:
// We will do a tally of affected locations per time slot
DownMap tallied;
for (auto& location : records)
for (auto& incident : location)
tallied.add({incident, 1u});
Run Code Online (Sandbox Code Playgroud)好的,让我们过滤一下.我们只需要适用于我们的DownMap的谓词
// define threshold where at least 2 locations have an outage
auto exceeds_threshold = [](DownMap::value_type const& slot) {
return slot.second >= 2;
};
Run Code Online (Sandbox Code Playgroud)合并时间段!
其实.我们只是创建另一个DownTimes集.只是,这次不是每个地点.
数据结构的选择再次获胜:
// just printing the union of any criticals:
DownTimes merged;
for (auto&& slot : tallied | filtered(exceeds_threshold) | map_keys)
merged.insert(slot);
Run Code Online (Sandbox Code Playgroud)报告!
std::cout << "Criticals: " << merged << "\n";
Run Code Online (Sandbox Code Playgroud)
请注意,我们无处接近操纵数组索引,重叠或非重叠间隔,闭合或开放边界.或者,[eeeeek!]收集元素的强力排列.
我们刚刚阐述了目标,让图书馆开展工作.
#include <boost/icl/interval_set.hpp>
#include <boost/icl/interval_map.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/numeric.hpp>
#include <boost/range/irange.hpp>
#include <algorithm>
#include <iostream>
#include <vector>
using TimePoint = unsigned;
using DownTimes = boost::icl::interval_set<TimePoint>;
using Interval = DownTimes::interval_type;
using Records = std::vector<DownTimes>;
using Tally = unsigned; // or: bit mask representing affected locations?
using DownMap = boost::icl::interval_map<TimePoint, Tally>;
// Just for fun, removed the explicit loops from the generation too. Obviously,
// this is bit gratuitous :)
static DownTimes generate_downtime(int j) {
return boost::accumulate(
boost::irange(0, 5),
DownTimes{},
[j](DownTimes accum, int i) { return accum + Interval::closed((i*10), ((i*10) + 5 - j)); }
);
}
int main() {
// Initializing data for test
using namespace boost::adaptors;
auto const records = boost::copy_range<Records>(boost::irange(0,4) | transformed(generate_downtime));
for (auto location : records | indexed()) {
std::cout << "Location " << (location.index()+1) << " " << location.value() << std::endl;
}
// We will do a tally of affected locations per time slot
DownMap tallied;
for (auto& location : records)
for (auto& incident : location)
tallied.add({incident, 1u});
// We will combine them so we get an interval_set defined for those periods
// where at least 2 locations have an outage
auto exceeds_threshold = [](DownMap::value_type const& slot) {
return slot.second >= 2;
};
// just printing the union of any criticals:
DownTimes merged;
for (auto&& slot : tallied | filtered(exceeds_threshold) | map_keys)
merged.insert(slot);
std::cout << "Criticals: " << merged << "\n";
}
Run Code Online (Sandbox Code Playgroud)
哪个打印
Location 1 {[0,5][10,15][20,25][30,35][40,45]}
Location 2 {[0,4][10,14][20,24][30,34][40,44]}
Location 3 {[0,3][10,13][20,23][30,33][40,43]}
Location 4 {[0,2][10,12][20,22][30,32][40,42]}
Criticals: {[0,4][10,14][20,24][30,34][40,44]}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
597 次 |
最近记录: |