Adding objects to the boost::graph - c++

I am trying to create a graph of objects which I need to traverse using some traversal algorithm. At this very moment I am stuck trying to create the graph using my custom objects. The way I am trying to accomplish it is as follows:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <iostream>
using namespace std;
typedef boost::adjacency_list<boost::vecS,boost::vecS,boost::directedS> CustomGraph;
typedef boost::graph_traits<CustomGraph>::vertex_descriptor CustomVertex;
class CustomVisitor:public boost::default_dfs_visitor
{
public:
void discover_vertex(CustomVertex v,const CustomGraph& taskGraph) const
{
cerr<<v<<endl;
return;
}
};
class CustomObject{
private:
int currentId;
public:
CustomObject(int id){
currentId = id;
}
};
int main()
{
CustomGraph customGraph;
CustomObject* obj0 = new CustomObject(0);
CustomObject* obj1 = new CustomObject(1);
CustomObject* obj2 = new CustomObject(2);
CustomObject* obj3 = new CustomObject(3);
typedef std::pair<CustomObject*,CustomObject*> Edge;
std::vector<Edge> edgeVec;
edgeVec.push_back(Edge(obj0,obj1));
edgeVec.push_back(Edge(obj0,obj2));
edgeVec.push_back(Edge(obj1,obj2));
edgeVec.push_back(Edge(obj1,obj3));
customGraph(edgeVec.begin(),edgeVec.end());
CustomVisitor vis;
boost::depth_first_search(customGraph,boost::visitor(vis));
return 0;
}
But this doesn't seem to be the right way to create objects within the vertices. Can somebody guide me as to what is the correct way to create nodes such that I can retrieve my objects while traversing the graph.
Thanks

Hi I know this is a rather old question, but there might others that can benefit from an answer.
It seems as if you have forgotten to define that your Graph will have a custom class as vertices. You have to add a fourth parameter to your typedef and add a typedef for your edge:
typedef boost::adjacency_list<boost::vecS,boost::vecS,boost::directedS, CustomObject> CustomGraph;
typedef boost::graph_traits<CustomGraph>::vertex_descriptor CustomVertex;
typedef boost::graph_traits<CustomGraph>::edge_descriptor CustomEdge;
Then I usually add my nodes before connecting them with edges:
// Create graph and custom obj's
CustomGraph customGraph
CustomObject obj0(0);
CustomObject obj1(1);
CustomObject obj2(2);
CustomObject obj3(3);
// Add custom obj's to the graph
// (Creating boost vertices)
CustomVertex v0 = boost::add_vertex(obj0, customGraph);
CustomVertex v1 = boost::add_vertex(obj1, customGraph);
CustomVertex v2 = boost::add_vertex(obj2, customGraph);
CustomVertex v3 = boost::add_vertex(obj3, customGraph);
// Add edge
CustomEdge edge;
bool edgeExists;
// check if edge allready exist (only if you don't want parallel edges)
boost::tie(edge, edgeExists) = boost::edge(v0 , v1, customGraph);
if(!edgeExists)
boost::add_edge(v0 , v1, customGraph);
// write graph to console
cout << "\n-- graphviz output START --" << endl;
boost::write_graphviz(cout, customGraph);
cout << "\n-- graphviz output END --" << endl;

Related

Restore order of polygons after CGAL::Polyline_simplification_2

