C++ N个Boost区间的组合

C++ N个Boost区间的组合,c++,algorithm,boost,intervals,boost-icl,C++,Algorithm,Boost,Intervals,Boost Icl,我有一个服务,它在4个不同的位置有停机。我正在将每个位置的停机建模为一个Boost ICL interval_集合。我想知道至少N个位置何时有活动停机 因此,下面,我实现了一个组合算法,这样我就可以通过区间集交点在元素集之间创建组合 当这个过程结束时,我应该设置一定数量的间隔,每个间隔同时定义N个位置的中断,最后一步将加入它们以获得所需的完整画面 问题是我目前正在调试代码,当打印每个交叉点的时间到来时,输出文本变得疯狂(即使我使用gdb一步一步地调试),我看不到它们,导致大量CPU使用 我猜,不

我有一个服务,它在4个不同的位置有停机。我正在将每个位置的停机建模为一个Boost ICL interval_集合。我想知道至少N个位置何时有活动停机

因此,下面,我实现了一个组合算法,这样我就可以通过区间集交点在元素集之间创建组合

当这个过程结束时,我应该设置一定数量的间隔,每个间隔同时定义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;
}
#包括
#包括
#包括
#包括
int main(){
//初始化测试数据
std::矢量输出位置;

对于置换循环末尾的(unsigned int j=0;j),您可以编写:

numCombinations++;
std::cout << "[-INTERSEC-] " << combinations[numCombinations] << std::endl;  // The problem appears here
或者,对于c++03

std::cout << "[-INTERSEC-] " << combinations[combinations.size()-1] << "\n";
std::coutAs,这里有一种“高级”方法

Boost ICL容器不仅仅是“美化的间隔起点/终点对”的容器。它们旨在以一种通用优化的方式实现组合、搜索的业务

所以你不必这么做。 如果你让图书馆做它应该做的事:

using TimePoint = unsigned;
using DownTimes = boost::icl::interval_set<TimePoint>;
using Interval  = DownTimes::interval_type;
using Records   = std::vector<DownTimes>;
  • 好的,让我们进行筛选。我们只需要在下行图上工作的谓词,对吗

    // define threshold 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";
    
    // 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});
    
    // define threshold 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";
    
    #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";
    }
    
    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]}