digraph模块是对图结构的一种封装,主要的description请参考http://www.erlang.org/doc/man/digraph.html
下面来看看digraph的一些方法:
图结构无非就是由一些节点和边组成的,在digraph中有个Label的东西,这个其实就是图节点的附加信息,类似在C语言中在一个节点中放个指针,指向一些附加的信息。
那么要创建图,就必须要先创建一些图的基本结构出来
new() -> digraph()
new(Type) -> digraph()
cyclic
Allow cycles in the digraph (default).
acyclic
The digraph is to be kept acyclic.
protected
Other processes can read the digraph (default).
private
The digraph can be read and modified by the creating process only.
cyclic表示的是有向有环图:如果一个有向图能从某个顶点出发经过若干条边回到该点,则这个图是一个有向有环图
acyclic表示的是有向无环图:如果一个有向图无法从某个顶点出发经过若干条边回到该点,则这个图是一个有向无环图
protected表示该图可以被其他进程访问
private表示只能被创建这个图的那个进程访问
那么可以看出图的信息应该是存储在ets表中的
add_vertex(G) -> vertex()
add_vertex(G, V) -> vertex()
add_vertex(G, V, Label) -> vertex()
这个三个方法就是给某个图增加一个节点上去,同时可以给出这个节点的附带信息Label
add_edge(G, V1, V2) -> edge() | {error, add_edge_err_rsn()}
add_edge(G, V1, V2, Label) -> edge() | {error, add_edge_err_rsn()}
add_edge(G, E, V1, V2, Label) ->
这三个方法就是给V1节点和V2节点之间建立一条边,并且给出这个边的附带信息Label
如果在一个有向无环图中创建一条边导致这个图可以构成有环图,那么就会抛出{error,{bad_edge,Path}}的错误,如果V1和V2节点中有任意一个不是图的节点,那么也会抛出{error,{bad_vertex,V}}的错误
还有一些删除图的边以及点,还有一些可以获取图中的点以及边的方法具体请参照官方文档
get_cycle(G, V) -> Vertices | false
Types:
G = digraph()
V = vertex()
Vertices = [vertex(), ...]
If there is a simple cycle of length two or more through the vertex V, then the cycle is returned as a list [V, ..., V] of vertices, otherwise if there is a loop through V, then the loop is returned as a list [V]. If there are no cycles through V, then false is returned.
上面的方法是在图中找出一条简单的可以构成环的路径出来,返回中间经过的点,请见例子
G = digraph:new([cyclic]).
digraph:add_vertex(G,1,{vertex1}).
digraph:add_vertex(G,2,{vertex2}).
digraph:add_vertex(G,3,{vertex3}).
digraph:add_edge(G,1,2).
digraph:add_edge(G,2,3).
digraph:add_edge(G,3,1).
digraph:get_cycle(G,2). 输出为[2,3,1,2]
get_path(G, V1, V2) -> Vertices | false
Types:
G = digraph()
V1 = V2 = vertex()
Vertices = [vertex(), ...]
Tries to find a simple path from the vertex V1 to the vertex V2 of the digraph G. Returns the path as a list [V1, ..., V2] of vertices, or false if no simple path from V1 to V2 of length one or more exists.
在途中找出一条从V1到V2的路径
digraph:get_path(G,1,2).
[1,2]
get_short_cycle(G, V) -> Vertices | false
Types:
G = digraph()
V = vertex()
Vertices = [vertex(), ...]
Tries to find an as short as possible simple cycle through the vertex V of the digraph G. Returns the cycle as a list [V, ..., V] of vertices, or false if no simple cycle through V exists. Note that a loop through V is returned as the list [V, V].
跟get_cycle差不多,只不过这里要最短的环
get_short_path(G, V1, V2) -> Vertices | false
Types:
G = digraph()
V1 = V2 = vertex()
Vertices = [vertex(), ...]
Tries to find an as short as possible simple path from the vertex V1 to the vertex V2 of the digraph G. Returns the path as a list [V1, ..., V2] of vertices, or false if no simple path from V1 to V2 of length one or more exists.
与get_path同理
in_degree(G, V) -> integer() >= 0
Types:
G = digraph()
V = vertex()
Returns the in-degree of the vertex V of the digraph G.
返回一个点的入度数量,图的入度,出度可以查阅图的知识
digraph:in_degree(G,1).
1
out_degree(G, V) -> integer() >= 0
Types:
G = digraph()
V = vertex()
Returns the out-degree of the vertex V of the digraph G.
与上面相对应,这个是计算某个节点出度的值
in_neighbours(G, V) -> Vertex
Types:
G = digraph()
V = vertex()
Vertex = [vertex()]
Returns a list of all in-neighbours of V of the digraph G, in some unspecified order.
通俗来说就是返回那些指向节点V的其他节点
digraph:in_neighbours(G,1).
[3]
out_neighbours(G, V) -> Vertices
Types:
G = digraph()
V = vertex()
Vertices = [vertex()]
Returns a list of all out-neighbours of V of the digraph G, in some unspecified order.
与上面的相反
digraph:out_neighbours(G,1).
[2]
info(G) -> InfoList
Returns a list of {Tag, Value} pairs describing the digraph G. The following pairs are returned:
{cyclicity, Cyclicity}, where Cyclicity is cyclic or acyclic, according to the options given to new.
{memory, NoWords}, where NoWords is the number of words allocated to the ETS tables.
{protection, Protection}, where Protection is protected or private, according to the options given to new.
这个方法的作用比较明显,不再累赘
erlang还提供digraph_util的工具模块,有兴趣的可以去查看,下面就看看rabbitmq用到了digraph_util的几个方法
方法一
reaching(Vertices, Digraph) -> Reaching
Types:
Digraph = digraph()
Vertices = Reaching = [digraph:vertex()]
Returns an unsorted list of digraph vertices such that for each vertex in the list, there is a path from the vertex to some vertex of Vertices. In particular, since paths may have length zero, the vertices of Vertices are included in the returned list.
返回这些节点之间在图中存在有path的点集
方法二:
subgraph(Digraph, Vertices) -> SubGraph
subgraph(Digraph, Vertices, Options) -> SubGraph
Types:
Digraph = SubGraph = digraph()
Vertices = [digraph:vertex()]
Options = [{type, SubgraphType} | {keep_labels, boolean()}]
SubgraphType = inherit | [digraph:d_type()]
Creates a maximal subgraph of Digraph having as vertices those vertices of Digraph that are mentioned in Vertices.
If the value of the option type is inherit, which is the default, then the type of Digraph is used for the subgraph as well. Otherwise the option value of type is used as argument to digraph:new/1.
If the value of the option keep_labels is true, which is the default, then the labels of vertices and edges of Digraph are used for the subgraph as well. If the value is false, then the default label, [], is used for the subgraph's vertices and edges.
subgraph(Digraph, Vertices) is equivalent to subgraph(Digraph, Vertices, []).
There will be a badarg exception if any of the arguments are invalid.
返回这些节点的最大子图,最大子图就是在给出的节点中,从原图中构造出一个节点最多的子图
方法三
topsort(Digraph) -> Vertices | false
Types:
Digraph = digraph()
Vertices = [digraph:vertex()]
Returns a topological ordering of the vertices of the digraph Digraph if such an ordering exists, false otherwise. For each vertex in the returned list, there are no out-neighbours that occur earlier in the list.
即是拓扑排序了。
一个简单的求拓扑排序的算法:首先要找到任意入度为0的一个顶点,删除它及所有相邻的边,再找入度为0的顶点,以此类推,直到删除所有顶点。顶点的删除顺序即为拓扑排序。
相关推荐
从给定的文件信息中,我们可以提炼出一些关于Erlang语言以及其参数化模块的重要知识点。 首先,Erlang是一种严格、动态类型的函数式编程语言。它的特点是没有破坏性更新,即数据不可变。Erlang内置了对并发的支持,...
BBEdit 的 Erlang 语言模块 v1.4, (2018/01/14) Erlang语言模块为BBEdit 11和更高版本的Erlang编程语言引入了语法着色,自动完成,功能导航和代码折叠。 它识别以下 Erlang 文件: erlang 源代码 (.erl) erlang 包含...
Erlang是一种面向并发、分布式计算的编程语言,它的源代码是组织在模块(module)中的。模块是Erlang程序的基本单位,包含了特性(attribute)和函数(function)声明。下面将详细介绍Erlang模块的规则、特性、...
模块是Erlang代码的基本组织单位,可以包含函数和记录。记录类似于结构体,提供了一种命名字段的数据结构。模块间通过导出和导入函数来实现接口交互,便于代码复用和维护。 在分布式系统方面,Erlang节点可以在网络...
Erlang源码揭示了这些模块如何设计和实现,包括如何使用Erlang的模块化特性来组织代码,以及如何通过进程间的通信来协调各个部分的工作。 5. **热代码升级** Erlang的热代码升级机制允许在不中断服务的情况下更新...
在Erlang编程环境中,模块级别的热部署是一项关键特性,它允许开发者在不中断系统运行的情况下更新或替换已加载的模块。这对于实时系统和高可用性服务尤其重要,因为它们需要持续提供服务而不能因为代码更新而停机。...
这本书的作者Fred Hébert是一位在一线拥有丰富实战经验的工程师,他通过轻松幽默的文风和清晰的讲解,向读者介绍了Erlang的模块、函数、类型、递归、错误处理、数据结构、并行编程、多处理、事件处理以及Erlang的...
5. **模块化编程**:Erlang的模块系统可以帮助组织代码,习题可能要求学习者将功能分解到多个模块中,提高代码的可重用性和可读性。 6. **性能优化**:通过解决实际问题,学习者可以学习到如何有效地利用Erlang的...
php扩展peb.so erlang通讯扩展,解决宝塔编译安装php peb扩展编译失败,直接上传到php扩展目录修改配置文件即可使用。
### Erlang 中文基础教程:理解Erlang Shell与模块函数 #### 1. Erlang Shell:编程者的交互式环境 Erlang Shell是Erlang编程语言提供的一种交互式编程环境,允许开发者直接在命令行中编写、执行Erlang代码并观察...
模块名必须和文件名相同,否则 Erlang 无法找到模块。函数是模块中的基本单元,用于实现具体的计算任务。 在 Erlang 中,用户可以使用模块和函数来实现复杂的计算任务。例如,用户可以创建一个模块,定义一个函数来...
2. **API更新**:可能对Erlang的内置函数或模块进行增强,提供新的功能或修复已知问题。 3. **兼容性提升**:与先前版本相比,25.0可能增强了与其他软件或框架的兼容性。 4. **错误修复**:解决上一版本中的已知问题...
例如,如果你想要添加一个新功能,可以在`rabbitmq_server/src`目录下创建一个新的Erlang模块,然后在`rabbit`模块中调用它。确保遵循Erlang的模块命名规范,并在`rabbit.app`配置文件中声明你的模块。 在测试和...
**Erlang 模块模板** 是一个针对 Erlang 编程语言的工具,它提供了一种方便的方式来创建和管理代码模板。Erlang 是一种并发性极强、功能丰富的编程语言,尤其适用于构建分布式系统和高可用性的软实时应用。在 Erlang...
- **OTP(开放电信平台)**:Erlang OTP是一套库和设计原则,提供了构建可靠系统的框架,包括Mnesia数据库、Event Manager、Supervisor和GenServer等行为模块。 学习Erlang时,你需要掌握以下核心概念: - **BEAM...
3. **过程和模块**:Erlang的组织方式,包括如何定义和调用函数,以及模块的使用。 4. **错误调试**:Erlang的错误处理机制,如shell的使用、日志和调试工具。 5. **REPL(Read-Eval-Print Loop)**:Erlang shell...
此外,这本书还会讨论Erlang的模块系统、类型系统以及如何利用REPL(Read-Eval-Print Loop)进行调试和测试。 这两本书的结合,为学习Erlang提供了全面的视角。《Erlang and OTP in Action》以其实践导向,帮助...
Erlang还有强大的模块系统,每个文件对应一个模块,模块内包含函数定义。 OTP库提供了许多实用的模块,如gen_server、gen_event和gen_fsm,这些都是Erlang并发编程的基础。 总而言之,Erlang9.rar是一个包含Erlang/...
Erlang还提供了丰富的标准库,如`io`模块用于输入输出,`lists`模块提供了各种列表操作,`erlang`模块包含了Erlang的内置函数等。`client.erl`可能会使用这些库来实现功能,比如`io:format/2`用于打印信息,`lists:...
**Erlang编程:Introducing Erlang** Erlang是一种函数式编程语言,由爱立信在1986年开发,主要用于构建高可用性、容错性和并发性的分布式系统。"Introducing Erlang"是Simon St. Laurent撰写的一本入门级教程,...