I follow this example of the CGAL documentation in order to simplify a number of polygons, which are initially stored in a vector called polys. Afterwards I collect the simplified polygons into a vector called simple_polys. However, the order of the polygons is mixed up during the simplification. This means simple_polys[i] is not necessarily the simplified version of polys[i]. I would be thankful for any ideas on how to adapt my code (see below) such that the order of the polygons is maintained or restored.
Notice: The obvious solution to simplify each polygon individually is not an option for me, since I need to preserve the common edges of the polygons (if there are any), i.e., the common edges are allowed to be simplified but they must remain common edges.
Here is the current version of my code:
#include <vector>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/Polyline_simplification_2/simplify.h>
#include <CGAL/Polyline_simplification_2/Squared_distance_cost.h>
#include <CGAL/IO/WKT.h>
// CGAL typedefs
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
// CGAL classes needed for polyline simplification
namespace PS = CGAL::Polyline_simplification_2;
typedef PS::Vertex_base_2<Kernel> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> TDS;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, CGAL::Exact_predicates_tag> CDT;
typedef CGAL::Constrained_triangulation_plus_2<CDT> CT;
typedef PS::Stop_above_cost_threshold Stop;
typedef PS::Squared_distance_cost Cost;
int main()
{
// Read the polygons from WTK file
std::ifstream is("polys.wkt");
std::vector<Polygon_2> polys;
do {
Polygon_2 p;
CGAL::IO::read_polygon_WKT(is, p);
if(!p.is_empty())
polys.push_back(p);
} while(is.good() && !is.eof());
// Insert the polygons into a Constrained_triangulation_plus_2
CT ct;
for ( auto poly : polys ) ct.insert_constraint(poly);
// Simplify the polygons
PS::simplify(ct, Cost(), Stop(2.0));
// Convert the result back into normal polygons
std::vector<Polygon_2> simple_polys;
for( CT::Constraint_iterator cit = ct.constraints_begin(); cit != ct.constraints_end(); ++cit)
{
Polygon_2 poly;
for ( CT::Points_in_constraint_iterator vit = ct.points_in_constraint_begin(*cit);
vit != ct.points_in_constraint_end(*cit); ++vit) poly.push_back(*vit);
simple_polys.push_back(poly);
}
}
Here is an example of a WKT input file one can use to run the above code (name it polys.wkt):
POLYGON((46.465 -37.3521,35.5358 -20.6702,48.8869 -11.958,51.9866 -16.8288,50.0332 -18.1056,54.9318 -25.6487,55.8444 -25.0541,55.5429 -22.8841,73.1793 -11.5299,77.2208 -17.435))
POLYGON((150.934 48.3496,137.482 47.0145,136.581 54.533,134.581 54.3679,134.206 58.2453,136.107 58.4855,135.177 66.2472,148.772 67.1611))
POLYGON((113.969 -24.4624,103.013 -25.5321,102.007 -15.8837,101.437 -15.8568,101.143 -12.0671,101.652 -12.0653,100.581 -1.99834,107.794 -1.3459,107.853 -2.01614,111.495 -1.66637,111.568 -1.96882,111.947 -1.88637))
POLYGON((35.8102 -21.0888,27.2558 -8.05192,38.1005 -0.96724,44.4211 -10.2175,45.1996 -9.66818,45.021 -9.3973,45.5261 -7.35956,50.2289 -4.30611,50.4096 -3.43368,64.9678 6.02664,66.7379 -0.809735))
POLYGON((-1.28342 -115.889,22.725 -111.81,25.6615 -128.839,16.2488 -130.272,16.4807 -131.888,12.9582 -132.401,12.7173 -130.807,12.4127 -130.833,16.6721 -156.064,0.111882 -158.497,-1.28339 -150.737))
POLYGON((133.248 -68.93,100.825 -72.0011,99.8362 -61.4584,107.418 -60.8479,107.399 -60.397,110.68 -60.2175,110.691 -60.6869,120.743 -59.7579,120.696 -59.3589,124.041 -59.0963,124.058 -59.5348,132.275 -58.7058))
POLYGON((118.371 29.3127,111.786 28.6569,110.332 42.1233,117.682 42.8478,117.895 41.5415,118.397 41.5653,118.858 38.6083,118.3 38.521,118.704 35.4032,117.714 35.3187))
POLYGON((146.407 -67.6797,132.75 -68.9772,131.777 -58.752,135.766 -58.415,135.713 -57.87,138.974 -57.6063,139.028 -58.0592,145.445 -57.5652))
POLYGON((38.7765 -180.005,42.57 -177.511,39.8274 -173.17,45.4545 -169.387,34.4094 -152.557,47.1264 -144.271,47.0159 -144.108,51.1497 -141.344,53.8363 -145.461,55.5009 -144.64,58.878 -149.842,57.4133 -151.006,61.0026 -156.489,62.2453 -155.685,67.94 -140.543,85.4228 -166.825,64.2719 -180.516,60.9827 -175.481,56.3313 -178.594,57.1839 -179.899,44.1068 -188.413))
POLYGON((117.162 35.7683,136.609 37.8265,137.825 36.8336,138.697 36.9208,137.923 42.338,137.507 42.2789,137.23 44.2193,137.646 44.2784,137.59 44.664,137.165 44.6034,136.887 46.5429,137.314 46.6042,137.188 47.4854,150.877 48.8464,152.721 32.789,117.873 29.2627))
POLYGON((115.832 -45.2902,104.975 -46.2859,104.142 -37.6361,103.622 -37.7286,103.332 -34.3286,103.777 -34.0371,102.964 -25.0344,113.924 -23.9644))
POLYGON((66.5341 -28.0144,70.402 -33.9903,70.291 -34.3719,60.4063 -40.7947,59.9046 -40.7393,56.0238 -34.773,56.1665 -34.3699,56.3403 -34.274,66.1632 -27.8986))
POLYGON((105.673 -127.635,90.8711 -104.911,92.492 -102.406,115.3 -100.248,116.48 -111.052,112.586 -111.576,112.605 -111.81,111.09 -112.735,110.572 -112.55,110.365 -112.893,115.687 -121.196))
POLYGON((152.194 5.74036,111.195 -2.55811,111.11 -2.20564,107.405 -2.56147,106.262 7.74335,143.459 15.1823,142.642 22.9693,142.005 22.9033,141.67 26.0846,142.307 26.1507,141.68 32.1367,152.665 33.2868,154.612 15.5801,151.26 15.2101,151.847 9.88508,151.738 9.87268))
POLYGON((22.9004 58.0935,-1.28339 56.2459,-1.28339 62.8131,-0.817275 62.867,-0.1184 63.6614,5.80649 64.1534,6.12005 64.7858,8.92235 65.0356,9.85597 64.4913,21.9914 65.718))
I was able to figure it out myself. I post the solution here in case it would be useful for somebody else in the future. The solution is to make a connection between the indices of the polygons in the vector polys and the IDs of the constraints in the Constrained_triangulation_plus_2 object. Below is the adapted code which includes the solution to the problem.
#include <vector>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/Polyline_simplification_2/simplify.h>
#include <CGAL/Polyline_simplification_2/Squared_distance_cost.h>
#include <CGAL/IO/WKT.h>
// CGAL typedefs
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
// CGAL classes needed for polyline simplification
namespace PS = CGAL::Polyline_simplification_2;
typedef PS::Vertex_base_2<Kernel> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> TDS;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, CGAL::Exact_predicates_tag> CDT;
typedef CGAL::Constrained_triangulation_plus_2<CDT> CT;
typedef PS::Stop_above_cost_threshold Stop;
typedef PS::Squared_distance_cost Cost;
int main()
{
// Read the polygons from WTK file
std::ifstream is("polys.wkt");
std::vector<Polygon_2> polys;
do {
Polygon_2 p;
CGAL::IO::read_polygon_WKT(is, p);
if(!p.is_empty())
polys.push_back(p);
} while(is.good() && !is.eof());
// Insert the polygons into a Constrained_triangulation_plus_2 and keep
// track of the constraint IDs
CT ct;
std::vector<CT::Constraint_id> constraint_IDs;
for ( auto poly : polys )
{
CT::Constraint_id ID = ct.insert_constraint(poly);
constraint_IDs.push_back(ID);
}
// Simplify the polygons
PS::simplify(ct, Cost(), Stop(2.0));
// Convert the result back into normal polygons
std::vector<Polygon_2> simple_polys(polys.size());
for( CT::Constraint_iterator cit = ct.constraints_begin(); cit != ct.constraints_end(); ++cit)
{
// Find the index of the constraint ID in the constraint_IDs vector. This is the index
// of the original polygon the current simplified polygon corresponds to
auto it = std::find(constraint_IDs.begin(), constraint_IDs.end(), *cit);
size_t idx = it - constraint_IDs.begin();
// Obtain the simplified polygon
Polygon_2 poly;
for ( CT::Points_in_constraint_iterator vit = ct.points_in_constraint_begin(*cit);
vit != ct.points_in_constraint_end(*cit); ++vit) poly.push_back(*vit);
// Write the simplified polygon to the correct location
simple_polys[idx] = poly;
}
}

