2015-05-15 9 views
12

अद्यतन: समस्या बीच कोड में हो सकती है। अगर मैं brandes_betweenness_centrality पर कॉल पर टिप्पणी करता हूं तो कोड संकलित होगा। समस्या पहले संकेत के रूप में स्थापित सूचकांक नहीं हो सकता है। यदि आप ब्रांड्स_बेटविनेनेस_सेंट्रलिटी के लिए वैकल्पिक कॉल के साथ आ सकते हैं तो मैं बाउंटी पुरस्कार दूंगा जो इंडेक्स को बाहरी रखने की अनुमति देगा।सूची में vertex_index जोड़ना मध्यस्थता

मैं सूची के साथ काम करने के लिए अपने कुछ पुराने वीसीएस कोड को बदलने की कोशिश कर रहा हूं, विशेष रूप से brandes_betweenness_centrality एल्गोरिदम।

मैं वर्टेक्स और एज गुणों को बहुत हल्का वजन रखने और मुख्य रूप से बाहरी गुणों के साथ काम करने की कोशिश कर रहा हूं। इसका कारण यह है कि मुझे नहीं पता कि मैं इस बिंदु पर उनके साथ क्या जोड़ना चाहता हूं।

मुझे जो त्रुटियां मिल रही हैं, वे adjacency_list.hpp के अंदर से आ रही हैं, इसलिए मुझे लगता है कि समस्या हमारे पुराने दोस्त vertex_index_t सूची सूची के साथ है।

निम्न कोड संकलित त्रुटि को पुन: उत्पन्न करने के तरीके से पता चलता है। इस कामकाजी उदाहरण में, आप ग्राफ परिभाषा में vertex_index को भरने के लिए परिभाषा को बदल सकते हैं और पूरी तरह से काम करने वाले कोड (जो सही ढंग से बीच में चलती है) के लिए बीच विधि में सेट अप को बदल सकते हैं।

पूर्ण उदाहरण:

#include <iostream> 
#include <algorithm> 
#include <vector> 

#include <boost/graph/adjacency_list.hpp> 
#include <boost/graph/graph_traits.hpp> 
#include <boost/graph/betweenness_centrality.hpp> 

#include <boost/timer.hpp> 

using namespace std; 

enum edge_t {A,B}; 

struct VertexProperties{ 
    std::string id; 
}; 

struct EdgeProperties{ 
    edge_t type; 
}; 

//vertex_index in as internal property, switch to this graph and change below vertex map for working code 
//typedef boost::adjacency_list < boost::listS, boost::listS, boost::undirectedS, 
//  boost::property<boost::vertex_index_t,size_t,VertexProperties>, EdgeProperties > DynamicNet; 

// No internal vertex_index 
typedef boost::adjacency_list < boost::listS, boost::listS, boost::undirectedS, 
     VertexProperties, EdgeProperties > DynamicNet; 

typedef boost::graph_traits<DynamicNet>::vertex_descriptor DynamicNetVertex; 
typedef boost::graph_traits<DynamicNet>::vertex_iterator DynamicNetVI; 

typedef boost::graph_traits<DynamicNet>::edge_descriptor DynamicNetEdge; 
typedef boost::graph_traits<DynamicNet>::edge_iterator  DynamicNetEI; 


void calcBetweenness(DynamicNet &g, 
        std::vector<double> &v_centrality_vec, 
        std::vector<double> &e_centrality_vec); 


