interval_map 的密码域中的选择
Selection in the codomain of interval_map
在我目前的项目中processes,可区分的区间,需要合并,如果它们是相邻的。
为此,我想使用很棒的 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
吗?
二、区间映射建模一个函数,映射不保证是injective.
在您示例的有限范围内,您似乎更愿意反转数据结构,以得出:
#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)}
我认为你对 "in such a way that merging of overlapping intervals is automatically done" 的意思是什么。
两者兼得
当然你可以从原始数据结构推导出逆映射:
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";
}
更多笔记
直接支持查询 域 中的多个键,请在此处查看各种指针:
- boost multi_index_container search for records that fall within intervals defined by two fields
您始终可以构建自己的提供双向索引的数据结构,例如所示
- 此处
在我目前的项目中processes,可区分的区间,需要合并,如果它们是相邻的。
为此,我想使用很棒的 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
吗?
二、区间映射建模一个函数,映射不保证是injective.
在您示例的有限范围内,您似乎更愿意反转数据结构,以得出:
#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)}
我认为你对 "in such a way that merging of overlapping intervals is automatically done" 的意思是什么。
两者兼得
当然你可以从原始数据结构推导出逆映射:
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";
}
更多笔记
直接支持查询 域 中的多个键,请在此处查看各种指针:
- boost multi_index_container search for records that fall within intervals defined by two fields
您始终可以构建自己的提供双向索引的数据结构,例如所示
- 此处