How to get vertex from boost graph in constant time?

I'm trying to create a graph where lanes represent vertices and edges connections between. The idea is to later on use a_star algorithm to traverse the graph and find the best route.
My question is how can I get vertex (descriptor?) by using just (town_id, road_id, lane_id)?
I tryied battling with the examples that are shipped with boost and basically lost. In them they always traverse thru all the vertices and then get the vertex_descriptor, but I want to do that in constant time.
What is need is something like boost::get_vertex(std::tuple(1, 2, 3), graph).
My situation is marked as PROBLEM bellow in the code. The code bellow compiles because there is 12 that I guess corresponds to the index in boost::vecS, but I want to use a tuple (or something else that can hold the triplet) that could get me the vertex descriptor as my starting location.
using TRL = std::tuple<int, int, int>;
struct TRL_VProp {
/// For some reason this object has to be default constructable
/// use invalid data to flag it as invalid
TRL_VProp()
: trl(-1, -1, 0) {}
TRL_VProp(TRL trl)
: trl(trl) {}
TRL_VProp(int town_id, int road_id, int lane_id)
: trl(town_id, road_id, lane_id) {}
TRL trl;
};
using DirectedGraph = boost::adjacency_list<boost::listS,
boost::vecS,
boost::directedS,
RSL_VProp>;
using Vertex = boost::graph_traits<DirectedGraph>::vertex_descriptor;
using VertexI = boost::graph_traits<DirectedGraph>::vertex_iterator;
using EdgeI = boost::graph_traits<DirectedGraph>::edge_iterator;
using Edge = boost::graph_traits<DirectedGraph>::edge_descriptor;
using AdjI = boost::graph_traits<DirectedGraph>::adjacency_iterator;
using Route = std:vector<TRL>;
Route BuildRoute(Map & map) {
Route result;
DirectedGraph graph;
const boost::property_map<DirectedGraph, RSL RSL_VProp:: *>::type trl =
boost::get(&TRL_VProp::rsl, graph);
bool is_inserted;
Edge e_desc;
for (auto & town: map.GetTowns()) {
for (auto & road: town.GetRoads()) {
for (auto & lane: road.GetLanes()) {
auto vtx_1 = boost::add_vertex(
RSL_VProp(town.GetId(), road.GetId(), lane.GetId()),
graph);
const auto next_lanes = map.GetNextLanes(town.GetId(), road.GetId(), lane.GetId());
for(const auto & next_lane : next_lanes) {
auto vtx_2 = boost::add_vertex(
TRL_VProp(lane.GetTown().GetId(), lane.GetRoad().GetId(), lane.GetId()),
graph);
std::tie(e_desc, is_inserted) = boost::add_edge(vtx_1, vtx_2, graph);
assert(is_inserted);
}
}
}
}
// debug part
TRL temp_trl;
std::pair<AdjI, AdjI> adj_i = boost::adjacent_vertices(12, graph); // <--- PROBLEM
for( auto i = adj_i.first; i != adj_i.second; i++) {
temp_trl = trl[*i]; // trl prop map
std:: cout << "\Town id: " << std::get<0>(temp_trl)
<< "\nRoad id: " << std::get<1>(temp_trl)
<< "\nLane id: " << std::get<2>(temp_trl);
result.push_back(
std::make_tuple(
std::get<0>(temp_trl),
std::get<1>(temp_trl),
std::get<2>(temp_trl)));
}
return result;
}
For completeness, I don't plan to change data inside the property or the graph itself. Once thing is created it will probably stay that way. Maybe lateron I'll probably have to add the weight or whatever is necessary to get the traversing algorithm to work.
Edit: I forgot to mention that there is a bug in the code because I'm adding vertices before checking was vertex with identical (town, road, lane) already been created. I wonder is there a builtin boost::graph way to not insert duplicated so I won't have to use a std::unordered_map or something.

