通过与输入相同的boost图创建无向图
Create undirected graph by boost graph same as the input
我想创建如下图,第一列是顶点,其他是邻接顶点
- 2 1 3 4
- 3 1 2 4
- 4 1 2 3 5
- 5 4 6 7 8
- 6 5 7 8
- 7 1 5 6 8
- 8 5 7
我像这样把边添加到图中
using MinCutG = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS>;
MinCutG graph;
std::vector<std::vector<int> > input{ {1,2,3,4,7}, {2,1,3,4}, {3,1,2,4},
{4,1,2,3,5}, {5,4,6,7,8}, {6,5,7,8}, {7,1,5,6,8}, {8,5,6,7}};
for(auto const &data : input){
auto begin = std::begin(data);
auto end = std::end(data);
if(begin != end){
auto const Vertex = *begin;
++begin;
while(begin != end){
boost::add_edge(Vertex, *begin, graph);
++begin;
}
}
}
打印图形
template<typename Graph>
void print_adjacent_vertex(Graph const &g)
{
for (auto vertex = vertices(g); vertex.first != vertex.second; ++vertex.first){
std::cout << *vertex.first << " is connected with ";
for (auto neighbour = adjacent_vertices(*vertex.first, g);
neighbour.first != neighbour.second; ++neighbour.first){
std::cout << *neighbour.first << " ";
}
std::cout<<std::endl;
}
}
我期望输出应该与输入相同,但事实并非如此结果为
- 1与2 3 4 7 2 3 4 7连接
- 2与1 1 3 4 3 4连接
- 3与1 2 1 2 4 4连接
- 4与1 2 3 1 2 3 5 5连接
- 5与4 4 6 7 8 6 7 8连接
- 6与5 5 7 8 7 8连接
- 7与1 5 6 1 5 6 8 8连接
- 8与5 6 7 5 6 7 7连接
my expected results
- 1与2 3 4 7连接
- 2与1 3 4连接
- 3与1 2 4连接
- 4与1 2 3 5连接
- 5连接4 6 7 8
- 6与6 5 7 8连接
- 7与7 1 5 6 8连接
- 8与8 5 6 7连接
简而言之,使用setS
作为OutEdgeList
模板参数将禁用平行边,从而产生所需的输出。
boost::adjacency_list
的第一个模板参数是OutEdgeList
,它控制某些图形行为,例如允许或不允许平行边。在无向MinCutG
图的情况下,vecS
被用作OutEdgeList
,这将启用并行边。例如,如果无向图支持平行边,则使用:
add_edge(1, 2, graph); // Vertex 1 and 2 are adjacent to one another via edge A.
add_edge(2, 1, graph); // Vertex 1 and 2 are adjacent to one another via edge B,
// which is parallel to edge A.
顶点1
的adjacent_vertices()
将包含顶点2
两次,每条边(A
和B
)一次。
如文档中所述,可以通过对OutEdgeList
使用setS
或hash_setS
选择器来禁用平行边。例如,修改:
using MinCutG = boost::adjacency_list<
boost::vecS, // OutEdgeList with parallel edges
boost::vecS,
boost::undirectedS>;
:
using MinCutG = boost::adjacency_list<
boost::setS, // OutEdgeList with no parallel edges
boost::vecS,
boost::undirectedS>;
下面是一个使用原始代码的示例,仅将OutEdgeList
从vecS
更改为setS
:
#include <iostream>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
template<typename Graph>
void print_adjacent_vertex(Graph const &g)
{
for (auto vertex = vertices(g); vertex.first != vertex.second;
++vertex.first){
std::cout << *vertex.first << " is connected with ";
for (auto neighbour = adjacent_vertices(*vertex.first, g);
neighbour.first != neighbour.second; ++neighbour.first){
std::cout << *neighbour.first << " ";
}
std::cout<<std::endl;
}
}
int main()
{
using MinCutG = boost::adjacency_list<
boost::setS, boost::vecS, boost::undirectedS>;
MinCutG graph;
std::vector<std::vector<int> > input
{
{1,2,3,4,7},
{2,1,3,4},
{3,1,2,4},
{4,1,2,3,5},
{5,4,6,7,8},
{6,5,7,8},
{7,1,5,6,8},
{8,5,6,7}
};
for(auto const &data : input){
auto begin = std::begin(data);
auto end = std::end(data);
if(begin != end){
auto const Vertex = *begin;
++begin;
while(begin != end){
boost::add_edge(Vertex, *begin, graph);
++begin;
}
}
}
print_adjacent_vertex(graph);
}
生成以下输出:
0 is connected with
1 is connected with 2 3 4 7
2 is connected with 1 3 4
3 is connected with 1 2 4
4 is connected with 1 2 3 5
5 is connected with 4 6 7 8
6 is connected with 5 7 8
7 is connected with 1 5 6 8
8 is connected with 5 6 7
正如Tanner所解释的那样,你实际上是将每条边添加两次,首先作为(a,b),然后作为(b,a)。避免这种情况的一种相当昂贵的方法是使用setS
作为控制边缘容器的模板参数。这就是坦纳在他的回答中所暗示的。
另一种选择是在添加边之前检查边是否存在。它表示
这行boost::add_edge(Vertex, *begin, graph);
应替换为
if (! edge(Vertex, *begin, graph).second ) //edge does not exist yet
boost::add_edge(Vertex, *begin, graph);
在大多数情况下,这段代码可能更快,占用更少的内存。
相关文章:
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 创建一个函数的 Python 绑定,返回指向带有 boost 的向量的指针
- 避免使用 boost::进程间::消息队列创建文件
- boost日志文件无法创建sample.log文件
- Boost Asio SerialPort。无法创建并打开串口服务
- 我正在尝试创建一个C++映射,该映射在boost内存映射文件中具有向量值
- 调用boost.asio的异步函数时,线程是什么时候创建的
- 如何通过boost::asio和shared_ptr创建串行端口
- 如何创建一个版本的 boost::range::transform,该版本具有用于捕获上下文的额外参数
- 有没有办法为使用 Boost 生成的进程创建新的控制台窗口
- 无法导入 Boost.Python 创建的 dll(按照 Boost Python 的快速入门)
- 是否可以使用 static_cast 从可变参数枚举创建 boost::mpl::list_c
- 使用 Boost.Python 创建的 Python 模块不会被导入
- 使用Boost C 创建JSON数组
- 为什么BOOST创建的JSON字符串与我的服务器所需的不同
- Boost:创建一组线程并等待所有线程的正确习惯用法是什么
- CGAL-Boost创建无向图
- 正在设置由boost创建的共享内存的权限
- boost::创建托管共享内存对象时出现进程间ubuntu异常
- 如何使用Boost创建临界区?