博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
graph-tool文档(一)- 快速开始使用Graph-tool - 2.属性映射、图的IO和Price网络
阅读量:6471 次
发布时间:2019-06-23

本文共 6950 字,大约阅读时间需要 23 分钟。

目录:

  • 属性映射
    -- 内部属性映射
  • 图的I/O
  • 构建一个 Price网络(例)

名词解释:

Property maps:属性映射
PropertyMap:一个类
scalar value types:标量值类型
pickle module:
scale-free graph:

属性映射

属性映射是一种将额外信息与顶点、边或图本身相关联的方式。

因此有这样三种类型的属性映射:顶点、边和图。
它们都是由同一个类来操作:PropertyMap。
每个创建了的属性映射都有一个与之相关联的类型的值,预定义设置的类型有如下几种:

Type name Alias
bool uint8_t
int16_t short
int32_t int
int64_t long, long long
double float
long double .
string .
vector bool vector uint8_t
vector int16_t vector short
vector int32_t vector int
vector int64_t vector long, vector long long
vector double vector float
vector long double .
vector string .
python::object object

可以对于每一个映射类型通过调用new_vertex_property()new_edge_property()new_graph_property()为一个指定的图创建新的属性映射。

然后可以通过顶点或边的描述符或图本身来访问该值,因此:

from itertools import izipfrom numpy.random import randintg = Graph()g.add_vertex(100)# insert some random linksfor s,t in izip(randint(0, 100, 100), randint(0, 100, 100)):    g.add_edge(g.vertex(s), g.vertex(t))vprop_double = g.new_vertex_property("double")            # Double-precision floating pointvprop_double[g.vertex(10)] = 3.1416vprop_vint = g.new_vertex_property("vector
") # Vector of intsvprop_vint[g.vertex(40)] = [1, 3, 42, 54]eprop_dict = g.new_edge_property("object") # Arbitrary python object.eprop_dict[g.edges().next()] = {"foo": "bar", "gnu": 42} # In this case, a dict.gprop_bool = g.new_graph_property("bool") # Booleangprop_bool[g] = True

标量值类型的属性映射也可以被当做numpy.ndarray来访问,通过get_array()方法,或者a属性。

from numpy.random import random# this assigns random values to the vertex propertiesvprop_double.get_array()[:] = random(g.num_vertices())# or more conveniently (this is equivalent to the above)vprop_double.a = random(g.num_vertices())

内部属性映射

任何创建的属性映射可以作为“内部”到相应的图上。

这意味着它将被复制并和图一起被保存到一个文件。
属性被内在化,通过将它们包括在图的类字典属性中:vertex_properties,edge_properties或graph_properties(或它们的别名,vp,ep或gp)。
当插入到图中时,属性映射必须有一个唯一的名称(相同类型的之间):

>>> eprop = g.new_edge_property("string")>>> g.edge_properties["some name"] = eprop>>> g.list_properties()some name      (edge)    (type: string)

内部图的属性映射表现得略有不同。

它不是返回属性映射对象,值本身是从字典中返回的:

>>> gprop = g.new_graph_property("int")>>> g.graph_properties["foo"] = gprop   # this sets the actual property map>>> g.graph_properties["foo"] = 42      # this sets its value>>> print(g.graph_properties["foo"])42>>> del g.graph_properties["foo"]       # the property map entry is deleted from the dictionary

为了方便起见,内部属性映射也可以通过属性来访问:

>>> vprop = g.new_vertex_property("double")>>> g.vp.foo = vprop                        # equivalent to g.vertex_properties["foo"] = vprop>>> v = g.vertex(0)>>> g.vp.foo[v] = 3.14>>> print(g.vp.foo[v])3.14

图的I/O

图可以通过四种格式保存和加载:graphml、dot、gml和一个定制的二进制格式gt(见gt文件格式)。

警告:

二进制格式gt和graphml是首选的格式,因为它们是迄今为止最完整的。

这些格式都是同样完整的,但gt速度更快,需要的存储空间也更少。

图可以保存或加载到一个文件上,通过saveload方法,以一个文件名或类似文件的对象。

图也可以从光盘上加载,通过load_graph()函数,如下:

g = Graph()#  ... fill the graph ...g.save("my_graph.xml.gz")g2 = load_graph("my_graph.xml.gz")# g and g2 should be copies of each other

图类也可以通过pickle模块来pickled with。

一个例子:构建一个 Price网络

Price网络是第一个已知的“无尺度”图模型,于1976年被de Solla Price发明。

它是被动态定义的,每一步添加一个新的顶点到图中,并连接到一个旧的顶点,概率与它的入度成正比。
下面的程序使用graph-tool实现了这个结构。

注意:

只使用price_network()函数将会快得多,因为它是以c++实现的,而不是像下面的脚本一样使用纯python。

下面的代码仅仅是一个如何使用该库的示例。

