2017-01-10 2 views
1

그래프에 외부 속성지도를 첨부 : 지금은 같은 일을하고 "외부 속성"을 사용하는 방법을 보여하려는 경우그것은 바로 내부 속성으로 그래프에 에지 가중치를 추가 할 정방향

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] << " "; 
    } 
} 

는, 나는이 함께했다하지만, 모든 원래의 그래프에 정말 어떤 링크가 없습니다 :

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] << " "; 
    } 
} 

get(boost::edge_weight_t(), g); 같은 것을 만들 수있는 방법이 있나요이지도를 반환 (내부 예에서)? 이 외부 예제에서 g.setPropertyMap(boost::edge_weight_t, edgeWeightMap)을 말하고 싶습니까?

답변

1

나는 이득이 무엇인지 잘 모르겠지만, 아마도이 영감을하는 데 도움이 : 나는 그런 식으로 boost::get과 모호성을 피할 수 없었습니다

#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(); 
} 

당신이 선택하는 ADL을 신뢰할 수 네임 스페이스 한정없이 "최고의"오버로드.

Live On Coliur

+0

그래서 이것은 내가 요구보다는 실제가'처럼 행동 adjacency_list' 만드는 것처럼 행동 자신의 그래프와 같은 용기를 만드는 종류이다. 그래서 당신이 실제로'adjacency_list'에'boost :: edge_weight_t'을 만드는 방법이 외부 속성 맵이라고 믿는 지 확인하고있는 것 같습니다. 그렇다면 어떤 BGL 알고리즘이라도 직접적으로 필요한 모든 필드에 대해'std :: map'과 같은 것을 받아 들여야하고, 내가 원하는 것을 할 필요가 없다는 개념입니다. –

+1

그게 어떻게 효과가 있다고 생각하니? 그래프 속성을 사용하여 상태를 저장할 수는 있지만 런타임 상태를 특정 형식으로 인코딩 할 수는 없습니다. 그것은 물리 법칙입니다. – sehe

+0

태그 디스패치 종류가 발생했다는 것을 상상해보십시오. 'edge_weight_t'에 대한 에지 가중치를 반환하는 부스트 그래프 클래스의 함수는 내 에지 가중치 컨테이너가있는 펑터 만 필요로하고 반환 할 수 있습니다. 내가 여기서 벗어나는거야? –

관련 문제