如何在 boost::icl 容器中允许静态有界、连续的单例间隔

问题描述 投票:0回答:1

我使用 boost ICL 对时间到状态和事件的映射进行建模,其中我将时间建模为

double
。有些事件是瞬时的,即它们不会在一段时间间隔内发生,而是在单个时间点发生,我可以在概念上将其建模为单例间隔。然而,当尝试将这些概念添加为单例间隔来增强 ICL 时,我遇到了一些问题。

  • A

    boost::icl::right_open_interval
    (使用
    #define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS
    时的默认类型)单例似乎无效 -
    boost::icl::intersects
    在所有情况下都返回
    false
    ,并且交集在所有情况下都返回
    [0,0)
    。后者似乎甚至表明了一个无效的间隔。这是可以理解的,因为
    [a,a)
    表示集合
    {x | a <= x < a}
    ,即空集。

  • 因此,
  • A

    boost::icl::closed_interval
    似乎更适合对单例进行建模。然而,由于静态断言
    DomainT
    ,它不能默认构造为
    double
    BOOST_STATIC_ASSERT((icl::is_discrete<DomainT>::value));
    。然而,间隔容器需要默认的可构造间隔。

所以我有点不知道该做什么。这只是选择正确的间隔类型还是定义自定义间隔类型的问题?单例间隔是否适用于连续类型,或者这是我的概念误解?毕竟,“接触”间隔和与单例相交的概念变得非常混乱。区间

[a,b)
[b,c)
明显接触,而闭区间
[a,b]
[b,c]
将在单例
[b,b]
中相交。所以也许单例根本不起作用,需要通过一些有限的
[a, a+ε)
来建模?

boost intervals boost-icl
1个回答
0
投票

是的,我认为您可以通过使用离散时域来消除您描述的所有问题。它将所有“混乱”移至数据的采样边缘,而不是用复杂性阻碍您的逻辑。

此外,它还适合在静态有界区间上进行更多操作。例如。连续域不允许具有静态间隔的单例。此限制记录在表 1.14

T 离散
_间隔
连续
_间隔
右开
_间隔
左开
_间隔
关闭
_间隔
打开
_间隔
区间界限 动态 动态 静态 静态 静态 静态
表格 不对称 不对称 对称 对称
构建
T singleton(const P&)
d c d d d d
T construct(const P&, const P&)
d c dc dc d d
...

以及更多详细信息,请参阅间隔构造

构建 描述
T singleton(const P& value)
构造一个仅包含一个元素值的区间。对于 icl 的所有区间类型,可以为离散域类型构建单子。对于连续域类型,只有 Continuous_interval 能够构造单例。

示例

有一个库示例演示/澄清了其中大部分要点,并且评论值得一读。它甚至定义了一个玩具

Time
类型来离散建模时间。应该很容易用
std::chrono
time_point
替换它,例如因为 C++11 可能无处不在。这是稍微现代化的示例:

#include <cmath>

// We can change the library default for the interval types by defining 
#define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS
// prior to other inluces from the icl.
// The interval type that is automatically used with interval
// containers then is the statically bounded right_open_interval.

#include <boost/icl/interval_set.hpp>
#include <boost/icl/split_interval_set.hpp>
// The statically bounded interval type 'right_open_interval'
// is indirectly included via interval containers.

#include "toytime.hpp"
#include <boost/icl/rational.hpp>

using namespace boost::icl;

int main() {
    std::cout << ">> Interval Container Library: Sample static_interval.cpp <<\n";

    // Statically bounded intervals are the user defined library default for 
    // interval parameters in interval containers now.
    static_assert(std::is_same_v<interval_set<int>::interval_type, right_open_interval<int>>);
    static_assert(std::is_same_v<interval_set<float>::interval_type, right_open_interval<float>>);

    // As we can see the library default both for discrete and continuous
    // domain_types T is 'right_open_interval<T>'.
    // The user defined library default for intervals is also available via 
    // the template 'interval':
    static_assert(std::is_same<interval<int>::type, right_open_interval<int>>::value);

    // Again we are declaring and initializing the four test intervals that have been used
    // in the example 'interval' and 'dynamic_interval'
    interval<int>::type    int_interval  = interval<int>::right_open(3, 8); // shifted the upper bound
    interval<double>::type sqrt_interval = interval<double>::right_open(1/sqrt(2.0), sqrt(2.0));

    // Interval ("Barcelona", "Boston"] can not be represented because there is no 'steppable next' on
    // lower bound "Barcelona". Ok. this is a different interval:
    interval<std::string>::type city_interval = interval<std::string>::right_open("Barcelona", "Boston");

    // Toy Time is discrete again so we can transfrom open(Time(monday,8,30), Time(monday,17,20))
    //                                       to right_open(Time(monday,8,31), Time(monday,17,20))
    auto time_interval = interval<Time>::right_open({monday, 8, 31}, {monday, 17, 20});

#define CONTAINED(ival, val)                                                                                 \
    ival << " does " << (contains(ival, val) ? "" : "NOT ") << "contain " << #val << std::endl

    std::cout << "right_open_interval<int>   : " << int_interval  << std::endl;
    std::cout << "right_open_interval<double>: " << CONTAINED(sqrt_interval, sqrt(2.0));
    std::cout << "right_open_interval<string>: " << CONTAINED(city_interval, "Barcelona");
    std::cout << "right_open_interval<string>: " << CONTAINED(city_interval, "Boston");
    std::cout << "right_open_interval<Time>  : " << time_interval << "\n";

    using Ratio = boost::rational<int>;

    // Using statically bounded intervals does not allows to apply operations
    // with elements on all interval containers, if their domain_type is continuous.
    // The code that follows is identical to example 'dynamic_interval'. Only 'internally'
    // the library default for the interval template now is 'right_open_interval'
    auto unit_interval = interval<Ratio>::right_open(0, 1);
    interval_set<Ratio>  unit_set(unit_interval);
    interval_set<Ratio > ratio_set(unit_set);
    //ratio_set -= Ratio(1, 3); // This line will not compile, because we can not
                              //// represent a singleton interval as right_open_interval.
}

印刷

>> Interval Container Library: Sample static_interval.cpp <<
right_open_interval<int>   : [3,8)
right_open_interval<double>: [0.707107,1.41421) does NOT contain sqrt(2.0)
right_open_interval<string>: [Barcelona,Boston) does contain "Barcelona"
right_open_interval<string>: [Barcelona,Boston) does NOT contain "Boston"
right_open_interval<Time>  : [mon:08:31,mon:17:20)
© www.soinside.com 2019 - 2024. All rights reserved.