[英]Removing an edge from a graph
我想從使用 Boost 圖庫生成的圖中刪除一些邊。
我使用 Boost 的boost::mt19937
生成從 1 到 N(頂點數)的隨機數,如下所示,並添加隨機邊。
#include "stdafx.h"
#include <ctime>
#include <iostream>
#include <utility> // for std::pair
#include <algorithm>
#include <time.h>
#include <boost/graph/adjacency_list.hpp>
#include "boost/graph/topological_sort.hpp"
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graphviz.hpp>
#include "boost/generator_iterator.hpp"
#include "boost/random.hpp"
// ----------------------------------------------
// Reading the number of vertices from the user.
//-----------------------------------------------
int read_int(std::string const & initmsg, std::string const & repeatmsg)
{
std::cout << initmsg;
for (std::string line; std::getline(std::cin, line); )
{
std::istringstream iss(line);
int res;
if (iss >> res >> std::ws && iss.get() == EOF) { return res; }
std::cout << repeatmsg;
}
std::cerr << "Unexpected end of input! Aborting.\n";
std::exit(1);
}
int main()
{
using namespace std;
using namespace boost;
typedef boost::mt19937 RNGType;
//Assignign a property value to first vertex, (i.e) the name
typedef property<vertex_name_t, std::string> VertexNameProperty;
// Defifning the type of gprah(undirected)
typedef adjacency_list< listS, vecS, undirectedS, VertexNameProperty > undigraph;
// a vertex iterator to iterate through the vertex to get the property vale
typedef graph_traits<undigraph>::vertex_iterator vertex_iter;
std::pair<vertex_iter, vertex_iter> vp;
int const N = read_int("Number of vertices: ",
"I did not understand, try again. Number of vertices: ");
// Creating a instance g of unigraph undirected graph
undigraph g;
//Assigining property(name) to graph vertex
property_map<undigraph, vertex_name_t>::type
name = get(vertex_name, g);
typedef graph_traits<undigraph>::vertex_descriptor Vertex;
Vertex u1;
u1=add_vertex(g);
name[u1] = "Controller";
// Creatng other vertices in the graph by iterating
for(Vertex p = 1; p <= N-1; ++p)
{
p=add_vertex(g);
}
// Priting out the controller
vp = vertices(g);
std::cout << "The name of the first vertex is " << name[*vp.first]<<" and the output graph is:" <<std::endl;
// --------------------------------------------------------------
// Generating a random edges from a vertex, maximum edges are four
// Using Mersenne twister- A Pseudo random generator algorithm
// Mersenne twister gives un-distributed random numbers
//----------------------------------------------------------------
RNGType rng( time(0) );
boost::uniform_int<> one_to_four( 1, (N-1) );
boost::variate_generator< RNGType, boost::uniform_int<> >gen(rng, one_to_four);
for(int i =0; i<(N-1); i++)
{
int k = 0;
while(k<(N-1))
{
int n = gen();
// Adding edges onto graph
if(!boost::edge(i, n, g).second && !boost::edge(n, i, g).second)
{
add_edge(i, n, g);
k++;
}
}
// removing edges that direct to same vertex graph
}
write_graphviz(cout, g);
return 0;
}
但是如果我有 4 個頂點,我會得到上面的輸出,如下所示:
graph G
0;
1;
2;
3;
4;
0--1 ;
0--2 ;
0--2 ;
0--2 ;
1--3 ;
2--1 ;
2--4 ;
3--2 ;
3--2 ;
3--4 ;
}
但是可以看出,邊(0,2) and (3,2)
是重復的。 對於較大的圖,有時例如: (1,3) and (3,1)
存在並且它們都與無向圖相同。 如何刪除這些頂點。 我知道 Boost 有一個叫做remove_edge_if()
東西,但我沒有找到任何精確的例子來支持我的情況。
正如它應該。 您在不檢查源節點和結束節點的情況下獲取一堆隨機數並為它們添加邊,因此有一些重復和一些圓形路徑也就不足為奇了。
我建議改變
add_edge(i, n, g)
k++
到
if(!has_edge(i,n,g))
{
add_edge(i, n, g)
k++
}
如果你只想要一對節點之間的一條邊而不管方向:
if(!has_edge(i,n,g) && !has_edge(n,i,g))
{
add_edge(i, n, g)
k++
}
我還建議不要添加邊緣,然后再刪除它們。 所以我會刪除你對(i == i)
檢查(i == i)
無論如何它永遠不會是假的),並在調用add_edge
之前將(i != n)
到條件中。
這:
for(Vertex p = 1; p <= N-1; ++p)
{
p=add_vertex(g);
}
很可能會出錯。 您在迭代p
同時也在編輯p
。 可能不是。 另外,您是否在任何階段輸出N
以檢查其值?
它沒有任何元素,它在生成圖形時掛起。 我認為這是因為你的while(k<(N-1))
。 您試圖讓每個節點與其他節點有N-1
連接。 但同時,您不會接受與已經連接到當前節點的節點的連接。 當您嘗試為第二個節點生成邊時,它無法連接到自身或第一個節點(已經連接到它),因此最多有 (N-2) 個連接。 但是你要等到它找到N-1
,這從來沒有發生過。
我嘗試將其更改為while(k<(N/2))
並且這似乎對我有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.