在interval_map的共域中选择



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

为此,我想使用梦幻般的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;
        }
}

首先,观察,由于间隔是闭合的,[0,4][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]; 
}

这导致:

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 << "nn";
    for (auto&& iter : imap) {
        std::cout << iter.first << " - " << iter.second << std::endl;
    }
    Process key{4};
    std::cout << key << " - " << inverted(imap)[key] << "n";
}

更多注意事项

直接支持查询中的多个键,请参阅此处的指针断言:

  • split_interval_map用法,高效查找与点相交的所有间隔
  • 提升multi_index_container搜索落在两个字段定义的时间间隔内的记录

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

  • 这里提升::multi_index_container,对标准::在容器内设置的操作

相关内容

  • 没有找到相关文章

最新更新