【问题标题】:best data structure to record a Pareto front记录帕累托前沿的最佳数据结构
【发布时间】:2018-08-18 20:14:25
【问题描述】:

请问是否有人已经看到或面临以下问题?

我需要处理成本/利润值列表 c1/p1, c2/p2, c3/ p3,... 满足:

  • c1≤c2≤c3≤c4...
  • p1≤p2≤p3≤p4...

这是一个例子:2/34/59/1512/19

如果有人尝试 insert 10/14 在上面的列表中,操作被 rejected 因为存在 成本/利润对9/12:增加成本永远没有用(9->10) 并减少利润(14->12)。例如,此类列表可能出现在 背包问题的(状态)动态规划算法,其中 成本可以代表权重。

如果在上面的列表中插入7/20,这应该触发删除9/1512/19

我使用C++ std::set 编写了一个解决方案(通常使用 红黑树),但我需要提供一个比较函数,最终 变得有点过于复杂。此外,在此类集合中的插入需要 对数时间,这实际上很容易导致线性时间(在 非摊销复杂度),例如当插入触发删除所有其他 元素。

我想知道是否存在更好的解决方案,因为有无数的解决方案 实现(有序)集合,例如优先级队列、堆、链表、散列 表等

这是一个帕累托前沿(obj1:最小成本,obj2:最大利润),但我仍然找不到记录它的最佳结构。

【问题讨论】:

  • 请定义“最佳”
  • 我希望能够通过重复应用恒定时间getNext() 函数来遍历列表。我知道我需要花费对数时间来检查是否应该拒绝新的一对(但也许可以更快地完成,谁知道?)。但我觉得可以避免损失对数时间来检查成本值是否存在。我也想在恒定时间内执行此操作,例如通过沿红黑树使用第二个数组(或哈希表)来仅记录成本集。

标签: priority-queue red-black-tree pareto-chart ordered-set


【解决方案1】:

我没有完全理解你描述的规则,所以我会不可知地说,尝试插入可能会触发拒绝,如果被接受,则需要删除后续项目。

您需要使用平衡的比较树,表示为一个数组。在这种情况下,找到您需要的节点将花费 O(logN) 时间,这将是搜索或拒绝插入尝试的复杂性。当您需要删除项目时,您将其删除并插入一个新项目,其复杂性为

O(logN + N + N + logN) (即搜索、删除、重新平衡和插入。如果在重新平衡时我们知道要插入新项目的位置,我们可以去掉最后一个对数)

O(logN + N + N + logN) = O(2logN + 2N) = O(logN^2 + 2N),很大程度上是线性复杂度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多