BGL 边缘(u,v,g)与边缘列表的自定义关联容器

发布于 2025-01-02 21:04:30 字数 1199 浏览 1 评论 0 原文

我刚刚开始学习 bgl,并在使用具有自定义排序的 std::set 作为 adjacency_list 中边缘列表的容器时遇到了问题。我定义了运算符<根据边的属性对边进行排序,就像ordered_out_edges.cpp 示例中一样。这里 boost::edge_unique_ordering 是一个自定义属性标签。

template < typename Edge >
struct order_by_unique_order: public std::binary_function< Edge, Edge, bool >
{
    inline bool operator() (const Edge& e1, const Edge& e2) const
    {
        return boost::get(boost::edge_unique_ordering, e1) < boost::get(boost::edge_unique_ordering, e2);
    }
};

struct default_edge_containerS {};

namespace boost
{
    template < class ValueType >
    struct container_gen< default_edge_containerS, ValueType >
    {
        typedef std::set< ValueType, order_by_unique_order< ValueType > > type;
    };
}

一般来说,它工作正常,但当我使用 edge(u, v, g) 函数时,我遇到迭代器异常。如果我用解决方法替换这些调用以避免通过(源,目标)请求边缘,那么一切都会正常工作。

我查看了 boost 代码,我很确定我知道原因是什么,我只是不确定这是否意味着我做错了什么,这是 boost 代码的问题,或者只是一个未记录的不兼容性。该函数在 u 的出边列表容器上调用 set::find(StoredEdge(v)) 。现在默认的stored_edge::operator<只是比较目标顶点,但就我而言,我的自定义运算符<正在被调用,并且正在查找的 StoredEdge(v) 显然是默认初始化的,没有任何属性,这可能是问题的原因。在我看来,edge(u, v, g) 应该严格基于目标顶点搜索任何匹配,无论容器内的边施加什么顺序。

任何人都可以阐明我可能做错或不理解的事情吗?

I've just begun learning bgl and have hit on a problem while using a std::set with a custom ordering as the container for edge lists in an adjacency_list. I define the operator< to order the edges based on their properties, much like in the ordered_out_edges.cpp example. Here boost::edge_unique_ordering is a custom property tag.

template < typename Edge >
struct order_by_unique_order: public std::binary_function< Edge, Edge, bool >
{
    inline bool operator() (const Edge& e1, const Edge& e2) const
    {
        return boost::get(boost::edge_unique_ordering, e1) < boost::get(boost::edge_unique_ordering, e2);
    }
};

struct default_edge_containerS {};

namespace boost
{
    template < class ValueType >
    struct container_gen< default_edge_containerS, ValueType >
    {
        typedef std::set< ValueType, order_by_unique_order< ValueType > > type;
    };
}

In general it is working fine, but I am getting iterator exceptions when I use the edge(u, v, g) function. If I replace these calls with a workaround to avoid requesting edges by (source, target) then everything works fine.

I looked through the boost code and I'm pretty sure I know what the cause is, I'm just unsure if it means I'm doing something wrong, it's a problem with the boost code, or just an undocumented incompatibility. The function invokes set::find(StoredEdge(v)) on the out edge list container of u. Now the default stored_edge::operator< just compares target vertices, but in my case my custom operator< is being called, and the StoredEdge(v) which is being looked for is obviously default initialized with no properties, which presumably is the cause of the problem. It seems to me that edge(u, v, g) should be searching for any match based strictly on the target vertex, regardless of what ordering is imposed on the edges within the container.

Can anyone shed some light on what I may be doing wrong or not understanding?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无法言说的痛 2025-01-09 21:04:30

看起来您需要编写一个包装比较运算符,该运算符采用一个类型(将使用 StoredEdge 类型填充)并比较 get_target) 上的结果使用自定义比较函数的两个输入,使用类似以下内容:

template <typename Cmp>
struct target_compare {
  Cmp cmp;
  target_compare(const Cmp& cmp): cmp(cmp) {}
  template <typename SE>
  bool operator()(const SE& a, const SE& b) const {
    return cmp(a.get_target(), b.get_target());
  }
};

然后使用 target_compare > 作为集合中的比较类型。

It looks like you will need to write a wrapper comparison operator that takes a type (which will be filled in using the StoredEdge type) and compares the results of get_target) on the two inputs using your custom compare function, using something like:

template <typename Cmp>
struct target_compare {
  Cmp cmp;
  target_compare(const Cmp& cmp): cmp(cmp) {}
  template <typename SE>
  bool operator()(const SE& a, const SE& b) const {
    return cmp(a.get_target(), b.get_target());
  }
};

then use target_compare<order_by_unique_order<Edge> > as the comparison type in your set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文