Here is a complete snippet to copy a graph with bundled properties, but results in bunch of compiler errors. What is needed to fix the problems?
struct NodeInfo1 {};
struct EdgeInfo1 {};
typedef boost::labeled_graph< boost::adjacency_list<
boost::vecS, boost::vecS, boost::undirectedS, NodeInfo1, EdgeInfo1>,
std::string> Graph1;
typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> Edge;
void TestCases::TestCopyGraph()
{
Graph1 grid, g1;
EdgeInfo1 ei;
Edge e = add_edge_by_label("A", "B", ei, grid);
copy_graph(grid, g1);
}
That's slightly misrepresenting the question. You're not actually copying the adjacency list, you're copying the labeled_graph adaptor, which happens to not satisfy the concepts required by copy_graph:
/** #name Labeled Mutable Graph
* The labeled mutable graph hides the add_ and remove_ vertex functions from
* the mutable graph concept. Note that the remove_vertex is hidden because
* removing the vertex without its key could leave a dangling reference in
* the map.
*/
Here's copying the adjacency_list: ¹
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, NodeInfo1, EdgeInfo1> AList;
typedef boost::labeled_graph<AList, std::string> Graph;
void TestCopyGraph()
{
std::string names[3] = { "A", "B", "C" };
Graph grid(3, names);
EdgeInfo1 ei;
/*auto e =*/ add_edge_by_label("C", "B", ei, grid);
AList g1;
copy_graph(grid, g1);
}
Copying the Labeled adaptor
Is much easier. No copy_graph required, just copy-construct the object:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/labeled_graph.hpp>
#include <boost/graph/graph_utility.hpp>
struct NodeInfo1 { int i; };
struct EdgeInfo1 { int j; };
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, NodeInfo1, EdgeInfo1> AList;
typedef boost::labeled_graph<AList, std::string> Graph;
auto TestCopyGraph()
{
std::string names[3] = { "A", "B", "C" };
NodeInfo1 props[3] = { {11}, {22}, {33} };
Graph grid(3, names, props);
/*auto e =*/ add_edge_by_label("C", "B", EdgeInfo1{17}, grid);
Graph g1 = grid; // just copy-construct
return g1;
}
int main() {
auto copied = TestCopyGraph();
print_graph(copied);
// check that properties were copied: vertex B has NodeInfo1 22
{
auto pmap = boost::get(&NodeInfo1::i, copied);
std::cout << "Vertex B NodeInfo1.i after copy: " << pmap[copied.vertex("B")] << "\n";
}
// edge properties too:
for (auto e : boost::make_iterator_range(edges(copied)))
std::cout << "Edge has property EdgeInfo1 " << copied[e].j << "\n";
std::cout << "Removed A:\n";
copied.remove_vertex("A");
print_graph(copied);
}
Prints
0 <-->
1 <--> 2
2 <--> 1
Vertex B NodeInfo1.i after copy: 22
Edge has property EdgeInfo1 17
Removed A:
0 <--> 1
1 <--> 0
¹ Note that you need this patch because of bugs in labeled_graph: https://github.com/boostorg/graph/pull/58
Related
The main question:
I am able to create a graph implementation with information structs assigned to the vertices and edges:
struct vertex_info {std::string name;};
struct edge_info {std::string name;};
typedef boost::adjacency_list<
boost::vecS,
boost::vecS,
boost::undirectedS,
vertex_info,
edge_info> UndirectedGraph;
And for an instance of UndirectedGraph, g, I can easily iterate over the vertices, and access their information:
for(size_t i=0; i<boost::num_vertices(g); i++){
std::cout << g[i].name << std::endl;
}
but I am unable to figure out how to do the same for the edges. I have come across some iterators to loop over all the edges, but I cannot access these edges as some kind of object or something with properties. How can I access the edge information of g?
A minimal working demonstration:
#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include "boost/graph/graph_traits.hpp"
#include "boost/graph/adjacency_list.hpp"
int main(int argc, char *argv[])
{
//Add vertex information struct
struct vertex_info {
std::string name;
};
//Add edge information struct
struct edge_info {
std::string name;
};
//Typedef my graph implimentation
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, vertex_info, edge_info> UndirectedGraph;
//Our set of edges, and count N: (0-7) and 8
enum {C, D, G, I, S, J, L, H, N};
const char *name = "CDGISJLH";
//Create a vector of edges
typedef std::pair<int, int> Edge;
std::vector<Edge> edgeVec;
edgeVec.push_back(Edge(C,D));
edgeVec.push_back(Edge(D,G));
edgeVec.push_back(Edge(I,G));
edgeVec.push_back(Edge(G,L));
edgeVec.push_back(Edge(H,G));
edgeVec.push_back(Edge(I,S));
edgeVec.push_back(Edge(S,J));
edgeVec.push_back(Edge(L,J));
edgeVec.push_back(Edge(H,J));
//Now we can initialize our graph using iterators from our above vector
UndirectedGraph g(edgeVec.begin(), edgeVec.end(), N);
std::cout << num_edges(g) << "\n"; //Outputs: 9
//loop over vertices, access "name" property
for(size_t i=0; i<boost::num_vertices(g); i++){
//And add information to the edges
g[i].name = "foo";
}
//We can access the first vertice and print the property
std::cout << g[0].name << std::endl; //Outputs: foo
//Edge iterator for or graph
typedef boost::graph_traits<UndirectedGraph>::edge_iterator edge_iterator;
//Iterate through all the edges
std::pair<edge_iterator, edge_iterator> ei = boost::edges(g);
for(edge_iterator edge_iter = ei.first; edge_iter != ei.second; ++edge_iter) {
//How can I access the edge property???
}
}
I have figure out the problem by walking through this example: https://www.boost.org/doc/libs/1_71_0/libs/graph/doc/bundles.html
The fix:
Although I still don't exactly understand how it all works. It seems like you have to use edge_iter as some kind of index into g:
//Edge iterator for or graph
typedef boost::graph_traits<MRFGraph>::edge_iterator edge_iterator;
//Iterate through all the edges
std::pair<edge_iterator, edge_iterator> ei = boost::edges(g);
for(edge_iterator edge_iter = ei.first; edge_iter != ei.second; ++edge_iter) {
g[*edge_iter].name = "bar";
std::cout << *edge_iter << ": " << g[*edge_iter].name << std::endl;
}
Output:
If I add this to the minimal working demonstration, it produces the following output:
9
foo
(0,1): bar
(1,2): bar
(3,2): bar
(2,6): bar
(7,2): bar
(3,4): bar
(4,5): bar
(6,5): bar
(7,5): bar
May not be exactly what you are looking for but does achieve what you are after
#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
namespace boost {
enum edge_myname_t { edge_myname };
BOOST_INSTALL_PROPERTY(boost::edge, myname);
}
int main(int argc, char* argv[]) {
// Add vertex information struct
struct vertex_info {
std::string name;
};
// Add edge information struct
//struct edge_info {
//std::string name;
//};
using EdgeName = boost::property<boost::edge_myname_t, std::string>;
// Typedef my graph implimentation
using UndirectedGraph =
boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
vertex_info, EdgeName>;
// Our set of edges, and count N: (0-7) and 8
enum { C, D, G, I, S, J, L, H, N };
const char* name = "CDGISJLH";
// Create a vector of edges
//using Edge = std::pair<int, int>;
//std::vector<Edge> edgeVec;
//edgeVec.push_back(Edge(C, D));
//edgeVec.push_back(Edge(D, G));
//edgeVec.push_back(Edge(I, G));
//edgeVec.push_back(Edge(G, L));
//edgeVec.push_back(Edge(H, G));
//edgeVec.push_back(Edge(I, S));
//edgeVec.push_back(Edge(S, J));
//edgeVec.push_back(Edge(L, J));
//edgeVec.push_back(Edge(H, J));
// Now we can initialize our graph using iterators from our above vector
UndirectedGraph g(N);
//UndirectedGraph g(edgeVec.begin(), edgeVec.end(), N);
boost::add_edge(C, D, EdgeName("#1"), g);
boost::add_edge(D, G, EdgeName("#2"), g);
boost::add_edge(I, G, EdgeName("#3"), g);
boost::add_edge(G, L, EdgeName("#4"), g);
boost::add_edge(H, G, EdgeName("#5"), g);
boost::add_edge(I, S, EdgeName("#6"), g);
boost::add_edge(S, J, EdgeName("#7"), g);
boost::add_edge(L, J, EdgeName("#8"), g);
boost::add_edge(H, J, EdgeName("#9"), g);
boost::property_map<UndirectedGraph, boost::edge_myname_t>::type get_name =
boost::get(boost::edge_myname, g);
std::cout << num_edges(g) << "\n"; // Outputs: 9
// loop over vertices, access "name" property
for (size_t i = 0; i < boost::num_vertices(g); i++) {
// And add information to the edges
g[i].name = "foo";
}
// We can access the first vertice and print the property
std::cout << g[0].name << std::endl; // Outputs: foo
// Edge iterator for or graph
using EdgeIterator = boost::graph_traits<UndirectedGraph>::edge_iterator;
// Iterate through all the edges
std::pair<EdgeIterator, EdgeIterator> ei = boost::edges(g);
for (EdgeIterator edge_iter = ei.first; edge_iter != ei.second; ++edge_iter) {
// How can I access the edge property???
std::cout << get_name[*edge_iter] << "\n";
}
}
I just slightly modified some of the code for my own readability issues.
For reference, check this out.
It is straight forward to add edge weights to a graph as internal properties:
void InternalProperties()
{
std::cout << "InternalProperties()" << std::endl;
// Graph with internal edge weights
using EdgeWeightProperty = boost::property<boost::edge_weight_t, double>; // <tag, type>
using GraphWithInternalEdgeWeightsType = boost::adjacency_list<boost::setS, // out edge container
boost::vecS, // vertex container
boost::undirectedS, // directed or undirected
boost::no_property, // vertex properites
EdgeWeightProperty> // edge properties
;
// Create a graph object
GraphWithInternalEdgeWeightsType g(3);
// add two edges with edge weights
EdgeWeightProperty e1 = 5;
add_edge(0, 1, e1, g);
EdgeWeightProperty e2 = 3;
add_edge(1, 2, e2, g);
boost::property_map<GraphWithInternalEdgeWeightsType, boost::edge_weight_t>::type edgeWeightMap = get(boost::edge_weight_t(), g);
using edge_iter = boost::graph_traits<GraphWithInternalEdgeWeightsType>::edge_iterator;
std::pair<edge_iter, edge_iter> edgePair;
for(edgePair = edges(g); edgePair.first != edgePair.second; ++edgePair.first) {
std::cout << edgeWeightMap[*edgePair.first] << " ";
}
}
Now if I want to do the same thing and demonstrate using "external properties", I came up with this, but there is really no link at all back to the original graph:
void ExternalProperties()
{
std::cout << std::endl << "ExternalProperties()" << std::endl;
// Graph with external edge weights
using GraphWithExternalEdgeWeightsType = boost::adjacency_list<boost::setS, // out edge container
boost::vecS, // vertex container
boost::undirectedS> // directed or undirected
;
// Create a graph object
GraphWithExternalEdgeWeightsType g(3);
// add edges (without edge weights)
add_edge(0, 1, g);
add_edge(1, 2, g);
// create a map from edge_descriptors to weights and populate it
std::map<GraphWithExternalEdgeWeightsType::edge_descriptor, double> edgeWeightMap;
edgeWeightMap[boost::edge(0,1,g).first] = 5;
edgeWeightMap[boost::edge(1,2,g).first] = 3;
using edge_iter = boost::graph_traits<GraphWithExternalEdgeWeightsType>::edge_iterator;
std::pair<edge_iter, edge_iter> edgePair;
for(edgePair = edges(g); edgePair.first != edgePair.second; ++edgePair.first) {
std::cout << edgeWeightMap[*edgePair.first] << " ";
}
}
Is there any way to make something like get(boost::edge_weight_t(), g); (from the internal example) return this map? Like to say g.setPropertyMap(boost::edge_weight_t, edgeWeightMap) in this external example?
I'm not sure what the gain is, but perhaps this helps for inspiration:
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <map>
#include <iostream>
namespace MyLib {
struct MyGraph : boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS> {
using base_type = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS>;
using base_type::adjacency_list;
std::map<edge_descriptor, double> m_weights;
};
auto get(boost::edge_weight_t, MyGraph& g) { return boost::make_assoc_property_map(g.m_weights); }
auto get(boost::edge_weight_t, MyGraph const& g) { return boost::make_assoc_property_map(g.m_weights); }
}
namespace boost {
template <> struct graph_traits<MyLib::MyGraph> : graph_traits<adjacency_list<setS, vecS, undirectedS> > {};
template <> struct property_map<MyLib::MyGraph, edge_weight_t, void> {
using Traits = graph_traits<MyLib::MyGraph>;
using Edge = Traits::edge_descriptor;
using type = boost::associative_property_map<std::map<Edge, double> >;
using const_type = boost::associative_property_map<std::map<Edge, double> > const;
};
}
void ExternalProperties() {
std::cout << "ExternalProperties()" << std::endl;
// Graph with external edge weights
// Create a graph object
using Graph = MyLib::MyGraph;
Graph g(3);
// add edges (without edge weights)
add_edge(0, 1, g);
add_edge(1, 2, g);
// create a map from edge_descriptors to weights and populate it
auto edgeWeightMap = MyLib::get(boost::edge_weight, g);
edgeWeightMap[boost::edge(0, 1, g).first] = 5;
edgeWeightMap[boost::edge(1, 2, g).first] = 3;
using edge_iter = boost::graph_traits<Graph>::edge_iterator;
std::pair<edge_iter, edge_iter> edgePair;
for (edgePair = edges(g); edgePair.first != edgePair.second; ++edgePair.first) {
std::cout << edgeWeightMap[*edgePair.first] << " ";
}
}
int main() {
ExternalProperties();
}
I've not been able to avoid ambiguity with boost::get in such a way that you can trust ADL to pick the "best" overload without namespace qualification.
Live On Coliur
I have just realized that I have not yet understood how to use boost graph library. I have this code:
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
using namespace std;
using namespace boost;
typedef unsigned int WeightType;
typedef adjacency_list<listS, vecS, bidirectionalS,
no_property, property<edge_weight_t, WeightType>> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef graph_traits<Graph>::edge_descriptor Edge;
typedef property_map<Graph, edge_weight_t>::type WeightMap;
typedef property_map<Graph, edge_weight_t>::const_type ConstWeightMap;
const WeightType infinity = numeric_limits<WeightType>::max();
int main() {
Graph g(4);
Graph g2(4);
for (uint i = 0; i < 3; ++i) {
add_edge(i, i+1, i, g);
add_edge(i, i+1, i*10, g2);
}
WeightMap m = get(edge_weight, g);
WeightMap m2 = get(edge_weight, g2);
for (auto e : make_iterator_range(edges(g))) {
cout << m[e] << endl;
}
cout << endl;
for (auto e : make_iterator_range(edges(g))) {
cout << m2[e] << endl;
}
}
I would expect an output like: "0 1 2 , 0 10 20". But the output is "0 1 2, 0 1 2". Every graph have its weight property map, doesn't it? Where is my mistake?
You made a typo in the second for loop:
for (auto e : make_iterator_range(edges(g))) {
Should be:
for (auto e : make_iterator_range(edges(g2))) {
So you were printing the content of the first graph twice, instead of the first then the second.
I would like to use the Boost Graph Library more effectively by attaching properly encapsulated classes to graph nodes & edges. I am not interested in attaching int's or POD struct's. Following suggestions on other StackOverFlow articles, I have developed the following sample app. Can anybody tell me the magic I need to sprinkle onto the EdgeInfo class to make this thing compile?
I am using Visual Studio 2010 with Boost 1.54.0.
//------------------------------------------------------------------------
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <iostream>
//------------------------------------------------------------------------
struct VertexInfo
{
struct Tag
{
typedef boost::vertex_property_tag kind;
static std::size_t const num; // ???
};
typedef boost::property<Tag, VertexInfo> Property;
};
std::size_t const VertexInfo::Tag::num = reinterpret_cast<std::size_t> (&VertexInfo::Tag::num);
//------------------------------------------------------------------------
class EdgeInfo
{
int _nWeight;
public:
int getWeight () const {return _nWeight;}
struct Tag
{
typedef boost::edge_property_tag kind;
static std::size_t const num; // ???
};
typedef boost::property<boost::edge_weight_t, int> Weight;
typedef boost::property<Tag, EdgeInfo> Property;
EdgeInfo (int nWeight = 9999) : _nWeight (nWeight) {}
};
std::size_t const EdgeInfo::Tag::num = reinterpret_cast<std::size_t> (&EdgeInfo::Tag::num);
//------------------------------------------------------------------------
typedef boost::property<boost::edge_weight_t, int> EdgeProperty;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexInfo::Property, EdgeProperty> GraphWorking;
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexInfo::Property, EdgeInfo::Property> GraphBroken;
//------------------------------------------------------------------------
template<typename GraphType, typename EdgeType> void
dijkstra (GraphType g, EdgeType e)
{
typedef boost::graph_traits<GraphType>::vertex_descriptor VertexDesc;
typedef boost::graph_traits<GraphType>::edge_descriptor EdgeDesc;
VertexDesc u = add_vertex (g);
VertexDesc v = add_vertex (g);
std::pair<EdgeDesc, bool> result = add_edge (u, v, e, g);
std::vector<VertexDesc> vecParent (num_vertices (g), 0);
dijkstra_shortest_paths (g, u, boost::predecessor_map (&vecParent[0]));
}
//------------------------------------------------------------------------
int
main (int argc, char** argv)
{
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
std::cout << "Buy a new compiler\n";
#else
std::cout << "Your compiler is fine\n";
#endif
GraphWorking gWorking;
GraphBroken gBroken;
dijkstra (gWorking, 3);
dijkstra (gBroken, EdgeInfo (4));
}
//------------------------------------------------------------------------
When I run your code i get an error in numeric_limits that results from a distance map in dijkstra.
"
Error 1 error C2440: '' : cannot convert from 'int' to 'D' c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\limits 92
"
probably from this part of http://www.boost.org/doc/libs/1_55_0/boost/graph/dijkstra_shortest_paths.hpp
typedef typename property_traits<DistanceMap>::value_type D;
D inf = choose_param(get_param(params, distance_inf_t()),
(std::numeric_limits<D>::max)());
I think there may be an easier way to tie a real class for your nodes and edges. Its more trouble than its worth to create vertex and edge property classes that will provide all the needed tagged properties (index, weight, color, etc) needed for most boost algorihtms.
Don't forget Edge class != Edge property.
The edge class is really the graph_traits::edge_discriptor.
Properties are the data associated with each edge. Same for vertex.
I would use bundled properties and add a pointer to your class in each one.
Here is an example
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/properties.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/property_map/property_map.hpp>
#include <iostream>
//Fancy Edge class
class EdgeData
{
int _data;
public:
EdgeData(){
_data=0;
}
EdgeData(int data){
_data= data;
}
void printHello(){
std::cout << "hello " << _data << std::endl;
}
};
//Fancy Vert class
class VertexData
{
int _data;
public:
VertexData(){
_data=0;
}
VertexData(int data){
_data= data;
}
void printHello(){
std::cout << "hello " << _data << std::endl;
}
};
//bundled properties
struct VertexProps
{
VertexData* data;
};
struct EdgeProps
{
size_t weight;
EdgeData* data;
};
//Graph
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
VertexProps,EdgeProps> Graph;
//helpers
//Vertex
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
//Edge
typedef boost::graph_traits<Graph>::edge_descriptor Edge;
//------------------------------------------------------------------------
template<typename GraphType> void
templateFunction (GraphType g)
{
typedef boost::graph_traits<GraphType>::edge_iterator edge_iter;
std::pair<edge_iter, edge_iter> ep;
edge_iter ei, ei_end;
ep = edges(g);
ei_end = ep.second;
for (ei = ep.first; ei != ei_end; ++ei){
g[*ei].data->printHello();
}
}
//if you want to alter the graph use referenced &graph
template<typename GraphType,typename EdgePropType> void
templateFuctionProps(GraphType &g, EdgePropType e)
{
typedef boost::graph_traits<GraphType>::vertex_descriptor VertexDesc;
VertexDesc v = add_vertex(g);
VertexDesc u = add_vertex(g);
//add an edge with the Edge property
add_edge(v,u,e,g);
}
//------------------------------------------------------------------------
int
main (int argc, char** argv)
{
Graph g;
//vertex holder
std::vector<Vertex> verts;
//add some verts
for(size_t i = 0; i < 5; ++i){
Vertex v = add_vertex(g);
g[v].data = new VertexData(i%2);
verts.push_back(v);
}
//add some edges
for(size_t i = 0; i < 4; ++i){
std::pair<Edge,bool> p = add_edge(verts.at(i),verts.at(i+1),g);
Edge e = p.first;
g[e].data = new EdgeData(i%3);
g[e].weight = 5;
}
//iterate edges and call a class function
typedef boost::graph_traits<Graph>::edge_iterator edge_iter;
std::pair<edge_iter, edge_iter> ep;
edge_iter ei, ei_end;
ep = edges(g);
ei_end = ep.second;
for (ei = ep.first; ei != ei_end; ++ei){
g[*ei].data->printHello();
}
std::cout << "Iterate with template with template " << std::endl;
templateFunction(g);
//Use an edge property in a function
EdgeProps edgeProp;
edgeProp.weight = 5;
edgeProp.data = new EdgeData(150);
std::cout << "Modity graph with template function " << std::endl;
templateFuctionProps(g,edgeProp);
std::cout << "Iterate again with template" << std::endl;
templateFunction(g);
//getting the weight property
boost::property_map<Graph,size_t EdgeProps::*>::type w
= get(&EdgeProps::weight, g);
std::cout << "Print weights" << std::endl;
ep = edges(g);
ei_end = ep.second;
for (ei = ep.first; ei != ei_end; ++ei){
std::cout << w[*ei] << std::endl;
}
std::cin.get();
}
//------------------------------------------------------------------------
Also I see you are using vecS, meaning that both vectors and edges are stored as vectors with a fixed ordering.
You could just have a class that stores your Edge and Vertex classes with a pointer to the vertex map or edge map for the graph.
I don't know your goals for this project, but I would definitely have higher level classes than manage all of this boost stuff behind the scenes. Meaning storing classes in a vector with an index look up would be hidden and encapsulated from applications that want to use your nice graph class.
I'm new to BGL and I have a problem with making own property maps which key is edge_property
can you tell me what I'm doing wrong that following code prints not :
(0,1) == (0,1) ? 1
but
(0,1) == (0,1) ? 0
Here is the code
#include <boost/graph/adjacency_list.hpp>
#include <iostream>
#include <map>
using namespace std;
class A {};
class B {};
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::bidirectionalS,
A, B > Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Graph>::edge_iterator edge_iterator;
typedef boost::graph_traits<Graph>::in_edge_iterator in_edge_iterator;
typedef boost::graph_traits<Graph>::out_edge_iterator out_edge_iterator;
map<edge_descriptor, int> fun(Graph g){
map<edge_descriptor, int> m;
m[*(edges(g).first)] = 5;
return m;
}
int main(){
Graph g;
vertex_descriptor a = add_vertex(g);
vertex_descriptor b = add_vertex(g);
add_edge(a, b, g);
map<edge_descriptor, int> m = fun(g);
edge_iterator ei, ei_end;
for(tie(ei, ei_end) = edges(g) ; ei !=ei_end ; ++ei){
cout << m.begin()->first << " == " << *ei << " ? " << (m.begin()->first == *ei) << endl;
}
}
thank you very much!
EDIT:
maybe there is a better way to map edge than by edge_property value?
Your edge descriptor has 3 members: source node, target node and a pointer to your B property. In your fun you make a copy of your graph, and the copied edge in your new graph points to a different B. If you declare your fun as map<edge_descriptor, int> fun(const Graph& g) (and you probably should since a copy of a bigger graph can be expensive) you obtain the result you expect.