2011-04-19 52 views
4

在文檔中:http://www.boost.org/doc/libs/1_46_1/libs/graph/doc/random.html#randomize_property如何在boost圖庫中使用捆綁屬性圖的`randomize_property`?

只有一個函數原型,我找不到一個工作的例子。 我嘗試了幾件事,但它不能編譯。 這裏有一個簡單的源代碼:

#include <ctime> 
#include <iostream> 
#include <boost/graph/random.hpp> 
#include <boost/graph/adjacency_list.hpp> 
#include <boost/random/linear_congruential.hpp> 
#include <boost/graph/erdos_renyi_generator.hpp> 
#include <boost/graph/graphviz.hpp> 
using namespace std; 
using namespace boost; 

struct EdgeProperty { 
    int cost; 
}; 

typedef adjacency_list< 
     setS, // disallow parallel edge 
     vecS, 
     undirectedS, 
     no_property, 
     EdgeProperty 
> Graph; 

typedef erdos_renyi_iterator<minstd_rand, Graph> ERGen; 

int main(int argc, const char *argv[]) 
{ 
    minstd_rand gen(time(0)); 
    assert(argc >= 3); 
    int n = atoi(argv[1]); 
    double p = atof(argv[2]); 
    Graph g(ERGen(gen, n, p), ERGen(), n); 

    // randomize_property< [unknown class] >(g, gen); 

    return 0; 
} 

更新:通過@phooji作品提供的代碼。我加了一個默認構造EdgeProperty和我的代碼編譯過:

struct EdgeProperty { 
    EdgeProperty(int x = 0) : cost(x) { } 
    int cost; 
}; 

原來的編譯錯誤過帳爲依據here,我無法理解。希望有人告訴我這是如何工作的。

+0

似乎是提升用戶的重複問題:http://lists.boost.org/boost-users/ 2005/09/14033.php和http://lists.boost.org/boost-users/2009/08/50755.php - 看起來不像是時間解決了。 – Cubbi 2011-04-19 18:34:36

+0

@Cubbi是的,我也找到了。他放棄了使用捆綁的屬性來做這件事。 – 2011-04-21 22:45:27

+0

這與您的問題無關,但我試圖弄清楚如何禁止平行邊緣,並且您的代碼示例給了我答案。多謝! – 2012-06-04 23:02:06

回答

2

這編譯對我來說:

#include <boost/graph/adjacency_list.hpp> 
#include <boost/graph/random.hpp> 
#include <boost/random/linear_congruential.hpp> 

struct myedge { 
    myedge(int x) : testme(x) { 
    } 
    int testme; 
}; 

typedef boost::adjacency_list<boost::setS, // disallow parallel edge 
    boost::vecS, 
    boost::undirectedS, 
    boost::no_property, 
    myedge 
    > mygraph; 

int main(int argc, char**argv) { 
    mygraph g; 

    // auto pmap = boost::get(&myedge::testme, g); 
    boost::minstd_rand gen(0); 
    boost::randomize_property<boost::edge_bundle_t>(g, gen); 
    return EXIT_SUCCESS; // :) 
} 

希望幫助 - 我沒有時間來實際測試,所以道歉,如果這不是你所追求的。

+0

謝謝。您的代碼編譯。這太奇怪了,你的代碼和我的代碼之間的唯一區別是你的捆綁邊屬性類myedge有一個構造函數。我添加了構造函數和代碼編譯。無法弄清楚原因。希望得到解釋:) – 2011-04-21 22:53:01

+1

@伊萬Z.Xiao:請注意,這是一個單參數構造函數,沒有標記爲「explicit」,意思是下面的編譯:'myedge m = 5;'或者更重要的是'm = gen();'編譯。 – Cubbi 2011-04-22 12:52:41

+0

@Cubbi Arrr ...感謝您指出這一點。如果我沒有錯誤地解釋它,編譯器必須通過調用'myedge m = 5;'的默認構造函數來進行隱式轉換。 – 2011-04-22 17:42:08

0

至少有一個問題我可以看到,這是無效的邊緣屬性定義。要定義圖形屬性,應使用property<>類型。有幾種預定義的屬性種類,如索引,重量,顏色等。要定義邊緣成本,請使用edge_weight_t屬性種類。因此,圖形類型定義應該如下:

typedef adjacency_list< 
     setS, // disallow parallel edge 
     vecS, 
     undirectedS, 
     no_property, 
     property<edge_weight_t, int> 
> Graph; 

要訪問屬性類型使用property_map<>property_map<Graph, edge_weight_t>::type

編輯我就捆綁性質的錯誤,仍然很難爲randomize_property<Property>模板參數,這應該是物業那種提供正確的類型。如果定義中的圖形在我的例子中,使用將randomize_property<edge_weight_t>(g, gen);

+0

他的財產是無效的,它的捆綁,如http://www.boost.org/doc/libs/1_46_1/libs/graph/doc/bundles.html – Cubbi 2011-04-19 20:14:07

+0

@Cubbi你是對的,這是我關於捆綁的錯誤。然而,由於'Property'模板參數需要像'edge_weight_t'或'vertex_index_t'這樣的屬性類型,這很難從bundle中派生出來,所以bundle作爲屬性映射使'randomize_property <>'變得複雜。 – Eugene 2011-04-20 14:58:53

+0

捆綁的屬性更直觀,所以我使用它。在他們的文件中他們表示他們將在未來貶低內部財產。 – 2011-04-21 22:53:54

0

您可以使用以下解決方法,直到它被提升正確整理出來:

boost::detail::randomize_property<int EdgeProperty::*> 
     (g, gen, &EdgeProperty::cost, boost::edge_bundle_t);