如何实现以下算法

How to implement the following algorithm?

本文关键字:算法 实现 何实现      更新时间:2023-10-16

很抱歉这个谜一般的标题。我的问题是:

class Item
{
public:
    double value;
    void recomputeValue();   // after this, will probably increase a little, 
                             // but never decrease.
    std::list<Item*> neighbors;  // relatively few items
};

我正在尝试实现一个程序,它可以将这些项目的列表修剪到指定的大小:

void trimToNewSize(std::list<Item*>& items, int newSize);

需要实现的算法为:

while (size > newSize)
{
   erase item with smallest value;
   recomputeValue() for all its neighbors;
}

到目前为止,我考虑了两种方法:

1。堆

从所有的值构造一个堆。Heap是合适的,因为它可以在O(1)中找到并删除最小元素,并且可以在O(n)中构造。

每次移除后,找到堆中的所有邻居recomputeValue(),并更新它们在堆中的位置。

所以我对Wikipedia和Boost上的堆数据结构做了一些浅显的研究问题似乎是Heap没有提供查找元素的快速方法。

2。散列表

按值对列表排序。构造一个哈希表,将指针Item*映射到在链表中指向它们的迭代器。然后,每次我从列表中删除顶部(最小)项时,由于哈希表的存在,我在常量时间内找到了列表中所有它的邻居。然后对于每个相邻的recomputeValue(),更新其在列表中的位置和相应的迭代器在哈希表中的位置。

如果我使用一个有序的跳跃列表而不是链表,可能就不需要哈希表了。

我是一个编程新手,所以我的方法可能太幼稚和复杂,我欢迎任何建议。

总结一下我的问题:

  1. 是否有一种方法可以在堆中执行快速查找以使#1可行?
  2. 是否有一个容器,维护元素的顺序,并可以执行快速查找,以便我可以使#2更干净?
  3. 你会如何处理这个问题?

这看起来像一个普通的老std::map< double, Item * >的工作。它为您提供最小元素* items.begin(),要重新计算邻居,只需执行以下操作:

typedef std::map< double, Item * > itemsByValue;
itemsByValue items;
class Item
{
public:
    double value;
    void recomputeValue();   // after this, will probably increase a little, 
                             // but never decrease.
    std::list< itemContainer::iterator > neighbors;  // relatively few items
};
for ( itemsByValue::iterator i = neighbors.begin();
      i != neighbors.end(); ++ i ) {
    Item &item = * neighbor;
    items.erase( neighbor );
    item.recomputeValue();
    items.insert( std::make_pair( item.value, & item ) );
}