主要内容总结:
- 图的定义与常见类型:图由节点和连接节点的箭头(边)组成,节点和边可包含数据,常见的有有向图、无向图、简单图、多重图、超图、超超图等。图在软件工程(如包依赖、模块导入等)、业务逻辑(如引用的白皮书、交通网络、社交网络等)中广泛存在。
缺乏图支持的原因:
- 设计选择过多:图的类型多样,包括有向、无向,简单、多重等,每种类型又有不同的变体,如超图、超超图等,这给库的设计带来很多决策,且不同类型的图在算法性能上有差异,如二分图可使用特定快速算法,而其他图需用慢算法,这增加了库的维护负担。
- 实现选择过多:对于简单的有向图,编程语言内部存储方式有边列表、邻接表、邻接矩阵、结构体引用等,不同表示方式在不同图操作上性能不同,且对于有节点数据、边数据等情况,第三方库大致分为提供单一丰富数据类型和为每种表示提供单独图类型两类,前者效率低,后者增加算法维护负担。
- 性能重要性:很多图算法是 NP 完全或更难的,图可能很大,数据表示和算法实现细节对算法性能影响大,如在 Nosey Parker 中,原有的图遍历器不适用,需设计新算法;在 15 谜题中,通用图类型无法与针对问题选择的表示竞争;即使是图数据库在优化基本图操作时也有困难,所以需要对数据表示和算法有很多控制。
不同语言中的图类型:
- 图查询语言:如 SPARQL、Neo4j 的 Cypher 等,主要区别是关系是一等实体,GQL 可操作边,如求演员间的关联路径等,但 SPARQL 不能计算路径长度和沿路径计算,更复杂的 GQL 支持这些功能,从 Alloy 的关系数据类型可看出图支持所需的遍历原语。
- 主流语言中的图:Python 在 2020 年添加了 graphlib,但使用较少,CPython 中几乎未使用;Erlang 和 SWI-Prolog 也有图类型,但不知何时添加;还有“一切都是图”的编程语言如 GP2、Grape 等目前仍较学术;数学软件语言如 Mathematica、MATLAB、Maple 等有各种形式的图库。
总之,语言不在标准库中支持图是因为设计决策多、权衡多、维护负担重,程序员避免使用第三方图库是因为其要么有限要么慢,只有在极端情况下才考虑用图,且不同语言和库在图的支持上存在差异。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。