int main(int argc, char* argv[]){ 
    cout << "betweenness" << endl; 

    DynamicNet net; 

    //Fig. 1, wheen graph (a - h), modified with added z added to a 
    //http://www.boost.org/doc/libs/1_58_0/libs/graph/doc/betweenness_centrality.html 
    DynamicNetVertex a = boost::add_vertex(net); net[a].id = "a"; 
    DynamicNetVertex b = boost::add_vertex(net); net[b].id = "b"; 
    DynamicNetVertex c = boost::add_vertex(net); net[c].id = "c"; 
    DynamicNetVertex d = boost::add_vertex(net); net[d].id = "d"; 
    DynamicNetVertex e = boost::add_vertex(net); net[e].id = "e"; 
    DynamicNetVertex f = boost::add_vertex(net); net[f].id = "f"; 
    DynamicNetVertex g = boost::add_vertex(net); net[g].id = "g"; 

    //core 
    DynamicNetVertex h = boost::add_vertex(net); net[h].id = "h"; 

    boost::add_edge(a,h,net); 
    boost::add_edge(b,h,net); 
    boost::add_edge(c,h,net); 
    boost::add_edge(d,h,net); 
    boost::add_edge(e,h,net); 
    boost::add_edge(f,h,net); 
    boost::add_edge(g,h,net); 

    //add an edge to make the calculation more interesting 
    DynamicNetVertex z = boost::add_vertex(net); net[z].id = "z"; 
    boost::add_edge(a,z,net); 



    vector<double> v_centrality_vec(boost::num_vertices(net),0.0); 
    vector<double> e_centrality_vec(boost::num_edges(net),0.0); 

    boost::timer t; 
    t.restart(); 
    calcBetweenness(net,v_centrality_vec,e_centrality_vec); 
    double s = t.elapsed(); 
    cout << s << " s" << endl; 
    cout << endl; 

    cout << "Vertex betweenness" << endl; 
    DynamicNetVI vi,ve;  
    size_t i = 0; 
    for(boost::tie(vi,ve) = boost::vertices(net); vi != ve; ++vi){ 
     cout << net[*vi].id << "\t" << v_centrality_vec.at(i) << endl; 
     ++i; 
    } 

    cout << endl; 

    cout << "Edge betweenness" << endl; 
    DynamicNetEI ei,ee; 
    i = 0; 
    for(boost::tie(ei,ee) = boost::edges(net); ei != ee; ++ei){ 
     DynamicNetEdge e = *ei; 
     cout << net[boost::source(e,net)].id << "\t" 
      << net[boost::target(e,net)].id << "\t" << e_centrality_vec.at(i) << endl; 
     ++i; 
    } 

    cin.get(); 
} 

void calcBetweenness(DynamicNet &g, 
        std::vector<double> &v_centrality_vec, 
        std::vector<double> &e_centrality_vec) 
{ 
    std::cout << "betweenness called" << std::endl; 

    //vertex 
    //Uncomment and change to internal vertex graph above for working code. 

/* 
    typedef std::map<DynamicNetVertex,size_t> StdVertexIndexMap; 
    StdVertexIndexMap viMap; 
    typedef boost::property_map<DynamicNet, boost::vertex_index_t>::type VertexIndexMap; 
    VertexIndexMap v_index = boost::get(boost::vertex_index,g); 
    DynamicNetVI vi,ve; 
    size_t i = 0; 
    for(boost::tie(vi,ve) = boost::vertices(g); vi != ve; ++vi){ 
     boost::put(v_index,*vi,i); 
     ++i; 
    } 
    boost::iterator_property_map< std::vector<double>::iterator, VertexIndexMap > 
     v_centrality_map(v_centrality_vec.begin(), v_index); 
*/ 

    //this code which exactly mimics the working approached used by edge results in an error 
    typedef std::map<DynamicNetVertex,size_t> StdVertexIndexMap; 
    StdVertexIndexMap viMap; 
    typedef boost::associative_property_map<StdVertexIndexMap> VertexIndexMap; 
    VertexIndexMap v_index(viMap); 
    DynamicNetVI vi,ve; 
    size_t i = 0; 
    for(boost::tie(vi,ve) = boost::vertices(g); vi != ve; ++vi){ 
     boost::put(v_index,*vi,i); 
     ++i; 
    } 
    boost::iterator_property_map< std::vector<double>::iterator, VertexIndexMap > 
     v_centrality_map(v_centrality_vec.begin(), v_index); 



    //edge, this appraoch works fine for edge 
    typedef std::map<DynamicNetEdge,size_t> StdEdgeIndexMap; 
    StdEdgeIndexMap eiMap; 
    typedef boost::associative_property_map<StdEdgeIndexMap> EdgeIndexMap; 
    EdgeIndexMap e_index(eiMap); 
    DynamicNetEI ei,ee; 
    i = 0; 
    for(boost::tie(ei,ee) = boost::edges(g); ei != ee; ++ei){ 
     boost::put(e_index,*ei,i); 
     ++i; 
    } 
    boost::iterator_property_map< std::vector<double>::iterator, EdgeIndexMap > 
     e_centrality_map(e_centrality_vec.begin(), e_index); 

    brandes_betweenness_centrality(g,v_centrality_map, e_centrality_map); 
} 

