解决重叠项目的堆叠顺序



我有一个具有以下属性的Foo列表:

class Foo
(
    Date From
    Date To
    int Importance
)

这些项目的FromTo日期可以重叠。在两个foo重叠的地方,具有最高Importance的foo覆盖其他项。

是否有一种优雅的算法来获取Foo的列表并使用上述规则解决任何重叠(通过确定哪个Foo具有最高的Importance因子(?到目前为止,我的尝试都很糟糕。最终,它们归结为对每个可能的重叠冲突进行一系列检查,例如在较低优先级的foo之前有一个较高优先级,在较低优先权的foo的范围中间出现一个较高优先权的foo,等等。这样的策略看起来是不可维护的,需要一种我还没有找到的更优雅的方法。

这里的大问题是,较高优先级的Foo可以细分较低优先级的,所以我们不能简单地调整冲突的FoosFromTo点。

您可以使用优先级队列。

  1. 生成所有三元组(Date,bool,int(,其中第一个参数是其中一个Foo的To或From属性,bool表示它是To(true(还是From(false(,int是优先级
  2. 按日期对这些配对的列表进行排序
  3. 创建一个由按重要性排序的三元组组成的空优先级队列
  4. 在排序的列表上迭代,对于每个三元组(日期、isTo、重要性(执行:

    a。如果是From(isTo=false(,则添加到队列

    b。如果是To(isTo=true(,则从队列中删除

在任何时候,队列中的最大元素(您可以在O(1(中查找(都包含在该时间内获胜的那个元素。

(如果您需要实际的Foo对象,只需将三元组设为4元组,并引用Foo即可(。

我也会像Petar一样使用优先级队列,但我只会将所有Foo元素存储在其中。该队列中的优先级为:第一个-起始日期,第二个-结束日期,第三,"优先级"(我的意思是首先根据from字段对所有元素进行"排序",然后根据to字段对具有相同from字段的元素进行排序,最后根据优先级进行排序(。完成优先级队列后,您可以简单地对其进行迭代,检查每对元素之间的"距离"是否相同(其中距离为((To1-To2(+(From1-From2((。如果你找到这样一对,留下第一个,删除第二个。实际上,您可以在创建队列时或在插入新项目时执行此操作。如果我是正确的,整个算法将是O(nlogn(。

@编辑:哦,对不起,我在早上喝咖啡之前,我以为你指的是2个Foo有相同的To和From的情况,根据我现在的理解,你也希望在以下情况下删除项目:
Foo1从5到10优先级1
Foo2从1到11优先级2
什么是优先级较低的"封闭"Foo(即1-11(?

@编辑2:好吧,我的算法稍微调整一下就可以了。而不是t1-t2+f1-f2,只需如上所述对它们进行排序,并检查每对f2(来自foo2(是否在t1和f1之间。如果是,则删除Foo2。

示例:
Foo1:从3到4优先级1
Foo2:从5到6优先级2
Foo3:从1到7优先级3


按优先级排序后:
Foo3->Foo1->Foo2
首先检查Foor3和Foo1,Foo1的From介于Foo3的From和To之间,因此删除Foo1,因为它的优先级较低(在这种情况下,说得越好(。然后检查Foo3和Foo2(如果Foo1和Foo2没有被删除,则检查它(。再次检查Foo2的From是否在Foo3的From和to之间,因为它是,所以删除Foo2。
整个算法仍然是O(nlogn(。如果我看不到它会失败的某些情况,请给我一声呼喊。

使用优先级队列。按importance排序,然后按from排序,再按to排序。现在,您提取的每个foo要么是清晰的(而不是冲突的(,要么与同等或更高优先级的foo相交。按顺序解决冲突,你就完了!

最新更新