#! /usr/bin/env python# We will need some things from several placesfrom __future__ import division, absolute_import, print_functionimport sysif sys.version_info < (3,):    range = xrangeimport osfrom pylab import *  # for plottingfrom numpy.random import *  # for random samplingseed(42)# We need to import the graph_tool module itselffrom graph_tool.all import *# let's construct a Price network (the one that existed before Barabasi). It is# a directed network, with preferential attachment. The algorithm below is# very naive, and a bit slow, but quite simple.# We start with an empty, directed graphg = Graph()# We want also to keep the age information for each vertex and edge. For that# let's create some property mapsv_age = g.new_vertex_property("int")e_age = g.new_edge_property("int")# The final size of the networkN = 100000# We have to start with one vertexv = g.add_vertex()v_age[v] = 0# we will keep a list of the vertices. The number of times a vertex is in this# list will give the probability of it being selected.vlist = [v]# let's now add the new edges and verticesfor i in range(1, N):    # create our new vertex    v = g.add_vertex()    v_age[v] = i    # we need to sample a new vertex to be the target, based on its in-degree +    # 1. For that, we simply randomly sample it from vlist.    i = randint(0, len(vlist))    target = vlist[i]    # add edge    e = g.add_edge(v, target)    e_age[e] = i    # put v and target in the list    vlist.append(target)    vlist.append(v)# now we have a graph!# let's do a random walk on the graph and print the age of the vertices we find,# just for fun.v = g.vertex(randint(0, g.num_vertices()))while True:    print("vertex:", int(v), "in-degree:", v.in_degree(), "out-degree:",          v.out_degree(), "age:", v_age[v])    if v.out_degree() == 0:        print("Nowhere else to go... We found the main hub!")        break    n_list = []    for w in v.out_neighbours():        n_list.append(w)    v = n_list[randint(0, len(n_list))]# let's save our graph for posterity. We want to save the age properties as# well... To do this, they must become "internal" properties:g.vertex_properties["age"] = v_ageg.edge_properties["age"] = e_age# now we can save itg.save("price.xml.gz")# Let's plot its in-degree distributionin_hist = vertex_hist(g, "in")y = in_hist[0]err = sqrt(in_hist[0])err[err >= y] = y[err >= y] - 1e-2figure(figsize=(6,4))errorbar(in_hist[1][:-1], in_hist[0], fmt="o", yerr=err,        label="in")gca().set_yscale("log")gca().set_xscale("log")gca().set_ylim(1e-1, 1e5)gca().set_xlim(0.8, 1e3)subplots_adjust(left=0.2, bottom=0.2)xlabel("$k_{in}$")ylabel("$NP(k_{in})$")tight_layout()savefig("price-deg-dist.pdf")savefig("price-deg-dist.png")

下面是程序的运行结果:

vertex: 36063 in-degree: 0 out-degree: 1 age: 36063vertex: 9075 in-degree: 4 out-degree: 1 age: 9075vertex: 5967 in-degree: 3 out-degree: 1 age: 5967vertex: 1113 in-degree: 7 out-degree: 1 age: 1113vertex: 25 in-degree: 84 out-degree: 1 age: 25vertex: 10 in-degree: 541 out-degree: 1 age: 10vertex: 5 in-degree: 140 out-degree: 1 age: 5vertex: 2 in-degree: 459 out-degree: 1 age: 2vertex: 1 in-degree: 520 out-degree: 1 age: 1vertex: 0 in-degree: 210 out-degree: 0 age: 0Nowhere else to go... We found the main hub!

下面是100000个节点的度的分布。

如果你想看到一个更广泛的幂律,可以尝试增加顶点的数量到(10 ^ 6)或(10 ^ 7)。
price-deg-dist.png
(10 ^ 5)个节点的Price网络的入度分布。
我们可以画图来观察它的一些其他的拓扑特性。
为此,我们可以使用graph_draw()函数。

g = load_graph("price.xml.gz")age = g.vertex_properties["age"]pos = sfdp_layout(g)graph_draw(g, pos, output_size=(1000, 1000), vertex_color=[1,1,1,0],           vertex_fill_color=age, vertex_size=1, edge_pen_width=1.2,           vcmap=matplotlib.cm.gist_heat_r, output="price.png")

一个有(10 ^ 5 )个节点的Price网络。

顶点颜色代表顶点的年龄,旧的(红色),新的(黑)。

原文链接:

转载地址:http://rpvko.baihongyu.com/

你可能感兴趣的文章
laravel 如何添加自定义帮助函数
查看>>
Rust 和Erlang的对比
查看>>
Visual Studio 2015 for Linux更好地支持Linux下的开发
查看>>
SRE工程师到底是做什么的?
查看>>
当当网创始人李国庆宣布离开当当,投身区块链再创业
查看>>
白话解析分布式系统,小白也能看懂
查看>>
GitLab发布11.6版本,支持无服务器功能部署
查看>>
REST是否会步SOAP的后尘?
查看>>
视野与实践,看华为云如何消解Cloud2.0时代开发者的焦虑 | 好书推荐
查看>>
下一时代的HTML5和JavaScript
查看>>
KPN iTV的敏捷转型之旅
查看>>
从解决规模问题到集成AI,谈谈云服务的发展和挑战
查看>>
容器运维最佳实践
查看>>
PHP扩展库PEAR被攻击,近半年下载者或被影响
查看>>
百度:我们要利用技术的力量,成为最懂用户的公司
查看>>
Java工程师的成长路线图是什么?
查看>>
eBay通过事件溯源实现持续交付
查看>>
Google开源了Abseil,为C++和Python开发提供支持
查看>>
亚马逊发布新的AWS Step Functions集成
查看>>
Scala在挖财的应用实践
查看>>