त्रुटि:

Error 1 error C2182: 'reference' : illegal use of type 'void' ... \boost_1_58_0\boost\graph\detail\adjacency_list.hpp 2543 
Error 2 error C2182: 'const_reference' : illegal use of type 'void' ... \boost_1_58_0\boost\graph\detail\adjacency_list.hpp 2544 

MSVS उत्पादन:

1>------ Build started: Project: testBetweenness, Configuration: Release 

Win32 ------ 
1>Compiling... 
1>testBetweenness.cpp 
1>...\boost_1_58_0\boost/graph/detail/adjacency_list.hpp(2543) : error C2182: 'reference' : illegal use of type 'void' 
1>  ...\boost_1_58_0\boost/graph/detail/adjacency_list.hpp(2619) : see reference to class template instantiation 'boost::adj_list_any_vertex_pa::bind_<Tag,Graph,Property>' being compiled 
1>  with 
1>  [ 
1>   Tag=boost::vertex_index_t, 
1>   Graph=boost::adjacency_list<boost::listS,boost::listS,boost::undirectedS,pintk::VertexProperties,pintk::EdgeProperties>, 
1>   Property=pintk::VertexProperties 
1>  ] 
1>  ...\boost_1_58_0\boost/graph/detail/adjacency_list.hpp(2752) : see reference to class template instantiation 'boost::detail::adj_list_choose_vertex_pa<Tag,Graph,Property>' being compiled 
1>  with 
1>  [ 
1>   Tag=boost::vertex_index_t, 
1>   Graph=boost::adjacency_list<boost::listS,boost::listS,boost::undirectedS,pintk::VertexProperties,pintk::EdgeProperties>, 
1>   Property=pintk::VertexProperties 
1>  ] 
1>  ...\boost_1_58_0\boost/graph/properties.hpp(208) : see reference to class template instantiation 'boost::adj_list_vertex_property_selector::bind_<Graph,Property,Tag>' being compiled 
1>  with 
1>  [ 
1>   Graph=boost::adjacency_list<boost::listS,boost::listS,boost::undirectedS,pintk::VertexProperties,pintk::EdgeProperties>, 
1>   Property=pintk::VertexProperties, 
1>   Tag=boost::vertex_index_t 
1>  ] 
1>  ...\boost_1_58_0\boost/graph/properties.hpp(217) : see reference to class template instantiation 'boost::detail::vertex_property_map<Graph,PropertyTag>' being compiled 
1>  with 
1>  [ 
1>   Graph=boost::adjacency_list<boost::listS,boost::listS,boost::undirectedS,pintk::VertexProperties,pintk::EdgeProperties>, 
1>   PropertyTag=boost::vertex_index_t 
1>  ] 
1>  ...\boost_1_58_0\boost/graph/betweenness_centrality.hpp(562) : see reference to class template instantiation 'boost::property_map<Graph,Property,Enable>' being compiled 
1>  with 
1>  [ 
1>   Graph=boost::adjacency_list<boost::listS,boost::listS,boost::undirectedS,pintk::VertexProperties,pintk::EdgeProperties>, 
1>   Property=boost::vertex_index_t, 
1>   Enable=void 
1>  ] 
1>  ...\Visual Studio 2008\Projects\yapnl\yapnl\ProteinNetworks.h(82) : see reference to function template instantiation 'void boost::brandes_betweenness_centrality<pintk::DynamicNet,boost::iterator_property_map<RandomAccessIterator,IndexMap>,boost::iterator_property_map<RandomAccessIterator,EdgeIndexMap>>(const Graph &,CentralityMap,EdgeCentralityMap,boost::graph::detail::no_parameter)' being compiled 
1>  with 
1>  [ 
1>   RandomAccessIterator=std::_Vector_iterator<double,std::allocator<double>>, 
1>   IndexMap=VertexIndexMap, 
1>   Graph=pintk::DynamicNet, 
1>   CentralityMap=boost::iterator_property_map<std::_Vector_iterator<double,std::allocator<double>>,VertexIndexMap>, 
1>   EdgeCentralityMap=boost::iterator_property_map<std::_Vector_iterator<double,std::allocator<double>>,EdgeIndexMap> 
1>  ] 
1>...\boost_1_58_0\boost/graph/detail/adjacency_list.hpp(2544) : error C2182: 'const_reference' : illegal use of type 'void' 
1>Build log was saved at "file://...\Visual Studio 2008\Projects\yapnl\testBetweenness\Release\BuildLog.htm" 
1>testBetweenness - 2 error(s), 0 warning(s) 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

