zoukankan      html  css  js  c++  java
  • graph-tool文档(一)- 快速开始使用Graph-tool

    目录:

    • 属性映射
      -- 内部属性映射
    • 图的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 izip
    from numpy.random import randint
    
    g = Graph()
    g.add_vertex(100)
    # insert some random links
    for 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 point
    vprop_double[g.vertex(10)] = 3.1416
    
    vprop_vint = g.new_vertex_property("vector<int>")         # Vector of ints
    vprop_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")                  # Boolean
    gprop_bool[g] = True
    

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

    from numpy.random import random
    
    # this assigns random values to the vertex properties
    vprop_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 places
    from __future__ import division, absolute_import, print_function
    import sys
    if sys.version_info < (3,):
        range = xrange
    import os
    from pylab import *  # for plotting
    from numpy.random import *  # for random sampling
    seed(42)
    
    # We need to import the graph_tool module itself
    from 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 graph
    g = Graph()
    
    # We want also to keep the age information for each vertex and edge. For that
    # let's create some property maps
    v_age = g.new_vertex_property("int")
    e_age = g.new_edge_property("int")
    
    # The final size of the network
    N = 100000
    
    # We have to start with one vertex
    v = 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 vertices
    for 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_age
    g.edge_properties["age"] = e_age
    
    # now we can save it
    g.save("price.xml.gz")
    
    
    # Let's plot its in-degree distribution
    in_hist = vertex_hist(g, "in")
    
    y = in_hist[0]
    err = sqrt(in_hist[0])
    err[err >= y] = y[err >= y] - 1e-2
    
    figure(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: 36063
    vertex: 9075 in-degree: 4 out-degree: 1 age: 9075
    vertex: 5967 in-degree: 3 out-degree: 1 age: 5967
    vertex: 1113 in-degree: 7 out-degree: 1 age: 1113
    vertex: 25 in-degree: 84 out-degree: 1 age: 25
    vertex: 10 in-degree: 541 out-degree: 1 age: 10
    vertex: 5 in-degree: 140 out-degree: 1 age: 5
    vertex: 2 in-degree: 459 out-degree: 1 age: 2
    vertex: 1 in-degree: 520 out-degree: 1 age: 1
    vertex: 0 in-degree: 210 out-degree: 0 age: 0
    Nowhere else to go... We found the main hub!
    

    下面是100000个节点的度的分布。
    如果你想看到一个更广泛的幂律,可以尝试增加顶点的数量到(10 ^ 6)或(10 ^ 7)。

    (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网络。
    顶点颜色代表顶点的年龄,旧的(红色),新的(黑)。

    原文链接:Quick start using graph-tool

  • 相关阅读:
    python 函数
    python升级功能
    python3与c++的不同点(初学看重点~)
    python中的数据结构
    github超简单用法
    ListView
    线性代数(1)--方程组的同解变形
    C++基础学习
    C++多态
    PKU《程序设计》专项课程_递归汉诺塔问题
  • 原文地址:https://www.cnblogs.com/leezx/p/5568283.html
Copyright © 2011-2022 走看看