2011-04-19 66 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); 
相关问题