나는 boost :: graph를 사용하여 정보를 저장하는 방법을 알아 내려고하고있다. 그러나 각 꼭지점에 묶어두기를 원하는 정보가 있습니다. 라이브러리에 대한 문서를 보니 (a) 나쁘게 작성된 문서 또는 (b) 필자가 생각한 것처럼 분명히 C++이 좋지 않다는 것을 알 수 있습니다. 둘을 골라.부스트 :: 그래프에서 버텍스 속성 수정하기
간단한 예제 사용을 찾고 있습니다.
나는 boost :: graph를 사용하여 정보를 저장하는 방법을 알아 내려고하고있다. 그러나 각 꼭지점에 묶어두기를 원하는 정보가 있습니다. 라이브러리에 대한 문서를 보니 (a) 나쁘게 작성된 문서 또는 (b) 필자가 생각한 것처럼 분명히 C++이 좋지 않다는 것을 알 수 있습니다. 둘을 골라.부스트 :: 그래프에서 버텍스 속성 수정하기
간단한 예제 사용을 찾고 있습니다.
나는 Boost.Graph가 매우 좋은 문서를 가지고 있다고 생각하지만,이 문제에 대한 초보자를위한 것은 아니다. 그래서 여기에 내가 충분히 간단하다는 희망이 들어간다.
//includes
// Create a name for your information
struct VertexInformation
{
typedef boost::vertex_property_type type;
};
// Graph type, customize it to your needs
// This is when you decide what information will be attached to vertices and/or edges
// of MyGraph objects
typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
boost::property<VertexInformation, double> > MyGraph;
int main()
{
MyGraph graph;
// Create accessor for information
typedef boost::property_map<MyGraph, VertexInformation>::type InformationAccessor;
InformationAccessor information(get(VertexInformation(), graph));
// Create a vertex (for example purpose)
typedef boost::graph_traits<MyGraph>::vertex_descriptor MyVertex;
MyVertex vertex = add_vertex(graph);
// Now you can access your information
put(information, vertex, 1.);
// returns 1 !
get(information, vertex);
return 0;
}
그래서 버텍스 프로퍼티 템플릿 인수를'boost :: property
다음은 일부 속성을 정점, 가장자리 및 그래프에 첨부하는 데 사용되는 코드입니다. 버텍스 이름과 그래프 이름은 vertex_name_t
과 graph_name_t
이 이미 정의 된 미리 정의 된 속성입니다 (전체 목록은 boost/properties.hpp를 참조하십시오). 그러나 vertex_location_t
, edge_length_t
및 graph_notes_t
은 내 속성이므로 정의가 필요합니다. 다양한 예제와 문서에서이 코드를 모아 봤는데 정확히 무엇이 BOOST_INSTALL_PROPERTY
인지는 모르겠지만 코드는 제대로 작동하는 것 같습니다.
// Define custom properties
enum vertex_location_t { vertex_location };
enum edge_length_t { edge_length };
enum graph_notes_t { graph_notes };
namespace boost
{
BOOST_INSTALL_PROPERTY(vertex, location);
BOOST_INSTALL_PROPERTY(edge, length );
BOOST_INSTALL_PROPERTY(graph, notes );
}
// Define vertex properties: vertex name and location
typedef property<vertex_name_t, string,
property<vertex_location_t, Point3> >
VertexProperties;
// Define edge properties: length
typedef property<edge_length_t, double> EdgeProperties;
// Define graph properties: graph name and notes
typedef property<graph_name_t, string,
property<graph_notes_t, string> >
GraphProperties;
// Define a graph type
typedef adjacency_list
<
vecS, // edge container type
vecS, // vertex container type
undirectedS,
VertexProperties,
EdgeProperties,
GraphProperties
> Graph;
매우 유용한 예를 발견했습니다. 창에서 \ Program Files \ boost \ boost_1_38 \ libs \ graph \ example 디렉토리에 있습니다.
kevin_bacon2.cpp는 꼭지점 속성을 사용하여 액터 이름을 저장합니다.
정점 및 가장자리 속성은 일반 구조체 또는 클래스에 저장할 수 있습니다.
boost :: graph의 중첩 템플릿 속성 접근 방식이 마음에 들지 않아서 기본적으로 모든 구조체/클래스를 정점/가장자리 속성으로 지정할 수있는 모든 것을 작은 래퍼로 작성했습니다. 구조체 멤버에 액세스하는 속성에 액세스 할 수 있습니다.
유연성을 유지하기 위해 이러한 구조체는 템플릿 매개 변수로 정의됩니다. 여기
코드 :
/* definition of basic boost::graph properties */
enum vertex_properties_t { vertex_properties };
enum edge_properties_t { edge_properties };
namespace boost {
BOOST_INSTALL_PROPERTY(vertex, properties);
BOOST_INSTALL_PROPERTY(edge, properties);
}
/* the graph base class template */
template < typename VERTEXPROPERTIES, typename EDGEPROPERTIES >
class Graph
{
public:
/* an adjacency_list like we need it */
typedef adjacency_list<
setS, // disallow parallel edges
listS, // vertex container
bidirectionalS, // directed graph
property<vertex_properties_t, VERTEXPROPERTIES>,
property<edge_properties_t, EDGEPROPERTIES>
> GraphContainer;
/* a bunch of graph-specific typedefs */
typedef typename graph_traits<GraphContainer>::vertex_descriptor Vertex;
typedef typename graph_traits<GraphContainer>::edge_descriptor Edge;
typedef std::pair<Edge, Edge> EdgePair;
typedef typename graph_traits<GraphContainer>::vertex_iterator vertex_iter;
typedef typename graph_traits<GraphContainer>::edge_iterator edge_iter;
typedef typename graph_traits<GraphContainer>::adjacency_iterator adjacency_iter;
typedef typename graph_traits<GraphContainer>::out_edge_iterator out_edge_iter;
typedef typename graph_traits<GraphContainer>::degree_size_type degree_t;
typedef std::pair<adjacency_iter, adjacency_iter> adjacency_vertex_range_t;
typedef std::pair<out_edge_iter, out_edge_iter> out_edge_range_t;
typedef std::pair<vertex_iter, vertex_iter> vertex_range_t;
typedef std::pair<edge_iter, edge_iter> edge_range_t;
/* constructors etc. */
Graph()
{}
Graph(const Graph& g) :
graph(g.graph)
{}
virtual ~Graph()
{}
/* structure modification methods */
void Clear()
{
graph.clear();
}
Vertex AddVertex(const VERTEXPROPERTIES& prop)
{
Vertex v = add_vertex(graph);
properties(v) = prop;
return v;
}
void RemoveVertex(const Vertex& v)
{
clear_vertex(v, graph);
remove_vertex(v, graph);
}
EdgePair AddEdge(const Vertex& v1, const Vertex& v2, const EDGEPROPERTIES& prop_12, const EDGEPROPERTIES& prop_21)
{
/* TODO: maybe one wants to check if this edge could be inserted */
Edge addedEdge1 = add_edge(v1, v2, graph).first;
Edge addedEdge2 = add_edge(v2, v1, graph).first;
properties(addedEdge1) = prop_12;
properties(addedEdge2) = prop_21;
return EdgePair(addedEdge1, addedEdge2);
}
/* property access */
VERTEXPROPERTIES& properties(const Vertex& v)
{
typename property_map<GraphContainer, vertex_properties_t>::type param = get(vertex_properties, graph);
return param[v];
}
const VERTEXPROPERTIES& properties(const Vertex& v) const
{
typename property_map<GraphContainer, vertex_properties_t>::const_type param = get(vertex_properties, graph);
return param[v];
}
EDGEPROPERTIES& properties(const Edge& v)
{
typename property_map<GraphContainer, edge_properties_t>::type param = get(edge_properties, graph);
return param[v];
}
const EDGEPROPERTIES& properties(const Edge& v) const
{
typename property_map<GraphContainer, edge_properties_t>::const_type param = get(edge_properties, graph);
return param[v];
}
/* selectors and properties */
const GraphContainer& getGraph() const
{
return graph;
}
vertex_range_t getVertices() const
{
return vertices(graph);
}
adjacency_vertex_range_t getAdjacentVertices(const Vertex& v) const
{
return adjacent_vertices(v, graph);
}
int getVertexCount() const
{
return num_vertices(graph);
}
int getVertexDegree(const Vertex& v) const
{
return out_degree(v, graph);
}
/* operators */
Graph& operator=(const Graph &rhs)
{
graph = rhs.graph;
return *this;
}
protected:
GraphContainer graph;
};
이 같은 속성에 액세스 할 수 있습니다이 사용 : 당신이 당신의 그래프의 구조에 대한 다른 요구가있을 수 있습니다
물론struct VertexProperties {
int i;
};
struct EdgeProperties {
};
typedef Graph<VertexProperties, EdgeProperties> MyGraph;
MyGraph g;
VertexProperties vp;
vp.i = 42;
MyGraph::Vertex v = g.AddVertex(vp);
g.properties(v).i = 23;
하지만, 코드의 수정은 위해야 꽤 쉬워.
번들 속성 사용은 어떻게됩니까?
using namespace boost;
struct vertex_info {
std::string whatever;
int othervalue;
std::vector<int> some_values;
};
typedef adjacency_list<vecS, vecS, undirectedS, vertex_info> graph_t;
graph_t g(n);
g[0].whatever = "Vertex 0";
[...]
등등.
BGL을 많이 사용하며 번들 속성을 사용하는 작업은 매우 간단합니다 (see the docs).
자주 사용하는 다른 유형의 정점 속성은 외부 속성입니다. 적절한 크기의 std::vectors
을 선언하고이를 대부분의 알고리즘과 대부분의 속성으로 속성으로 사용할 수 있습니다.
이 대답이 받아 들여질 필요가 있습니다. 특히 경쟁자가 답을 얻었으므로 현재 투표에서이 기능에 대한 재 구현이 이미 라이브러리에 있습니다! 예제 코드는 간단한 부스트 그래프 라이브러리 사용법을 설정하는 방법에 대해 웹에서 찾은 가장 간단한 예제이기도합니다. 감사. – Dennis
+1; 미안 해요, 파티에 늦었습니다. 단지 사이드 노트에 "std :: vectors 선언 할 수 있습니다."- vecS를 사용하고 vertex (가장자리가 아님) IIRC 만 사용하는 경우에만 해당됩니다. – phooji
TMP의 마법을 통해 여러 속성을 사용할 수도 있습니다. 여기 -> http://www.informit.com/articles/article.aspx?p=25756&seqNum=7 –
'17 년에 부스트 문서를보고 나서 두 가지 계시가 있습니다. –