Удаление ребра из графика

Я хотел бы удалить некоторые ребра из графа, созданного с помощью библиотеки графов Boost.

Я использую Boost’s 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) повторяются И для больших графиков, иногда для ex: (1,3) and (3,1) существует, и они оба одинаковы, так как это неориентированный граф.
Как я могу удалить эти вершины. Я знаю, что у Буста есть нечто, называемое remove_edge_if()Но я не нашел точного примера, чтобы поддержать мой случай.

Любая помощь могла бы быть полезна.

0

Решение

Как это должно. Вы берете кучу случайных чисел и добавляете ребра для них, не проверяя исходный и конечный узлы, поэтому неудивительно, что есть некоторые повторы и некоторые круговые пути.

Я бы предложил изменить

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 != n) до состояния до звонка в add_edge,

После редактирования

Это:

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)) и это, казалось, сработало для меня.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]