2015-05-15 15 views
12

Güncelleştirme: Sorun, alan kodu içinde olabilir. Eğer aramayı brandes_betweenness_centrality numaralı telefona bildirirseniz, kod derlenecektir. Sorun daha önce düşünüldüğü gibi kurulan dizin olmayabilir. Dizin harici tutmaya izin verecek brandes_betweenness_centrality alternatif bir çağrı ile gelebilir eğer ödül ödünç vereceğim.ListS grafiğe sineklik için bir vertex_index ekleme

Eski vecS kodumun bazılarını listSistemi, özellikle de brandes_betweenness_centrality algoritmasını kullanarak dönüştürmeye çalışıyorum.

Vertex ve Edge özelliklerini çok hafif tutmaya çalışıyorum ve çoğunlukla dış özelliklerle çalışıyorum. Bunun sebebi, bu noktada onlarla ne yapmak istediğimin ne olduğunu bilmem.

Aldığım hatalar adjacency_list.hpp içinden geliyor, bu yüzden sorunun eski arkadaşımız vertex_index_t listS ile olduğunu düşünüyorum.

Aşağıdaki kod, derleme hatasının nasıl yeniden üretileceğini gösterir. Bu çalışan örnekte, vertex_index'i grafik tanımına sığdırmak için tanımlamayı değiştirebilir ve tümüyle çalışan kod için (burada düzgün bir şekilde doğru arasında çalışır) kurulum yöntemini değiştirebilirsin.

tam bir örnek:

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

hatası:

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 çıkışı:

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 ========== 

Bu answer, beni izin grafik tanımı boost::vertex_index_t özelliği ekleyin yardımcı boost::property<boost::vertex_index_t,size_t,VertexProperties> kullanarak çalıştırmak için kod.

vertex_index_t'u grafikten tamamen dışarıda tutmak ve algoritmayı çalıştırmadan hemen önce eklemek istiyorum.

Edge_index'i kurmak için hemen hemen aynı kod buna izin verir. Bir şeyi mi özledim yoksa bu bir MSVS meselesi mi yoksa bir hata mı olabilir?

Özel sorum: vertex_index'i grafik tanımının dışında tutmak, onu anında eklemek ve hala algoritmayı çalıştırmak için neyi değiştirmem gerekiyor?

cevap

5

Güncellemede belirttiğim gibi, sorunun merkezlilik arasında olduğu anlaşılıyor. source'daki gönderiler arasında arama yaparak ve docs'daki parametrelere bakarak, vertex_index_map algoritmaya geçirilmediyse, varsayılan olarak get(vertex_index, g) bu özel grafikte mevcut olmadığını bildiğimizi fark ettim. Kafamı bgl_named_params adlı bir yere kaydırdıktan sonra, v_index değişkenini bir adlandırılmış parametre olarak iletebileceğimi anladım. Ben hata get(vertex_index,g) aramaya çalışıyorum ve listS grafikte başarısız brandes_betweenness_centrality yılında olduğunu düşünüyorum

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

:

Aşağıdaki kod

hile yaptı.

+0

Bence bu kendi sorunuzu cevaplıyor, değil mi? Hala biraz yardıma ihtiyacın var mı? – sehe

+1

@sehe, hayır, bu düzeltildi. Yine de teşekkürler. Eğer sadece lütuf lol göndermeden önce biraz daha zor çalıştı. Bunu kabul ettim, diğerleri de ödül için çaba harcayacak zaman harcamayacaktı. – pbible

İlgili konular