我需要一个可以在一个维度内存储非重叠范围的数据结构。不需要完全覆盖整个维度范围。
一个例子是会议室调度程序。维度是时间。没有两个时间表可能重叠。会议室并非始终安排。换句话说,在给定时间内,最多只能有一个时间表。
快速解决方案是存储开始和结束时间的范围。
Range {
Date start
Date end
}
这是非规范化的,要求容器不强制执行。对于两个相邻的范围,前一个'结束将在下一个开始时是多余的。
另一种方案可能涉及为每个范围存储一个边界值。但是对于连续的范围序列,总会有一个边界值而不是范围。为了解决这个问题,序列可以表示为交替的边界值和范围:
B =边界值,r =范围
B-R-B-R-B
数据结构可能如下所示:
Boundary {
Date value
Range prev
Range next
}
Range {
Boundary start
Boundary end
}
从本质上讲,它是一个带有交替类型的双向链表。
最终,我使用的任何数据结构都将在内存(应用程序代码)和关系数据库中表示。
我很好奇学术或行业所尝试的解决方案是什么。
答案 0 :(得分:1)
规范化表示数据的方式是存储每个时间单位的记录。这可以在会议安排应用的示例中完成。您的约束将是
的唯一约束(RoomId, StartTime)
在连续范围的情况下,您必须存储2个东西,一个边界以及第二个边界或长度。它通常通过存储第二个边界然后在类型的两个边界上创建约束来完成
(boundary not between colBoudaryA and colBoundaryB)
附加约束
(startBoundary < endBoundary)
答案 1 :(得分:1)
双向链表很有效,因为你只使用了填充范围所需的内存,并且只需要在插入时检查重叠 - 在这一点上这样做几乎是微不足道的。如果重叠,则拒绝新项目。
RoomID ReservationID PreviousReservationID NextReservationID StartTimeDate EndTimeDate Priority UserID
优先级和UserID允许计划具有优先级(教授可能具有比学生组更多的影响力),以便新项目可以在插入期间“敲击”较低优先级项目,并且UserID允许电子邮件将发送给受到欢迎的会议组织者。
您需要考虑添加一个指向每天第一次会议的表格,以便优化搜索。
- 亚当
答案 2 :(得分:1)
答案 3 :(得分:1)
如果幸运(!)足以使用Postgres,您可以使用tstzrange
列,并应用约束以防止重叠。使用范围类型的好处是它本身会阻止开始大于完成。
ALTER TABLE "booking"
ADD CONSTRAINT "overlapping_bookings"
EXCLUDE USING gist ("period" WITH &&, "room" WITH =);
您可能需要CREATE EXTENSION IF NOT EXISTS btree_gist
,因为使用&amp;&amp;创建要点没有该扩展名,则不支持。
答案 4 :(得分:0)
很大程度上取决于您将对数据做什么,因此哪些操作需要高效。但是,我会考虑在开始和结束的设置器中使用逻辑的双重链接列表来检查它是否现在与其邻居重叠,并且如果是这样则缩小它们(或者抛出异常,或者你想要处理一个尝试重叠)。
这给出了一个很好的简单链接列表,其中列出了要读取的预定期间,但没有任何容器负责维护不重叠规则。
答案 5 :(得分:0)
这在Constraint Programming世界中被称为“一元资源”约束。在这个领域有很多研究,特别是对于事件时间没有修复的情况,你需要找到每个时间段的时间段。 有一个商业C ++包可以解决你的问题,Ilog CP更多,但它可能有点过分。还有一个名为eclipse的开源版本(与IDE无关)。
答案 6 :(得分:0)
这是非常重要的,因为(在数据库世界中)您必须比较多行以确定非重叠范围。显然,当信息在存储器中时,则可以按时间顺序列出其他表示,例如列表。不过,我认为,即使在列表中,您的“开始+结束”表示法也是最好的。
关于这个主题有完整的书籍 - “时间数据库”处理的一部分。你可以看到的两个是Darwen,Date和Lorentzos“Temporal Data and the Relational Model”和(完全不同的极端)“Developing Time-Oriented Database Applications in SQL”,Richard T. Snodgrass,Morgan Kaufmann Publishers,Inc.,旧金山,7月,1999,504 + xxiii页,ISBN 1-55860-436-7。已经绝版,但在cs.arizona.edu的网站上以PDF格式提供(因此谷歌搜索很容易找到)。
我相信其中一个相关数据结构是R-Tree。这通常用于二维结构,但也可以对一维结构有效。
您还可以查找“Allen's Relations”的时间间隔 - 它们可能对您有所帮助。
答案 7 :(得分:0)
我已经成功存储了开始时间和持续时间。重叠的测试类似于
WHERE NOT EXISTS (
SELECT 1 FROM table
WHERE BeginTime < NewBeginTime AND BeginTime + Duration > NewBeginTime
)
AND NOT EXISTS (
SELECT 1 FROM table
WHERE NewBeginTime < BeginTime AND NewBeginTime + NewDuration > BeginTime
)
我认为没有测试,但希望你得到漂移