在interval_map

时间:2018-08-09 13:12:12

标签: c++ boost boost-icl

在我当前的项目流程中,如果它们相邻,则需要合并可区分的间隔。

为此,我想使用出色的boost::icl库。每个进程都可以通过其ID唯一标识。

首先,我在interval_map中添加了一些时间间隔。现在我想完成两件事:

  • 遍历所有发生的过程类型(此处id = 1、4、7)
  • 其次,以某种方式子集中的所有进程进行迭代,以使重叠间隔自动合并。

这是我到目前为止得到的:

#include <iostream>
#include <set>
#include <boost/icl/interval_map.hpp>
#include "boost/icl/closed_interval.hpp"

struct Process {
    int id;
};

bool operator==(const Process& p, const Process& q) {
    return p.id == q.id;
}

bool operator<(const Process& p, const Process& q) {
    return p.id < q.id;
}

std::ostream& operator<<(std::ostream& str, const Process& p) {
    str << "Process{" << p.id << "}";
    return str;
}
int main(int, char**) {
    using namespace boost::icl;
    interval_map<double, std::set<Process>> imap;   
    imap.add({ interval<double>::closed(0., 4.),{ Process{ 4 } } });
    imap.add({ interval<double>::closed(2., 6.),{ Process{ 1 } } });
    imap.add({ interval<double>::closed(4., 9.),{ Process{ 4 } } });
    imap.add({ interval<double>::closed(8., 8.),{ Process{ 7 } } });
    for (auto&& iter : imap) {
        std::cout << iter.first << " - " << iter.second<<  std::endl;
    }
    for (auto iter : find(imap, { Process{4} })) { // How to implement find on codomain
        // Should print:
        // [0.,4.] - { Process{4}}
        // [4.,9.] - { Process{4}}
        std::cout << iter.first << " - " << iter.second << std::endl;
        }
}

1 个答案:

答案 0 :(得分:1)

首先,观察一下,由于间隔是封闭的,[4,6]right_open实际上不是相邻,而是重叠的。您是说#include "boost/icl/closed_interval.hpp" #include <boost/icl/interval_map.hpp> #include <iostream> #include <set> #include <map> struct Process { int id; friend bool operator==(const Process& p, const Process& q) { return p.id == q.id; } friend bool operator<(const Process& p, const Process& q) { return p.id < q.id; } friend std::ostream& operator<<(std::ostream& str, const Process& p) { return str << "Process{" << p.id << "}"; } }; int main(int, char**) { using namespace boost::icl; using Map = std::map<Process, boost::icl::interval_set<double> >; // instead of boost::icl::interval_map<double, std::set<Process> >; using IVal = Map::mapped_type::interval_type; Map imap; imap[{4}] += IVal::right_open(0, 4); imap[{1}] += IVal::right_open(2, 6); imap[{4}] += IVal::right_open(4, 9); imap[{7}] += IVal::closed(8, 8); //for (auto&& el : imap) { std::cout << el.first << " - " << el.second << std::endl; } Process key{4}; std::cout << key << " - " << imap[key]; } 吗?

第二,区间映射为函数建模,不能保证映射为injective

在示例的有限范围内,您似乎希望反转数据结构以得出:

Process{4} - {[0,9)}

结果是:

template <typename IMap>
auto inverted(IMap const& imap) {
    std::map<typename IMap::codomain_type::value_type, boost::icl::interval_set<typename IMap::domain_type> > output;

    for (auto& el : imap)
        for (auto& key: el.second)
            output[key] += el.first;

    return output;
}

我想您的意思是“以一种自动完成重叠间隔的合并的方式。”

同时拥有

当然,您可以从原始数据结构中得出逆映射:

#include "boost/icl/closed_interval.hpp"
#include <boost/icl/interval_map.hpp>
#include <iostream>
#include <set>

struct Process {
    int id;

    friend bool operator==(const Process& p, const Process& q) { return p.id == q.id; }
    friend bool operator<(const Process& p, const Process& q) { return p.id < q.id; }
};

std::ostream& operator<<(std::ostream& str, const Process& p) {
    str << "Process{" << p.id << "}";
    return str;
}

template <typename IMap>
auto inverted(IMap const& imap) {
    std::map<typename IMap::codomain_type::value_type, boost::icl::interval_set<typename IMap::domain_type> > output;

    for (auto& el : imap)
        for (auto& key: el.second)
            output[key] += el.first;

    return output;
}

int main(int, char**) {
    using namespace boost::icl;
    using IMap = boost::icl::interval_map<double, std::set<Process> >;
    using IVal = IMap::interval_type;
    IMap imap;
    imap.add({ IVal::right_open(0, 4), {Process{ 4 }} });
    imap.add({ IVal::right_open(2, 6), {Process{ 1 }} });
    imap.add({ IVal::right_open(4, 9), {Process{ 4 }} });
    imap.add({ IVal::closed(8, 8), {Process{ 7 }} });
    std::cout << imap << "\n\n";
    for (auto&& iter : imap) {
        std::cout << iter.first << " - " << iter.second << std::endl;
    }
    Process key{4};
    std::cout << key << " - " << inverted(imap)[key] << "\n";
}

查看 Live On Coliru

 index=time >= 9.6 & tsyn <= 13.5; %time boundaries of first time signal
 time1=tsyn(index); %first time signal
 time_f=resample(time1,830,3901);
 Rate1=CLU_YR1(index)              %first rate signal
 Rate_f=resample(Rate1,830,3901);

 index2 = cm.Time.data >= 26.3 & cm.Time.data <= 30.45; %time boundaries of second time signal
 time2=cm.Time.data(index2)   %second time signal
 Rat2=cm.BodySensor_SC1_Omega_B_z.data*(-180/pi)        %second rate signal
 Rate_p=Rat2(index2)

更多注意事项

直接支持在中查询多个键,请参见此处的各种指针:

您始终可以构建自己的数据结构,该结构提供双向索引,例如所示的