[英]split_interval_map usage, efficient find all interval intersecting a point
#include <iostream>
#include <boost/icl/split_interval_map.hpp>
using namespace std;
using namespace boost::icl;
int main()
{
split_interval_map<double, int> intervals;
intervals.add(make_pair(interval<double>::closed(0.,1.),0));
intervals.add(make_pair(interval<double>::closed(1.,2.),1));
intervals.add(make_pair(interval<double>::closed(3.,4.),2));
intervals.add(make_pair(interval<double>::closed(2.,4.),3));
intervals.add(make_pair(interval<double>::closed(1.5,3.5),4));
std::vector<double> probes = { 0.23, 1., 1.33 , 1.57, 3.49, 3.51 };
for(auto probe : probes)
{
std::cout << std::endl<< "probe " << probe << std::endl;
auto lower = intervals.lower_bound(interval<double>::closed(probe, probe));
auto upper = intervals.upper_bound(interval<double>::closed(probe, probe));
while(lower != upper)
{
std::cout << lower->second << " ";
++lower;
}
}
}
int
s) of the interval containing 'probe'. int
)。 (intersection?) std::set<int>
as value, but in the documentation it is stated, that this has a huge impact on performance. std::set<int>
作为值来实现这一点,但是在文档中指出,这会对性能产生巨大影响。 Seems like split_interval_map contains that information but i don't know how to retrieve it it.
- What i get are the indices added up.
我得到的是加起来的指数。 But i'm looking for all the values (ints) of the interval containing 'probe'.
但是我正在寻找包含“探针”的间隔的所有值(整数)。 (intersection?)
(路口?)
You get all the values (the co-domain values) combined using the combiner of your choosing. 您可以使用选择的合并器合并所有值(共域值)。 For an arithmetic type, that implies summation.
对于算术类型,这意味着求和。
If your co-domain is an index, clearly summation is not meaningful combiner, and you should choose something else. 如果您的共同域是一个索引,则显然求和对合并器没有意义,您应该选择其他内容。
I could achieve this with
std::set<int>
as value, but in the documentation it is stated, that this has a huge impact on performance.我可以使用
std::set<int>
作为值来实现这一点,但是在文档中指出,这会对性能产生巨大影响。
As always, correct goes before performance. 一如既往,正确是表现的先行。 If it's what you need, it's what you need.
如果这是您需要的,那就是您的需要。
Seems like split_interval_map contains that information but i don't know how to retrieve it it.
好像split_interval_map包含该信息,但我不知道如何检索它。
Not with the chosen co-domain: the combiner loses the original information if intervals overlap (and you use add
, not set
). 不适用于所选的共同域:如果间隔重叠(并且您使用
add
,而不是set
),则合并器将丢失原始信息。
I need only a highly efficient lookup like in this example.
我只需要像此示例中那样的高效查找。 I don't need the intersecting interval ranges anymore.
我不再需要相交的间隔范围。 Is boost icl too heavy for this?
Boost icl是否太重了?
You could use equal_range
instead of lower_bound
/ upper_bound
: 您可以使用
equal_range
而不是lower_bound
/ upper_bound
:
for (auto probe : { 0.23, 1., 1.33, 1.57, 3.49, 3.51 }) {
std::cout << "\nprobe " << probe << ": ";
for (auto& p : boost::make_iterator_range(m.equal_range(Ival::closed(probe, probe)))) {
std::cout << p.second << " ";
}
}
Prints 版画
probe 0.23:
probe 1: 1
probe 1.33: 1
probe 1.57: 4
probe 3.49: 4
probe 3.51: 3
m.add({Ival::closed(0., 1.), 0});
m.add({Ival::closed(1., 2.), 1});
m.add({Ival::closed(3., 4.), 2});
These intervals subtly overlap. 这些间隔巧妙地重叠。
[0, 1]
and [1, 2]
have [1,1]
in common. [0, 1]
和[1, 2]
有共同的[1,1]
。 Did you really mean left_open
? 你真的是说
left_open
吗? ( [0, 1)
and [1, 2)
have no overlap). (
[0, 1)
和[1, 2)
没有重叠)。
m.add({Ival::closed(2., 4.), 3});
m.add({Ival::closed(1.5, 3.5), 4});
If you were surprised by the fact that this combines the values already in the overlapping interval(s), did you mean to replace them? 如果您对这样的事实感到惊讶,那就是它合并了重叠区间中已经存在的值,您是要替换它们吗?
m.set({Ival::closed(2., 4.), 3});
m.set({Ival::closed(1.5, 3.5), 4});
You could do the intersection with the set of probes at once: 您可以一次与一组探针进行交集:
Set probes; probes.insert(0.23); probes.insert(1.); probes.insert(1.33); probes.insert(1.57); probes.insert(3.49); probes.insert(3.51); std::cout << std::endl << "all: " << (m & probes) << "\\n";
Prints: 印刷品:
all: {([1,1]->1)([1.33,1.33]->1)([1.57,1.57]->4)([3.49,3.49]->4)([3.51,3.51]->3)}
To (maybe?) optimize that a little: 要(也许?)优化一点:
using Map = icl::split_interval_map<double, boost::container::flat_set<int> >;
If the sets are going to be small, consider specifying small_vector for that flat_set's sequence type: 如果集合将很小,请考虑为该flat_set的序列类型指定small_vector:
icl::split_interval_map<double, boost::container::flat_set<int, std::less<int>, boost::container::small_vector<int, 4> > >;
All else just still works: Live On Coliru 所有其他一切仍然有效: Live on Coliru
Completely OUT-OF-THE-BOX : are you modeling geometric regions? 完全是现成的 :您是否正在对几何区域建模? Like intervals on a timeline?
像时间线上的间隔一样? Or just line-segments on an axis?
还是仅在轴上设置线段? In that case, consider
boost::geometry::index::rtree<>
在这种情况下,请考虑
boost::geometry::index::rtree<>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.