Giriş
Tüm vertex'leri dolaşmamızı sağlayan bir iterator çifti döner. first iterator ilk vertex'e second iterator ise son vertex'e işaret eder.
Bu metod ile edges metodu kardeştir.
BGL_FORALL_VERTICES macrosu ile aynıdır.
Bu metod vertex_iterator tipinden iterator döner. İki iterator nesnesini dolaşmak için boost::make_iterator_range() kullanılabilir.
vertices - graph
Örnek
Elimizde vector tabanlı bir graph olsun
Her graph nesnesinin vertex'i anlamlı bir sayı vermeyebilir. std::vector tabanlı graph'larda sayıyı okuması kolaydır. Şöyle yaparız.
Şöyle yaparız.Burada graph.m_vertices ile dokümante edilmemiş bir alana erişiyoruz. Bu alan graph vecS olarak tanımlı ise vector tipendendir.
Tüm vertex ve onların tüm komşularını dolaşmak için şöyle yaparız.
vertices() çağrısının döndürdüğü vertex_iterator ile adjacent_vertices() çağrısının döndürdüğü adjacency_iterator tipleri birbirlerinden farklıdır. Şu kod derlenmez.
Elimizde bir grap olsun ve onu dolduralım.
Tüm vertex'leri rastgele dolaşmak isteyelim. Önce vertex'lerin başlangıcını saklarız.
Tüm vertex'leri dolaşmamızı sağlayan bir iterator çifti döner. first iterator ilk vertex'e second iterator ise son vertex'e işaret eder.
Bu metod ile edges metodu kardeştir.
BGL_FORALL_VERTICES macrosu ile aynıdır.
Bu metod vertex_iterator tipinden iterator döner. İki iterator nesnesini dolaşmak için boost::make_iterator_range() kullanılabilir.
vertices - graph
Örnek
Elimizde vector tabanlı bir graph olsun
struct VertexProps { int id; default_color_type color; };
using Graph = adjacency_list<vecS, vecS, directedS, VertexProps>;
Graph g = ...;
Şöyle yaparız.for (auto vd : boost::make_iterator_range(vertices(g))) {
std::cout << "Vertex descriptor #" << vd
<< " degree:" << degree(vd, g)
<< " id:" << g[vd].id
<< " color:" << g[vd].color
<< "\n";
}
ÖrnekHer graph nesnesinin vertex'i anlamlı bir sayı vermeyebilir. std::vector tabanlı graph'larda sayıyı okuması kolaydır. Şöyle yaparız.
typedef boost::adjacency_list<> Graph;
typedef Graph::vertex_iterator Vit;
Graph g(10);
add_edge(2,5,g);
add_edge(5,3,g);
add_edge(3,8,g);
Vit begin, end;
boost::tie(begin, end) = vertices(g);
for (Vit it = begin; it != end; ++it) {
unsigned edges = out_degree(*it, g);
if (edges)
std::cout << "vertex #" << *it << " has " << edges << " outgoing edge(s)\n";
}
}
Çıktı olarak şunu alırız.vertex #2 has 1 outgoing edge(s)
vertex #3 has 1 outgoing edge(s)
vertex #5 has 1 outgoing edge(s)
Eğer graph std::set tabanlı ise çıktıyı okumak zordur. edge eklemek için std::set'i std::vector'e çevirerek kullanırız. Şöyle yaparız.typedef boost::adjacency_list<boost::setS, boost::listS/*, boost::undirectedS*/> Graph;
typedef Graph::vertex_iterator Vit;
Graph g(10);
Vit begin, end;
boost::tie(begin, end) = vertices(g);
{
std::vector<Graph::vertex_descriptor> vindex(begin, end);
add_edge(vindex[2], vindex[5], g);
add_edge(vindex[5], vindex[3], g);
add_edge(vindex[3], vindex[8], g);
}
for (Vit it = begin; it != end; ++it) {
unsigned edges = out_degree(*it, g);
if (edges)
std::cout << "vertex #" << *it << " has " << edges << " outgoing edge(s)\n";
}
Çıktı olarak şunu alırız.vertex #0x994d00 has 1 outgoing edge(s)
vertex #0x994d70 has 1 outgoing edge(s)
vertex #0x994e50 has 1 outgoing edge(s)
Bu durumda vertex'lere property ekleriz ve yine aynı şekilde edge eklemek için std::set'i std::vector'e çevirerek kullanırız.struct VertexProperties {
std::string name;
VertexProperties(std::string name) : name(name) {}
};
typedef boost::adjacency_list<boost::setS, boost::listS, boost::directedS,
VertexProperties> Graph;
typedef Graph::vertex_iterator Vit;
Graph g;
add_vertex(VertexProperties ("zero"), g);
add_vertex(VertexProperties ("one"), g);
add_vertex(VertexProperties ("two"), g);
add_vertex(VertexProperties ("three"), g);
add_vertex(VertexProperties ("four"), g);
add_vertex(VertexProperties ("five"), g);
add_vertex(VertexProperties ("six"), g);
add_vertex(VertexProperties ("seven"), g);
add_vertex(VertexProperties ("eight"), g);
add_vertex(VertexProperties ("nine"), g);
Vit begin, end;
boost::tie(begin, end) = vertices(g);
{
std::vector<Graph::vertex_descriptor> vindex(begin, end);
add_edge(vindex[2], vindex[5], g);
add_edge(vindex[5], vindex[3], g);
add_edge(vindex[3], vindex[8], g);
}
for (Vit it = begin; it != end; ++it) {
unsigned edges = out_degree(*it, g);
if (edges)
std::cout << "vertex '" << g[*it].name << "' has " << edges << " outgoing edge(s)\n";
}
}
Çıktı olarak şunu alırız.
vertex 'two' has 1 outgoing edge(s)
vertex 'three' has 1 outgoing edge(s)
vertex 'five' has 1 outgoing edge(s)
ÖrnekŞöyle yaparız.Burada graph.m_vertices ile dokümante edilmemiş bir alana erişiyoruz. Bu alan graph vecS olarak tanımlı ise vector tipendendir.
VertexIterator vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(graph); vi != vi_end; ++vi){
graph.m_vertices[*vi].m_out_edges.reserve(6);
}
Örnek
Elimizde şöyle bir graph olsun.
Elimizde şöyle bir grap olsunElimizde şöyle bir graph olsun.
struct mytuple
{
int e1;
int e2;
int s;
bool operator==(const mytuple& a) const
{
return ((e1 == a.e1) && (e2 == a.e2) && (s == a.s));
}
};
struct MyVertex {
std::string comments;
int field1;
mytuple value;
MyVertex(std::string comments = std::string()) : comments(comments) {}
};
struct MyEdge {
std::string label;
MyEdge(std::string label = std::string()) : label(label) {}
};
using MyTree = boost::adjacency_list<boost::vecS, boost::vecS,
boost::bidirectionalS, MyVertex, MyEdge>;
using Vertex = boost::graph_traits<MyTree>::vertex_descriptor; // Define Vertex
using VertexItr = boost::graph_traits<MyTree>::vertex_iterator; //Vertex iterator
using Edge = std::pair<boost::graph_traits<MyTree>::edge_descriptor, bool>; //Edge
using EdgeItr = boost::graph_traits<MyTree>::edge_iterator; // Edge Iterator
Graph'ı dolduralım
Kullanmak için şöyle yaparız.MyTree mytree;
Vertex v1 = boost::add_vertex(mytree);
mytree[v1].value = {1, 1, 1};
mytree[v1].comments = "I am the one you seek";
Vertex v2 = boost::add_vertex(mytree);
mytree[v2].value = {2, 2, 2};
Vertex v3 = boost::add_vertex(mytree);
mytree[v3].value = {3, 3, 3};
Tüm vertex'leri dolaşarak eşitlik kontrolü yapmak için şöyle yaparız.
VertexItr findvertex(const MyTree& g, const mytuple& value){
VertexItr vi, vi_end;
for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) {
if(g[*vi].value == value) return vi;
}
return vi_end;
}
mytuple tuple = { 1,1,1};
const auto iter = findvertex(mytree, tuple);
const auto theEnd = boost::vertices(mytree).second;
Örnek - pairstruct Vertex { int id; double data; };
struct Edge { float distance; };
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS,
Vertex, Edge> Graph;
Vertex'lerin başını ve sonunu std::pair olarak almak için şöyle yaparız// Iterate through the vertices and print them out
typedef boost::graph_traits<Graph>::vertex_iterator vertex_iter;
std::pair<vertex_iter, vertex_iter> vp;
for (vp = boost::vertices(g); vp.first != vp.second; vp.first++)
{
std::cout << g[*(vp.first)].id << " " << g[*(vp.first)].data << std::endl;
}
Her vertex'i yazdırınca çıktı olarak şunu alırız.1 1.1
2 2.2
3 3.3
4 4.4
ÖrnekTüm vertex ve onların tüm komşularını dolaşmak için şöyle yaparız.
Graph g = ...;
Graph::vertex_iterator vertexIt, vertexEnd;
tie(vertexIt, vertexEnd) = vertices(g);
for (; vertexIt != vertexEnd; ++vertexIt)
{
Graph::adjacency_iterator neighbourIt, neighbourEnd;
tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt, inputgraph);
for (; neighbourIt != neighbourEnd; ++neighbourIt){
...
}
}
Örnekvertices() çağrısının döndürdüğü vertex_iterator ile adjacent_vertices() çağrısının döndürdüğü adjacency_iterator tipleri birbirlerinden farklıdır. Şu kod derlenmez.
Elimizde bir grap olsun ve onu dolduralım.
typedef adjacency_list<vecS, vecS, directedS> digraph;
typedef graph_traits<digraph>::vertex_iterator vertex_it;
typedef graph_traits<digraph>::adjacency_iterator adj_it;
graph_traits<digraph>::vertex_descriptor a, b, c;
digraph g;
a = add_vertex(g);
b = add_vertex(g);
c = add_vertex(g);
add_edge(a, b, g);
add_edge(b, c, g);
add_edge(c, a, g);
Daha sonra iki iterator'ü karıştırmaya çalışalım. Kod derlenmez.vector<vertex_it> stack;
vertex_it v_beg,v_end;
tie(v_beg,v_end) = vertices(g);
stack.push_back(v_beg);
adj_it adj_beg,adj_end;
tie(adj_beg, adj_end) = adjacent_vertices(*v_beg, g);
for (; adj_beg != adj_end; adj_beg++)
stack.push_back(adj_beg); //error here
ÖrnekTüm vertex'leri rastgele dolaşmak isteyelim. Önce vertex'lerin başlangıcını saklarız.
std::pair<vertex_iter, vertex_iter> vp;
vp = vertices(g);
Daha sonra sayıları rastgele karıştırırız.// initialize pseudo random number generator
std::srand(unsigned (std::time(0)));
// create offset vector
std::vector<int> myvector;
for (int i=0; i<3; ++i) {
myvector.push_back(i);
}
// using myrandom to shuffle offset vector
std::random_shuffle(myvector.begin(), myvector.end(), myrandom);
Rastgele dolaşmak için şöyle yaparız.vertex_iter dummy_iter;
// Looping on a shuffled vector, values should be 0..N-1
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
{
dummy_iter = vp.first + *it;
Vertex* v = *dummy_iter;
...
}
Hiç yorum yok:
Yorum Gönder