Pratik E
Pratik E

Reputation: 31

How to access boost subgraph 'graph' properties?

I am using adjacency_list and subgraph adapter to create my graph type.

#include <boost/graph/subgraph.hpp>
#include <boost/graph/adjacency_list.hpp>

struct VertexProperties
{
    bool bIsExpandable;          
    string sId;
    string sCoord_X;
    string sCoord_Y;
    std::size_t order;
};

struct EdgeProperties
{
    string sId;
    bool bBidirectional;
};

//Graph properties
enum graph_index_t {graph_index=111};
namespace boost{
BOOST_INSTALL_PROPERTY(graph,index);
}

typedef boost::property<boost::vertex_index_t, std::size_t , VertexProperties> vertex_prop;
typedef boost::property<boost::edge_index_t, std::size_t , EdgeProperties> edge_prop;
typedef boost::property<graph_index_t, std::size_t> graph_prop;

typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
vertex_prop ,
edge_prop,
graph_prop>
Graph;

typedef boost::subgraph<Graph> Subgraph;

I am using bundled properties for vertices and edges. I have tried giving bundled property to 'graph', for adjacency_list it works fine but could not be used for subgraph adapter, I have found that it is not supported by boost subgraph adapter. So I added graph_index_t to graph properties, but I am not able to access it. I have written following property map to access it, but it seems that it not the correct way.

typedef property_map<Subgraph , graph_index_t>::type GraphIndexPropertyMap;

It gives error in adjacency_list.hpp

d:\boost_1_53_0\boost\graph\detail\adjacency_list.hpp:2543: error: forming reference to void

I have checked boost 1.53 documentation but could not find the way related to this.

So I have 2 Questions:

1) How to get read-write access to the graph_index property?

2) Can I use bundled property for 'graph' with boost subgraph in some way?

Can anyone help?

Thanks,

Pratik

Upvotes: 3

Views: 899

Answers (2)

CrouchEndTiger
CrouchEndTiger

Reputation: 147

This answer comes very late! But I just ran into the same problem and it took a while to figure out so I though I'd share my solution.

Bundled properties aren't an option. There's nothing in the docs saying why the following doesn't work. However it seems like the subgraph implementation is incompatible, because it doesn't compile.

Graph = boost::subgraph<boost::adjacency_list<
        boost::vecS,
        boost::vecS,
        boost::directedS,
        boost::property<boost::vertex_index_t, std::size_t>,
        boost::property<boost::edge_index_t, std::size_t>,
        std::string>>;

Graph graph;
graph[boost::graph_bundle] = "Graph bundle value";

The following solution did work for me, however. At the bottom of the subgraph docs page they detail the get_property function which has a read-only version (returning a const ref) and a writable version (returning a ref).

namespace boost{
enum graph_index_t {graph_index=111};
BOOST_INSTALL_PROPERTY(graph,index);
}

Graph = boost::subgraph<boost::adjacency_list<
        boost::vecS,
        boost::vecS,
        boost::directedS,
        boost::property<boost::vertex_index_t, std::size_t>,
        boost::property<boost::edge_index_t, std::size_t>,
        boost::property<boost::graph_index_t, std::size_t>>>;

Graph graph;
boost::get_property(graph, boost::graph_index) = 69;

Upvotes: 1

mayur_narkhede
mayur_narkhede

Reputation: 1

Here is the solution for your problem, Which considers the accessing method in boost subgraph using bundled properties and dynamic properties as below:

#include <QtCore/QCoreApplication>

#include <boost/config.hpp>
#include <iostream>
#include <algorithm>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <string>
#include <boost/graph/subgraph.hpp>
#include <QMap>

using namespace std;
using namespace boost;

enum graph_IDproperty_t
{
   graph_IDproperty
};
namespace boost
{
  BOOST_INSTALL_PROPERTY(graph,IDproperty);
}
struct GraphProperties {
 std::string strName;
std::string id;
};

typedef boost::subgraph<boost::adjacency_list< boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_index_t, int , property<boost::vertex_color_t,   boost::default_color_type > > ,

boost::property<boost::edge_index_t,int, property<boost::edge_color_t , default_color_type> > ,

boost::property<graph_IDproperty_t,GraphProperties > > >
Graph;

Graph gMainGraph;

typedef QMap<Graph*,GraphProperties*> mapGraphToProperty;
mapGraphToProperty getMap(Graph& graph);
void graphMapRecur(mapGraphToProperty& map, Graph& graph);

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);

Graph& subG = gMainGraph.create_subgraph();
Graph& subG1 = gMainGraph.create_subgraph();

boost::ref_property_map<Graph*, GraphProperties>
        graph_propt1(boost::get_property(subG1,graph_IDproperty));

graph_propt1[&subG1].id = "SubG1";
cout<<graph_propt1[&subG1].id<<endl;

boost::ref_property_map<Graph*, GraphProperties>
        graph_propt(boost::get_property(subG,graph_IDproperty));

graph_propt[&subG].id = "SubG";
cout<<graph_propt[&subG].id<<endl;

boost::ref_property_map<Graph*, GraphProperties>
        graph_proptMain(boost::get_property(gMainGraph,graph_IDproperty));

graph_proptMain[&gMainGraph].id = "gMain";
cout<<graph_proptMain[&gMainGraph].id<<endl;

mapGraphToProperty map = getMap(gMainGraph);

boost::ref_property_map<Graph*, GraphProperties>
        graph_proptMain1(*(map.value(&gMainGraph)));

boost::ref_property_map<Graph*, GraphProperties>
        graph_proptsubG(*(map.value(&subG)));

boost::ref_property_map<Graph*, GraphProperties>
        graph_proptsubG1(*(map.value(&subG1)));

cout<<"Main G Value : "<<graph_proptMain1[&gMainGraph].id<<endl;
cout<<"Sub G Value : "<<graph_proptsubG[&subG].id<<endl;
cout<<"Sub G1 Value : "<<graph_proptsubG1[&subG1].id<<endl;


cout<<"Map Value Main: "<<(map.value(&gMainGraph))<<endl;
cout<<"Map Value SubG: "<<(map.value(&subG))<<endl;
cout<<"Map Value SubG1b: "<<(map.value(&subG1))<<endl;
return a.exec();
}
mapGraphToProperty getMap(Graph &graph)
{
mapGraphToProperty map;
graphMapRecur(map,graph);
return map;
}

void graphMapRecur(mapGraphToProperty &map, Graph &graph)
{
Graph::children_iterator itrSubgraph, itrSubgraph_end;

for (boost::tie(itrSubgraph, itrSubgraph_end) = (graph).children(); itrSubgraph != itrSubgraph_end; ++itrSubgraph)
{
    graphMapRecur(map,(*itrSubgraph));
}

GraphProperties* gp = &(get_property(graph,graph_IDproperty));

map.insert(&graph,gp);
cout<<"Recurrr"<<endl;

}

Upvotes: 0

Related Questions