对boost::graph中的EdgeList进行排序
Sorting the EdgeList in boost::graph
我想对boost::graph的边列表进行排序,定义如下:
struct Vertex{
int index;
};
struct Edge{
double weight;
};
boost::adjacency_list<boost::listS, boost::listS, boost::undirectedS, Vertex, Edge> Graph;
添加顶点和边后,如何对边列表进行排序。先取权重最大的边?
我知道可以使用
std::sort(edgeIt_begin,edgeIt_end,compare);
用于vector,但不适用于std::list。
您可以编写自己的EdgeList或OutEdgeList类来自动对元素进行排序。我举一个例子,因为我觉得怎么做不是那么明显。
#include <iostream>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
using namespace boost;
template<class T> struct Sorted_list
{
std::list<T> v;
public:
typedef T value_type;
typedef typename std::list<T>::size_type size_type;
typedef typename std::list<T>::iterator iterator;
iterator insert(const T& x)
{
Sorted_list<T>::iterator i = v.begin();
while(i != v.end() && x > *i)
{
i++;
}
return v.insert(i, x);
}
iterator begin() { return v.begin(); }
iterator end() { return v.end(); }
size_type size() const { return v.size(); }
};
struct SlistS {};
namespace boost {
template <class ValueType> struct container_gen<SlistS, ValueType>
{
typedef Sorted_list<ValueType> type;
};
struct sorted_list_tag {};
template<class T> sorted_list_tag container_category(Sorted_list<T>&)
{
return sorted_list_tag();
}
template<class T> std::pair<typename Sorted_list<T>::iterator, bool>
push_dispatch(Sorted_list<T>& v, const T& x, sorted_list_tag)
{
return std::make_pair(v.insert(x), true);
}
template <> struct parallel_edge_traits<SlistS> {
typedef allow_parallel_edge_tag type;
};
}
int main()
{
typedef adjacency_list<SlistS> Graph;
Graph g(10);
add_edge(1, 2, g);
add_edge(1, 5, g);
add_edge(1, 3, g);
add_edge(1, 7, g);
add_edge(1, 1, g);
graph_traits<Graph>::edge_iterator i, end;
for (tie(i, end) = edges(g); i != end; ++i) {
std::cout << source(*i, g) << " -> " << target(*i, g) << std::endl;
}
return 0;
}
输出:1 -> 1
1 -> 2
1 -> 3
1 -> 5
1 -> 7
对边缘排序不是boost::graph的惯用方法。看看Kruskal生成树算法的BGL实现。该算法需要按权重递增的顺序查看每条边。
std::priority_queue<Edge, std::vector<Edge>, weight_greater> Q(wl);
/*push all edge into Q*/
typename graph_traits<Graph>::edge_iterator ei, eiend;
for (boost::tie(ei, eiend) = edges(G); ei != eiend; ++ei)
Q.push(*ei);
它使用一个单独的数据结构对边进行排序,然后按该顺序遍历边。在您的示例中,您希望首先获得权重最大的边,因此您需要更改比较器操作符。
我不知道与Boost Graph表示的任何交互,但是IIRC 可以使用std::list::sort(Cmp)
std::list<int> l = { 1, 3, -1, 9, 2 };
l.sort();
上一个答案,虽然非常有用,但以一种有点不正确的方式管理bgl标签,这会导致冗余的push_dispatch定义,并且可能导致构建问题,如果调用其他*_dispatch函数(例如,在擦除操作的情况下)。
第二个令人困惑的情况是,在adj_list模板中替换了每个节点的边列表,但打印的是未受影响的全边列表。
有一些代码可能会纠正这些缺陷:
// ...
template<class T> struct Sorted_vector : public std::vector<T>
{
public:
iterator insert(const T& x)
{
iterator where = std::upper_bound(begin(), end(), x, std::less<T>());
return std::vector<T>::insert(where, x);
}
};
struct vecSS{};
namespace boost{
template <class ValueType> struct container_gen<vecSS, ValueType>
{
typedef Sorted_vector<ValueType> type;
};
template <> struct parallel_edge_traits<vecSS> {
typedef allow_parallel_edge_tag type;
};
template<class T> graph_detail::vector_tag container_category(const Sorted_vector<T>&)
{
return graph_detail::vector_tag();
}
template <class T> graph_detail::unstable_tag iterator_stability(const Sorted_vector<T>&)
{
return graph_detail::unstable_tag();
}
}
typedef adjacency_list<vecSS, ...> Graph;
// ....
graph_traits<Graph>::vertex_iterator ii, ee;
for(boost::tie(ii,ee) = vertices(g);ii!=ee;++ii){
std::cout << *ii << std::endl;
graph_traits<Graph>::adjacency_iterator jj, ff;
for(boost::tie(jj,ff)=adjacent_vertices(*ii, g);jj != ff; ++jj){
std::cout << "t -> " << *jj<<std::endl;
}
}
相关文章:
- 二叉排序树无法编译
- 仅使用绝对值对数组进行排序,并在C++中显示实际值
- C++选择排序算法中的逻辑错误
- 使用C++程序合并排序没有得到正确的输出
- 计算排序向量的向量中唯一值的计数
- 排序算法c++
- 使用2个键的cpp-stl::优先级队列排序不正确
- 将结构向量排序为子组
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 如何对点云数据进行排序
- 对字符串进行排序时,在c++中处理sort()
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 下面是排序算法O(n)吗
- std::sort()函数无法对向量的一部分进行排序
- shell排序中的交换和比较
- clang格式:禁用排序包含
- 显示错误输出的简单数组排序程序
- 为什么我的排序算法会更改数组值
- 试图在c++中对数字列表进行排序
- 对boost::graph中的EdgeList进行排序