Writing boost dynamic properties to a file using Boost Graph Library

I have already asked a question here about using Boost Graph Library and writing graph into file. Due to change in my requirements, I need to write dynamic graph properties into a DOT file. After some look up, I managed to come up with some code but it does not work. Below is what I have done so far:
Map class uses the Cell class as vertices and Cell class uses a separate CellProperty class for setting and getting all the Cell properties.
And finally Map class where I build the graph and try to write the graph into a DOT file.
Map.h
class Map {
public:
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, Cell> Graph;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
explicit Map(std::string pGraphFilePath);
virtual ~Map();
void LoadGraph();
private:
Graph mGraph;
std::vector<std::vector<Vertex>> mGrid;
};
Map.cpp
const unsigned int RowNum = 3;
const unsigned int ColumnNum = 4;
Map::Map(std::string pGraphFilePath) : mGraph(), mGrid() {}
Map::~Map() {}
void Map::LoadGraph() {
int dummyID = 1;
for (unsigned int row = 0; row < RowNum; row++) {
mGrid.resize(RowNum);
for (unsigned int col = 0; col < ColumnNum; col++) {
mGrid[row].resize(ColumnNum);
Vertex vID = boost::add_vertex(mGraph);
mGraph[vID].SetProperty<unsigned int>("ID", dummyID);
mGraph[vID].SetProperty<bool>("Navigable", true);
mGrid[row][col] = vID;
dummyID++;
// add the edges for the contained cells in the grid
if (col > 0) { boost::add_edge(mGrid[row][col - 1], mGrid[row][col], mGraph); }
if (row > 0) { boost::add_edge(mGrid[row - 1][col], mGrid[row][col], mGraph); }
}
}
// write cell properties
boost::dynamic_properties propertiesOutPut;
propertiesOutPut.property("ID", boost::get(boost::vertex_index, mGraph));
// As Navigable is an external property, it need to be mapped with the internal graph property
// the lines below are the update after I got the answers and link for my query
// cell.GetProperty() is a templated method the takes a default parameter, thus passing "false" bool parameter which returns the "Navigable" cell property
auto valueNavigable = boost::make_transform_value_property_map([](Cell &cell) { return cell.GetProperty<bool>("Navigable", false); }, boost::get(boost::vertex_bundle, mGraph));
propertiesOutPut.property("Navigable", valueNavigable);
std::ofstream fout("MyGraph.dot");
boost::write_graphviz_dp(fout, mGraph, propertiesOutPut, std::string("ID"));
}
The problem I am getting is with the propertiesOutPut.property() method for boost::get(). I can not figure out the correct parameters for boost::get(). Please help me out. Thanks !!
You could use a transform_value_property_map on top of the propertymap that contains the vertex properties struct. (You didn't show it).
I have a number of answers showing how to do that, although these are all using internal properties, there is no big difference because anu property map can be transformed in the same way, regardless of whether the property map is internal or external (that's the whole purpose of property maps: decoupling the way properties are accessed).
Most relevant:
Overloading streaming operators for a Boost Graph bundle output for GraphViz
Manually colouring of boost's graphs
Other:
see these search results: https://stackoverflow.com/search?tab=votes&q=user%3a85371%20make_transform_value_property_map

Boost-graph,accessing un-bundled vertex/edge properties [duplicate]

I have my custom vertex and edge properties
namespace boost {
enum vertex_diagonal_t{vertex_diagonal = 999};
BOOST_INSTALL_PROPERTY(vertex, diagonal);
}
namespace boost {
enum edge_dominance_t{edge_dominance = 998};
BOOST_INSTALL_PROPERTY(edge, dominance);
}
I create my adjacency list with boost::property
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_diagonal_t, const khut::diagonal*>,
boost::property<boost::edge_dominance_t, float>
> diagonal_dominance_graph;
typedef boost::property_map<diagonal_dominance_graph, boost::vertex_diagonal_t>::type diagonal_map_type;
typedef boost::property_map<diagonal_dominance_graph, boost::edge_dominance_t>::type dominance_map_type;
Now I want to loop through my own containers and add vertex
diagonal_dominance_graph graph;
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i){
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
//>> ?? HOW CAN I write Properties to dia_vertex HERE ?
//boost::property<boost::vertex_diagonal_t, const khut::diagonal*> p;
//boost::put(p, dia_vertex);
}
What I am not getting is How can I set properties of a vertex through vertex_descriptor. may be I am missing a simple function.
Please I don't need anything that makes BGL even more complex, or something that cleans and restructures the types in my example. I just need to know how to read/write properties through a vertex_descriptor or edge_descriptor
You're using property lists: they're documented here.
So in your example, you'd use
diagonal_map_type vp = get(boost::vertex_diagonal, graph);
using storage_type = std::vector<int>;
storage_type repo_begining(10);
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i) {
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
khut::diagonal* v = nullptr;
boost::put(vp, dia_vertex, v);
}
// likewise for edges
dominance_map_type ep = get(boost::edge_dominance, graph);
See it Live On Coliru
Bundled Properties
The very same documentation page says:
NOTE: The Boost Graph Library supports two interchangeable methods for specifying interior properties: bundled properties and property lists. The former is easier to use and requires less effort, whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism.
Boost 1.32 dates over 10 years ago! So, I'd suggest bundled properties:
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
namespace khut {
struct diagonal { };
struct MyVertexProperties {
diagonal const* diag_ptr;
};
struct MyEdgeProperties {
float dominance;
};
}
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
khut::MyVertexProperties,
khut::MyEdgeProperties
> diagonal_dominance_graph;
#include <iostream>
int main() {
using namespace boost;
diagonal_dominance_graph g;
khut::diagonal d1, d2;
{
auto v1 = add_vertex(khut::MyVertexProperties { &d1 }, g);
auto v2 = add_vertex(khut::MyVertexProperties { &d2 }, g);
/*auto e1 = */add_edge(v1, v2, khut::MyEdgeProperties { 42.31415926 }, g);
}
for(diagonal_dominance_graph::vertex_descriptor vd : make_iterator_range(vertices(g)))
std::cout << "Is diagonal d1? " << std::boolalpha << (&d1 == g[vd].diag_ptr) << "\n";
for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
std::cout << "Edge dominance: " << g[ed].dominance << "\n";
}
Prints
Is diagonal d1? true
Is diagonal d1? false
Edge dominance: 42.3142