यह answer, मुझे ग्राफ परिभाषा जिसकी अनुमति में boost::vertex_index_t संपत्ति जोड़ने में मदद की boost::property<boost::vertex_index_t,size_t,VertexProperties> का उपयोग कर चलाने के लिए कोड।

मुझे ग्राफ से पूरी तरह बाहरी vertex_index_t रखने और एल्गोरिदम चलाने से पहले इसे जोड़ने का तरीका चाहिए।

किनारे_इंडेक्स को स्थापित करने के लिए वस्तुतः समान कोड यह अनुमति देता है। क्या मुझे कुछ याद आ रहा है या यह एक एमएसवीएस चीज है या यह एक बग हो सकता है?

मेरा विशिष्ट प्रश्न है: मुझे ग्राफ परिभाषा से vertex_index रखने के लिए बदलने की आवश्यकता है, इसे फ्लाई पर जोड़ें, और अभी भी एल्गोरिदम चलाएं?

उत्तर

5

जैसा कि मैंने अद्यतन में कहा था, ऐसा लगता है कि समस्या मध्यस्थता में थी। source में प्रेषणों के माध्यम से खुदाई, और docs में पैरामीटर को देखते हुए मैंने पाया कि vertex_index_map एल्गोरिदम को पास नहीं किया गया है, यह get(vertex_index, g) पर डिफ़ॉल्ट है जैसा कि हम जानते हैं कि इस विशेष ग्राफ में मौजूद नहीं है।

कुछ समय बाद मेरे सिर को bgl_named_params नाम से लपेटने के बाद, मुझे लगा कि मैं नामित पैरामीटर के रूप में v_index चर पारित कर सकता हूं।

निम्नलिखित कोड चाल किया:

brandes_betweenness_centrality(g, 
      boost::centrality_map(v_centrality_map).edge_centrality_map(e_centrality_map).vertex_index_map(v_index)); 

मुझे लगता है कि त्रुटि get(vertex_index,g) कॉल करने के लिए कोशिश कर रहा है और listS ग्राफ पर असफल रहने brandes_betweenness_centrality में था।

+0

मुझे लगता है कि यह आपके खुद के प्रश्न का उत्तर है, है ना? क्या आपको अभी भी कुछ मदद की ज़रूरत है? – sehe

+1

@sehe, नहीं, यह तय है। हालांकि धन्यवाद। अगर मैं केवल बाउंटी लॉल पोस्ट करने से पहले थोड़ा कठिन काम करता था। मैंने इसे स्वीकार कर लिया ताकि अन्य लोग बक्षीस के लिए प्रयास करने में समय बर्बाद न करें। – pbible

संबंधित मुद्दे