我使用 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+ε)
来建模?
是的,我认为您可以通过使用离散时域来消除您描述的所有问题。它将所有“混乱”移至数据的采样边缘,而不是用复杂性阻碍您的逻辑。
此外,它还适合在静态有界区间上进行更多操作。例如。连续域不允许具有静态间隔的单例。此限制记录在表 1.14
T | 离散 _间隔 |
连续 _间隔 |
右开 _间隔 |
左开 _间隔 |
关闭 _间隔 |
打开 _间隔 |
---|---|---|---|---|---|---|
区间界限 | 动态 | 动态 | 静态 | 静态 | 静态 | 静态 |
表格 | 不对称 | 不对称 | 对称 | 对称 | ||
构建 | ||||||
|
d | c | d | d | d | d |
|
d | c | dc | dc | d | d |
... |
以及更多详细信息,请参阅间隔构造:
构建 | 描述 |
---|---|
|
构造一个仅包含一个元素值的区间。对于 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)