1 主要模块:
从源代码就可以看出networkx的整个结构,主要是以下几部分:
- 图对象类,其定义图的存储结构结构;
- 创造图类,用来产生一些标准的经典的图,比如完全图、树状图等等;
- 从其它数据源读取并构建图的辅助函数;
- 图分析功能,里面包含了经常多的图算法,基本你叫得出名的都可以在里面找到;
- 图绘制功能,只是提供了一个接口,具体由其它库实现比如graphviz;
2 api设计原则:
network大多数api都是一个全局函数,算法要作用的图数据通过一个参数传进去。这种扁平的代码结构对理解学习图算法非常有利,有时我们读一些软件的源代码发现非常难读,比如有些代码是用面向对象的方式实现的,其代码逻辑被各种封装继承多态打得支离破碎,总是不能一眼看到逻辑的全貌,总有一种“我在哪里?我要去到哪里?”的感觉。好了,扯远了。前面提到api通过一个参数将图传进去,这个参数本身是一个类,这个类里面也有提供方法,但这些方法都是只跟图数据的存储相关的,没有将复杂的算法放到其中。这样就保证了数据结构和算法的分离,读起来相当的顺畅,我们甚至可以先读懂network中的算法再将其实现到其它平台上,比如自己写算法扩展neo4j、或者将算法转换成pregel的形式放到graphx等分布式图计算引擎上执行3 一些规范:
- networkx类名使用驼峰命名法(第一个单词首字母也大写)
- 函数、变量使用小写字母,用下划线分隔
- 官方推荐这种方式引入:
import networkx as nx
4 四种图类型:
图按照“是否有向”、“两个点之前是否有多条边”这两个维度划分,组合形成四种图:- Graph - 无向图,两个结点间只能有一条边其它边会被忽略掉,边可以自环(即一个点和自己相连);
- DiGraph - 有向图(前缀Di即Direct);
- MultiGraph - 无向图允许两点间有多条边,这增加了灵活性会导致一些性能下降,但不会太多,该类继承自Graph;
- MultiDiGraph - 有向图并允许两点间有多条边,,该类继承自DiGraph;
为什么不把数据的类型统一起来呢?让一种类型就可以支持所有的类型呢,官方给出的答案是:
- 很多图的经典算法对于有向图,无向图是不同的
- 是否有多个条边对于图的存储结构影响比较大,如果可以确定只有单条边可以做一些优化
5 内部存储结构:
networkx将图的存储结构封装到了一个类中,这个类只提供了最简单的结点遍历、结点边的属性获取等操作,一个该类的实例就是一个图,所有的图数据存储于其中。networkx使用邻接表来存储图,使用一个三重的python dict来实现:- 第一重dict的key是结点,value是一个dict表示它的邻居结点,由于直接使用python的dict所以这里只要是可以hash的值都可以作为结点,不过一般实际中使用一个结点id来作为key;
- 第二重dict就是上面的邻居结点,它的key是每个邻居结点,同理也是可以hash的类型,value是边上的多个属性;
- 第三重dict就指边上的所有属性,key是边的属性名,value就是属性的值了;