Boost Graph accessing properties through vertex_descriptor

I have my custom vertex and edge properties
namespace boost {
enum vertex_diagonal_t{vertex_diagonal = 999};
BOOST_INSTALL_PROPERTY(vertex, diagonal);
}
namespace boost {
enum edge_dominance_t{edge_dominance = 998};
BOOST_INSTALL_PROPERTY(edge, dominance);
}
I create my adjacency list with boost::property
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_diagonal_t, const khut::diagonal*>,
boost::property<boost::edge_dominance_t, float>
> diagonal_dominance_graph;
typedef boost::property_map<diagonal_dominance_graph, boost::vertex_diagonal_t>::type diagonal_map_type;
typedef boost::property_map<diagonal_dominance_graph, boost::edge_dominance_t>::type dominance_map_type;
Now I want to loop through my own containers and add vertex
diagonal_dominance_graph graph;
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i){
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
//>> ?? HOW CAN I write Properties to dia_vertex HERE ?
//boost::property<boost::vertex_diagonal_t, const khut::diagonal*> p;
//boost::put(p, dia_vertex);
}
What I am not getting is How can I set properties of a vertex through vertex_descriptor. may be I am missing a simple function.
Please I don't need anything that makes BGL even more complex, or something that cleans and restructures the types in my example. I just need to know how to read/write properties through a vertex_descriptor or edge_descriptor
You're using property lists: they're documented here.
So in your example, you'd use
diagonal_map_type vp = get(boost::vertex_diagonal, graph);
using storage_type = std::vector<int>;
storage_type repo_begining(10);
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i) {
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
khut::diagonal* v = nullptr;
boost::put(vp, dia_vertex, v);
}
// likewise for edges
dominance_map_type ep = get(boost::edge_dominance, graph);
See it Live On Coliru
Bundled Properties
The very same documentation page says:
NOTE: The Boost Graph Library supports two interchangeable methods for specifying interior properties: bundled properties and property lists. The former is easier to use and requires less effort, whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism.
Boost 1.32 dates over 10 years ago! So, I'd suggest bundled properties:
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
namespace khut {
struct diagonal { };
struct MyVertexProperties {
diagonal const* diag_ptr;
};
struct MyEdgeProperties {
float dominance;
};
}
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
khut::MyVertexProperties,
khut::MyEdgeProperties
> diagonal_dominance_graph;
#include <iostream>
int main() {
using namespace boost;
diagonal_dominance_graph g;
khut::diagonal d1, d2;
{
auto v1 = add_vertex(khut::MyVertexProperties { &d1 }, g);
auto v2 = add_vertex(khut::MyVertexProperties { &d2 }, g);
/*auto e1 = */add_edge(v1, v2, khut::MyEdgeProperties { 42.31415926 }, g);
}
for(diagonal_dominance_graph::vertex_descriptor vd : make_iterator_range(vertices(g)))
std::cout << "Is diagonal d1? " << std::boolalpha << (&d1 == g[vd].diag_ptr) << "\n";
for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
std::cout << "Edge dominance: " << g[ed].dominance << "\n";
}
Prints
Is diagonal d1? true
Is diagonal d1? false
Edge dominance: 42.3142