【问题标题】:search for multiple indecies with Boost Multi-Index使用 Boost Multi-Index 搜索多个指标
【发布时间】:2010-12-21 14:06:35
【问题描述】:

如何根据先前搜索的结果限制 boost::multi_index 中的搜索? 例如:假设我有一个矩形类,其内部值如下:

    class MyRect
    {
    public:
        int    width;  
        int    height; 

        double value;
    }

并且我需要此类对象的数据结构来回答诸如“给定input_rectangle - 哪个对象MyRect 包含在该矩形中并且具有最高值?”之类的查询

我可以像这样使用“multi_index”:

    struct given_value{};
    struct given_width{};
    struct given_height{};

    typedef multi_index_container<MyRect,
        indexed_by<
            ordered_non_unique< tag<given_value>, 
                member<MyRect, double, &MyRect::value>,
            ordered_non_unique< tag<given_width>, 
                member<MyRect, int, &MyRect::width>,
            ordered_non_unique< tag<given_height>, 
                member<MyRect, int, &MyRect::height>, >
        >
    > MyDataStructure;

    typedef MyDataStructure::index<given_width>::type MyDataStructureGivenWidth;
    typedef MyDataStructureGivenWidth::iterator WidthIterator;

如果我的 input_rectangle 有宽度 input_width 我可以使用这样的东西:

WidthIterator start_iter = data_object.get<given_width>().begin();
WidthIterator end_iter   = data_object.get<given_width>().upper_bound(input_width);

但是如何限制两个给定迭代器对 coresp 高度的搜索? (然后在该结果中找到具有最高值的对象?)

【问题讨论】:

    标签: c++ search boost multi-index


    【解决方案1】:

    如果我正确理解您的问题,可能会有更简单的解决方案。只需将您的 MyRects 放入按值排序的 STL-Set 中(需要定义比较运算符或自定义比较函数)。您可以创建一个自定义谓词并使用它来检查给定的 MyRect 是否在某个范围内。然后使用 STL 算法find_if,并将自定义谓词交给它。如果您确保它以降序遍历序列(例如,通过使用 reverse_iterator),它应该返回您正在寻找的 MyRect。

    希望这可以理解并适用于您的问题。

    【讨论】:

    • 您好,谢谢您的回答。我不确定,如果我理解正确的话:你想使用std::set,它使用value 作为排序,对吧?然后你想迭代整个集合(从最大值开始)直到你找到一个包含在 input_rectangle 中的对象?为了我的目的(线性时间),这将减慢速度。在有序集中搜索是对数的。如果我可以告诉多索引在另一个搜索索引(宽度)的给定范围内搜索(高度),那么整个搜索可能是对数的。但我不知道这是否可能..
    • 如果您的查询始终具有相同的模式(并且始终具有相同的参数顺序),则 fastet(就复杂性而言)解决方案将是一个首先按宽度排序然后按高度。这就像一个 Set 的集合,其中每个内部 Set 包含所有按高度排序的固定宽度的 Rect,而外部 Set 包含按其相应宽度排序的内部 Set。
    • 啊,一个字典顺序(我可以用std::set 来实现)。在我看来,最快的实现将是一个包含随机访问的数据结构(即,如果你有一个最大的宽度和高度,你可以拥有max_width * max_height许多带有coresp MyRects或存储值的条目)然后你就拥有迭代包含在input_rectangle 中的所有可能的宽度和高度,并记住最大值。 (注意:这与input_rectangle 中已经包含的矩形数量成线性关系——有对数方式吗?)。但这会消耗大量内存。
    【解决方案2】:

    我认为您不能进行就地限制。
    将匹配宽度查询的结果迭代器存储在另一个容器中,并使用该容器通过 remove_if 查找匹配高度。然后使用 max_element 找到最大的。

    如果将元素存储为指针,则可以使用相同的 MIC 来存储结果。

    【讨论】:

    • 您好,感谢您的回答。我认为你是对的,就地限制需要的不仅仅是恒定的时间。尽管您的最后一个提示非常优雅,但我希望 boost 能够在内部执行此操作。 (例如:如果我找到了一个范围 [start_iter,end_iter),那么我希望 MIC 暂时(或在副本中)忘记所有其他元素并重建自身以进行所有其他不道德的搜索)。如果没有这样的内部方法,那么我可以直接迭代我的范围(因为这种有序数据结构的构造至少像 std::make_heap 一样是线性的,对吧?)
    • 您是对的:您必须找出最适合您的系统。但是请注意,MIC 可能必须执行类似的操作才能创建子视图。
    • 是的,恐怕内部方法也会做同样的事情。但是有一个很小的可能性是有一种方法可以通过内部方法有效地处理这个问题。当然,如果我不必手动操作,那就太好了。因此,我暂时搁置这个问题——也许其他人有另一个想法。但是谢谢你(两者)的回答!
    • 我在这里 [#1] 在文档示例中找到了如此复杂的搜索。该方法类似于 stefaaanv 建议的方法。只是想更新以前的评论,以防将来有人关心。感谢大家! (#1 = boost.org/doc/libs/1_39_0/libs/multi_index/doc/…)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 2010-12-14
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多