2013-03-07 167 views
2

我很抱歉,神秘的标题。这里是我的问题:如何实现以下算法?

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; 
} 

我已经考虑SOFAR 2点的方法:

1.堆

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

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

所以我也做了堆数据结构的一些粗浅的研究上WikipediaBoost问题是,它似乎是堆不提供快速的方式来定位它元素。

2.哈希表

排序列表由值。构建一个哈希表,将指针Item *映射到指向链表中的迭代器。然后,每次我从列表中删除顶部(最小)项目时,都会因为哈希表而在列表中持续查找其所有邻居。然后为每个邻居recomputeValue()更新其在列表中的位置以及散列表中的对应迭代器。

也许,如果我用一个有序skiplist,而不是一个链表哈希表需要将被淘汰。

我的新节目,所以我的方法可能是太天真了,复杂的,我欢迎任何建议。

总结我的问题:

  1. 有没有在堆中进行快速查找,使#1可行的方法吗?
  2. 是否有维护元素的顺序,可以进行快速查找,这样我可以做#2清洁的容器?
  3. 你会如何处理这个问题?
+0

作为堆,总重计算后,我认为这是构建新的堆'会比“更新旧堆快”。但这只是一个预感 – quetzalcoatl 2013-03-07 09:36:08

+0

我忘了提及,每个项目只有少数邻居,所以只有少数重新计算会发生。 – 2013-03-07 09:37:30

+2

这是非常积极的事情,你正在做深入的研究。然而,你有没有调查过“无关紧要”的零假设?你会有多少物品/邻居?你现在增加了“少数邻居”,对于FEW,例如O(N)或O(NlgN)等没有真正的差别,甚至O()符号中缺少的常数因子可能比O ()因素本身! – quetzalcoatl 2013-03-07 09:40:29

回答

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)); 
} 
+0

谢谢!所以我应该使用散列表的替代方案? – 2013-03-07 09:42:42

+2

@MartinDrozdik Huh?我在哪里提到了一个散列表?不幸的是'std :: unordered_multimap'没有提供你需要找到一个插入点的'lower_bound'操作,所以树是必需的。 – Potatoswatter 2013-03-07 09:43:50

+0

我在提到#2的问题。我正在使用QHashTable,但我想,这只是一个相当于std :: unordered_multimap。谢谢你的建议! – 2013-03-07 09:51:08