事件排序的数据结构设计

时间:2012-02-16 04:10:04

标签: algorithm math data-structures

我正在研究一个小型系统,我想出了一个初步的设计/解决方案来解决我即将要描述的问题。它工作正常,但是我不认为这是这个问题最优雅的设计,因此,如果您建议如何根据数据结构对此类问题进行建模,我将不胜感激:

  • 结果的概念和导致该结果的一系列事件。
  • 事件按其出现顺序排序,没有时间戳,只有位置/索引。
  • 事件顺序并不严格。事件可能以输入中列出的不同顺序发生。
  • 有些事件取决于其他事件的结果,并且保证了它们的相对顺序得以保留。 (例如:如果我们按此顺序有4个事件:A,B,C,D和事件A& C是相关的,那么在A之前C可能没有变化。)

我将使用此数据结构的最常见情况是确定事件可能发生的范围,考虑到上述依赖性。

示例:

- Event A<------+
- Event B <---+ | D2
- Event C <---|-|----+
- Event D ----+-+    |
- Event E <---|------+
- Event F ----+D1    |
- Event G -----------+ D3
  • D1描述了F和B之间的依赖关系.F在B之前永远不会发生。
  • D2描述了D和A之间的依赖关系.D在A之前永远不会发生。
  • D3描述了G和E之间的依赖关系.G在E或C之前永远不会发生。

我想遍历这个集合,并且在每个元素上获得该事件可能发生的范围,因为其他元素命令reamin不变。这是简单的版本。

对于v.2.0,我将需要当前元素顺序的可能范围,因为其他元素也可以移动。即,组合事件X尽可能接近开头,或者Y尽可能接近结尾。

谢谢!

1 个答案:

答案 0 :(得分:4)

你所描述的内容可以用directed acyclic graph建模,其中每个节点代表一些事件,从u到v的边缘意味着你必须在v之前来。

鉴于这种表示,我相信你可以有效地(在时间O(n + m),其中n是事件的数量,m是约束的数量)确定一些事件可能发生的最新可能时间修改后的topological sort。具体来说,开始对节点进行标准拓扑排序,但每当您展开表示相关事件的节点时,请跳过它并扩展其他节点(换句话说,选择不同的源节点)。当您完全耗尽其他节点进行扩展时,您将留下一个DAG,其中只有一个源节点,即您要展开的节点。您之前扩展的节点因此是您可能在您感兴趣的事件之前可能发生的事件,因此您可以通过查看其前面有多少事件来获取其最新可能的位置。

作为优化,如果您具有固定结构(不添加任何事件或依赖项),则可以通过计算DAG中每个节点具有的后代节点数来预先计算此信息。节点的后代数是在任何拓扑排序的顺序中不可能位于其之前的节点的数量,并且该信息可以在时间O(n + m)中计算一次。缓存后,每个元素的最后一个可能位置是n - 1 - k,其中k是该节点的后代数。

希望这有帮助!