代数图-0.7:代数图构造和转换库
版权(c) 安德烈·莫霍夫2016-2022
许可证MIT(请参阅文件LICENSE)
维护人员andrey.mokhov@gmail.com
稳定性实验的
安全哈斯克尔
语言哈斯克尔2010

代数。图表。无方向性

描述

阿尔加是用于图的代数构造和操作的库在哈斯克尔。请参见这篇论文对于图书馆背后的动机、基础理论和实施细节。

本模块定义了代数图的无向版本。无方向性图满足所有的定律无方向性类型类别,包括的可交换性连接.

避免名称与冲突代数。图表,此模块可以导入有资格的:

导入合格的代数。图表。未定向为未定向
简介

图的代数数据类型

数据 图表来源 #

这个图表数据类型提供了四个代数图结构基本体空的,顶点,覆盖连接以及各种派生函数。图表中定义的数据类型代数。图表是那个吗连接操作是可交换的。我们定义了号码实例作为一种方便的工作符号使用无向图:

0           ==顶点01 + 2       ==覆盖(顶点1) (顶点2)1 * 2       ==连接(顶点1) (顶点2)1 + 2 * 3   ==覆盖(顶点1) (连接(顶点2) (顶点3))1 * (2 + 3) ==连接(顶点1) (覆盖(顶点2) (顶点3))

注:这个号码实例不符合以下几个“习惯法”号码,这就决定了from整数 0from整数 1应作为加法和乘法恒等式,以及否定作为加法逆。然而,超载from整数,+*在以下情况下非常方便使用代数图;我们希望将来哈斯克尔的前奏曲会为代数结构提供更精细的类层次结构,我们可以在不违反任何法律的情况下使用。

这个等式实例当前使用关系作为标准图表示并满足代数图的所有公理:

  • 覆盖是可交换和关联的:

    x+y==y+xx+(y+z)==(x+y)+z
  • 连接具有关联性、交换性和空的作为身份:

    x*空==x空*x==xx*y==y*xx*(y*z)==(x*y)*z
  • 连接分布在覆盖:

    x*(y+z)==x*y+x*z(x+y)*z==x*z+y*z
  • 连接可以分解为:

    x*y*z==x*y+x*z+y*z

从上述公理集可以证明以下有用的定理。

  • 覆盖空的作为恒等式并且是幂等的:

    x+空==x空+x==xx+x==x
  • 吸收和饱和连接:

    x*y+x+y==x*yx*x*x==x*x

在指定图形算法的时间和内存复杂性时,n个表示图中的顶点数,表示边的数量在图中,以及将表示大小对应的图表表达式。例如,如果是一个图表然后n个,可以是计算如下:

n个==顶点计数米==边缘计数秒==大小

请注意大小计算表达式的所有叶数:

顶点计数 空的== 0大小        空的== 1顶点计数(顶点x) ==1大小(顶点x) ==1顶点计数(空的+空的) == 0大小(空的+空的) == 2

转换无向图表到相应的关系O(s+m*log(m))时间和O(s+m)内存。这也是图相等性测试,因为它当前是通过转换图来实现的表达式到基于邻接映射的规范表示。

图上的总顺序使用尺寸-详图比较:

  • 比较顶点数。如果出现平局,请继续。
  • 比较顶点集。如果出现平局,请继续。
  • 比较边的数量。如果出现平局,请继续。
  • 比较边缘集。

以下是几个示例:

顶点1 <顶点2顶点3 <边缘1 2顶点1 <边缘1 1边缘1 1 <边缘1 2边缘1 2 <边缘1 1 +边缘2 2边缘1 2 <边缘1 3边缘1 2 ==边缘2 1

请注意,结果订单细化了是SubgraphOf关系和是与…兼容覆盖连接操作:

是SubgraphOfx y==>x<=y
空的<=xx<=x+yx+y<=x*y

实例

实例详细信息
莫纳德 图表 来源 # 
实例详细信息

定义于代数。图表。无方向性

方法

(>>=)::图表a->(a->图表b) ->图表b#

(>>)::图表a->图表b->图表b#

返回::a->图表#

Functor(仿真器) 图表 来源 # 
实例详细信息

定义于代数。图表。无方向性

方法

功能性维修计划::(a->b)->图表a->图表b#

(<$)::a->图表b->图表#

适用 图表 来源 # 
实例详细信息

定义于代数。图表。无方向性

方法

纯净的::a->图表#

(<*>)::图表(a->b)->图表a->图表b#

提升A2::(a->b->c)->图表a->图表b->图表c(c)#

(*>)::图表a->图表b->图表b#

(<*)::图表a->图表b->图表#

备选方案 图表 来源 # 
实例详细信息

定义于代数。图表。无方向性

MonadPlus系列 图表 来源 # 
实例详细信息

定义于代数。图表。无方向性

订单a=>等式(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

号码a=>号码(图表a) 来源 #

注:这不满足通常的环定律;看见图表了解更多细节。

实例详细信息

定义于代数。图表。无方向性

订单a=>订单(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

(显示a中,订单a) =>显示(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

IsString(IsString)a=>IsString(IsString)(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

通用(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

关联的类型

类型 代表(图表a) ::类型->类型 #

方法

::图表a->代表(图表a) x个#

::代表(图表a) x->图表#

半群(图表a) 来源 #

通过定义覆盖.

实例详细信息

定义于代数。图表。无方向性

单体(图表a) 来源 #

通过定义覆盖空的.

实例详细信息

定义于代数。图表。无方向性

NF数据a=>NF数据(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

方法

径向基函数::图表a->()#

无方向性(图表a) 来源 # 
实例详细信息

定义于代数。图表。等级

图表(图表a) 来源 # 
实例详细信息

定义于代数。图表。等级

关联的类型

类型 顶点(图表a)来源 #

类型 代表(图表a) 来源 # 
实例详细信息

定义于代数。图表。无方向性

类型 代表(图表a)=第1页('元数据“Graph”“Algebra.Graph.Undirected”“algebraic-graphs-0.7-DxCmXygYU3a8wvsz565Q5f”“真的) (C1类('MetaCons公司“UG”'前缀I'False(错误)) (S1(第一阶段)('MetaSel(元选择)('没有什么::也许 吧 符号) '无源未打包'无源严格性'决定懒惰) (0级可采收水平(图表a) ))
类型 顶点(图表a) 来源 # 
实例详细信息

定义于代数。图表。等级

类型 顶点(图表a) =a

来自Undirected::订单a=>图表a->图表来源 #

提取底层代数。图表.复杂性:O(n+m)时间。

来自Undirected(边缘1 2)     ==边缘[(1,2),(2,1)]到未定向.来自Undirected==id顶点计数.from未定向==顶点计数
边缘计数.fromUndirected<=(*2)。边缘计数

到未定向::图表a->图表来源 #

从给定的图构造一个无向图代数。图表.复杂性:O(1)时间。

至未定向(边缘1 2)         ==边缘1 2到Undirected。来自Undirected==id顶点计数.to未定向==顶点计数(*2) .边缘计数.toUndirected>=边缘计数

基本图构造基元

空的::图表来源 #

构造空图形.

栈空空==真hasVertex公司x空==假顶点计数空==0边缘计数空==0大小空==1

顶点::a->图表来源 #

构建包含以下内容的图形单个孤立顶点.

栈空(顶点x)==假hasVertex公司x(顶点y)==(x==y)顶点计数(顶点x)==1边缘计数(顶点x)==0大小(顶点x)==1

边缘::a->a->图表来源 #

构建包含以下内容的图形单边.

边缘x y==连接(顶点x)(顶点年)边缘x y==边缘年x边缘x y==边缘[(x,y),(y,x)]hasEdge公司x y(边x y)==真边缘计数(边缘x y)==1顶点计数(边缘1 1)==1顶点计数(边缘1 2)==2

覆盖::图表a->图表a->图表来源 #

覆盖两张图。这是一个交换的、结合的和幂等的具有标识的操作空的.复杂性:O(1)时间和记忆,O(s1+s2)大小。

栈空(覆盖x y)==栈空x个&&栈空has顶点z(覆盖x y)==hasVertex公司z x轴||hasVertex公司z y(z y)顶点计数(覆盖x y)>=顶点计数x个顶点计数(覆盖x y)<=顶点计数x个+顶点计数边缘计数(覆盖x y)>=边缘计数x个边缘计数(覆盖x y)<=边缘计数x个+边缘计数大小(覆盖x y)==大小x个+大小顶点计数(叠加12)==2边缘计数(覆盖12)==0

连接::图表a->图表a->图表来源 #

连接两张图。这是一个与身份空的,分布在覆盖并遵守分解公理。复杂性:O(1)时间和记忆,O(s1+s2)大小。请注意结果图中边的数量与参数的顶点:m=O(m1+m2+n1*n2).

连接x年==连接年x栈空(连接x y)==栈空x个&&栈空hasVertex公司z(连接x y)==hasVertex公司z x轴||hasVertex公司z y(z y)顶点计数(连接x y)>=顶点计数x个顶点计数(连接x y)<=顶点计数x个+顶点计数边缘计数(连接x y)>=边缘计数x个边缘计数(连接x y)>=边缘计数边缘计数(连接x y)>=顶点计数x个*顶点计数边缘计数(连接x y)>=顶点计数x个*顶点计数div公司2大小(连接x y)==大小x个+大小顶点计数(连接12)==2边缘计数(连接12)==1

顶点::[a]->图表来源 #

构造包含给定孤立顶点列表的图。复杂性:O(L)时间、内存和大小,其中L(左)是的长度给定列表。

顶点[]==空的顶点[x]==顶点x个顶点==覆盖层.map(地图)顶点
hasVertex公司x。顶点==元素x个顶点计数.vertices(顶点)==长度.节点
顶点集.vertices==设置。来自列表

边缘::[(a,a)]->图表来源 #

从边列表构造图形。复杂性:O(L)时间、内存和大小,其中L(左)是的长度给定列表。

边[]==空的边[(x,y)]==边缘x年边[(x,y),(y,x)]==边缘x年

覆盖层:: [图表a] ->图表来源 #

覆盖给定的图形列表。复杂性:O(L)时间和记忆,以及O(S)大小,其中L(左)是长度给定列表的S公司是列表中图形的大小之和。

覆盖[]==空的覆盖[x]==x覆盖[x,y]==覆盖x年覆盖层==文件夹 覆盖 空的
栈空.覆盖层==全部的 栈空

连接:: [图表a] ->图表来源 #

连接给定的图表列表。复杂性:O(L)时间和记忆,以及O(S)大小,其中L(左)是长度给定列表的S公司是列表中图形的大小之和。

连接[]==空的连接[x]==x连接[x,y]==连接x年连接==文件夹 连接 空的
栈空.连接==全部的 栈空connects==连接。颠倒

图形折叠

折叠::b->(a->b)->(b->b->b)->(b->b->b)->图表a->b来源 #

概括图表折叠:递归折叠图表通过应用为表达式的叶和内部节点提供的函数。参数的顺序是:空、顶点、覆盖和连接。复杂性:O(s)个给定函数的应用。例如复杂性大小O(s)个,自常数+成本不变。

折叠空的 顶点        覆盖 连接==id折叠空的 顶点        覆盖(轻弹 连接)==id折叠1(常数1)     (+)     (+)            ==大小foldg正确(常数假)(&&)(&&&)==栈空foldg False(==x)(||)(|||)==hasVertex公司x个

图上的关系

是SubgraphOf::订单a=>图表a->图表a->布尔 来源 #

这个是SubgraphOf函数接受两个图形并返回真的如果第一个图形是子图第二个。复杂性:O(s+m*log(m))时间。请注意,边的数量图形可以是表达式大小的二次曲线.

是SubgraphOf空的x==正确是SubgraphOf(顶点x)空的==错误是x的子图(覆盖x y)==真是SubgraphOf(覆盖x年)(连接x y)==真是SubgraphOf(路径X轴)(电路xs)==正确是SubgraphOf(边缘x年)(边缘y x)==真是x y的子图==>x<=y

到关系::订单a=>图表a->关系来源 #

将无向图转换为对称图关系.

图形属性

栈空::图表a->布尔 来源 #

检查图形是否为空。复杂性:O(s)个时间。

栈空空的==正确是空的(覆盖 空的 空的)==正确是空的(顶点x) ==错误是空的(移除顶点x个$顶点x) ==正确是空的(删除边缘x年$边缘x y)==错误

大小::图表a->国际 来源 #

这个大小图的叶数,即表达式的叶数包括空的树叶。复杂性:O(s)个时间。

大小空的== 1尺寸(顶点x) ==1尺寸(覆盖x y)==尺寸x+尺寸y尺寸(连接x y)==尺寸x+尺寸y尺寸x>=1尺寸x>=顶点计数x个

hasVertex公司::等式a=>a->图表a->布尔 来源 #

检查图形是否包含给定的顶点。复杂性:O(s)个时间。

hasVertex x(具有顶点x)空的==错误hasVertex x(具有顶点x)(顶点y) ==(x==y)hasVertex x。移除顶点x个==常数False(错误)

hasEdge公司::等式a=>a->a->图表a->布尔 来源 #

检查图形是否包含给定边。复杂性:O(s)个时间。

hasEdge x y轴空的==错误hasEdge x y轴(顶点z) ==错误hasEdge x y轴(边缘x y)==真hasEdge x y轴(边缘y x)==真hasEdge x y。删除边缘x年==常数False(错误)hasEdge x y轴==元素(最小x y,最大x y)。边缘列表

顶点计数::订单a=>图表a->国际 来源 #

图中的顶点数。复杂性:O(s*log(n))时间。

顶点计数空的==  0顶点计数(顶点x) ==1顶点计数==长度.顶点列表顶点计数x<顶点计数y==>x<y

边缘计数::订单a=>图表a->国际 来源 #

图中的边数。复杂性:O(s+m*log(m))时间。请注意,边的数量图形可以是表达式大小的二次曲线.

边缘计数空的== 0边缘计数(顶点x) ==0边缘计数(边缘x y)==1边缘计数==长度.边缘列表

顶点列表::订单a=>图表a->[a]来源 #

给定图的顶点排序列表。复杂性:O(s*log(n))时间和O(n)内存。

顶点列表空的== []顶点列表(顶点x) ==[x]顶点列表。顶点==节点.分类

边缘列表::订单a=>图表a->[(a,a)]来源 #

图形的边的排序列表。复杂性:O(s+m*log(m))时间和O(米)内存。请注意边缘图的大小可以是表达式大小的二次方.

边缘列表空的== []边缘列表(顶点x) ==[]边缘列表(边缘x y)==[(最小x y,最大y x)]边缘列表(明星2 [3,1]) == [(1,2), (2,3)]

顶点集::订单a=>图表a->设置来源 #

给定图的顶点集。复杂性:O(s*log(n))时间和O(n)内存。

顶点集空的==设置。空的顶点集。顶点==设置。单子顶点集。顶点==设置。来自列表

边缘设置::订单a=>图表a->设置(a、a)来源 #

给定图的边集。复杂性:O(s*log(m))时间和O(米)内存。

边缘设置空的==设置。空的边缘设置(顶点x) ==设置。空的边缘设置(边缘x y)==设置。单子(最小值x年,最大值x年)

邻接列表::订单a=>图表a->[(a,[a])]来源 #

已排序的邻接列表图形的。复杂性:O(n+m)时间和记忆。

邻接列表空的== []邻接列表(顶点x) ==[(x,[])]邻接列表(边缘1 2)     == [(1, [2]), (2, [1])]邻接列表(明星2 [3,1]) == [(1, [2]), (2, [1,3]), (3, [2])]星星.a邻接列表==id

邻居::订单a=>a->图表a->设置来源 #

顶点集相邻的到给定顶点。

邻居x空的==设置。空的邻居x(顶点x) ==设置。空的邻居x(边缘x y)==设置。来自列表[年]邻居y(边缘x y)==设置。来自列表【x】

标准图族

路径::[a]->图表来源 #

这个路径在顶点列表上。复杂性:O(L)时间、内存和大小,其中L(左)是的长度给定列表。

路径[]==空的路径[x]==顶点x个路径[x,y]==边缘x年路径。颠倒==路径

电路::[a]->图表来源 #

这个电路在顶点列表上。复杂性:O(L)时间、内存和大小,其中L(左)是的长度给定列表。

电路[]==空的电路[x]==边缘x x x电路[x,y]==边缘(x,y)电路。颠倒==电路

集团::[a]->图表来源 #

这个集团在顶点列表上。复杂性:O(L)时间、内存和大小,其中L(左)是的长度给定列表。

集团[]==空的集团[x]==顶点x个集团[x,y]==边缘x年集团[x,y,z]==边缘[(x,y),(x,z),(y,z)]集团(xs++ys)==连接(集团xs)(集团ys)集团。颠倒==集团

二液化::[a]->[a]->图表来源 #

这个二液化在两个顶点列表上。复杂性:O(L1+L2)时间、内存和大小,其中第一层L2级给定列表的长度。

双液[][]==空的双液[x][]==顶点x个双液[][y]==顶点双液[x1,x2][y1,y2]==边缘[(x1,y1),(x1、y2),(x2,x2),(x2,y2)]双液xs-ys==连接(顶点xs)(顶点年)

明星::a->[a]->图表来源 #

这个明星由连接到叶子列表的中心顶点形成。复杂性:O(L)时间、内存和大小,其中L(左)是的长度给定列表。

星形x[]==顶点x个星x[y]==边缘x年星x[y,z]==边缘[(x,y),(x,z)]星形x y==连接(顶点x)(顶点年)

星星::[(a,[a])]->图表来源 #

这个星星通过覆盖列表形成明星s.的逆邻接列表.复杂性:O(L)时间、内存和大小,其中L(左)是的总大小输入。

星星[]==空的星星[(x,[])]==顶点x个星星[(x,[y])]==边缘x年星星[(x,ys)]==明星x年星星==覆盖层.地图(未修剪的 明星)星星。邻接列表==id覆盖(星星xs)(星星ys)==星星(xs++ys)

::a->图表来源 #

这个树状图根据给定的数据结构。复杂性:O(T)时间、内存和大小,其中是的大小给定树(即树中的顶点数)。

树(节点x[])==顶点x个树(节点x[节点y[节点z[]]])==路径[x,y,z]树(节点x[节点y[],节点z[]])==明星x〔y,z〕树(节点1[节点2[],节点3[节点4[],结点5[]])==边缘[(1,2), (1,3), (3,4), (3,5)]

森林::森林a->图表来源 #

这个森林图根据给定的森林数据结构。复杂性:O(F)型时间、内存和大小,其中F类是的大小给定森林(即森林中的顶点数)。

林[]==空的森林[x]==x个森林[节点1[节点2[],节点3[]],节点4[节点5[]]]==边缘[(1,2), (1,3), (4,5)]森林==覆盖层.地图 

图形转换

移除顶点::等式a=>a->图表a->图表来源 #

从给定图形中删除顶点。复杂性:O(s)个时间、内存和大小。

移除顶点x(顶点x)==空的删除顶点1(顶点2)       ==顶点2移除顶点x(边缘x x)==空的删除顶点1(边缘1 2)       ==顶点2删除顶点x。移除顶点x==移除顶点x

删除边缘::等式a=>a->a->图表a->图表来源 #

从给定图形中删除边。复杂性:O(s)个时间、内存和大小。

删除边缘x y(边缘x年)==顶点[x,y]移除边缘x y。removeEdge x y==删除边缘x y移除边缘x y==移除边缘y x移除边缘x y。移除顶点x个==移除顶点x个removeEdge 1 1(1*1*2*2)==1*2*2removeEdge 1 2(1*1*2*2)==1*1+2*2

替换顶点::等式a=>a->a->图表a->图表来源 #

功能替换顶点x年替换顶点x个带顶点在一个鉴于图表.如果已经存在,x个将合并。复杂性:O(s)个时间、内存和大小。

替换顶点x x==id替换顶点x y(顶点x)==顶点替换顶点x y==合并顶点(==x)y

合并顶点::(a->布尔)->a->图表a->图表来源 #

将满足给定谓词的顶点合并为给定顶点。复杂性:O(s)个时间、内存和大小,假设谓词恒定时间。

合并顶点(常数假)x==id合并顶点(==x)y==替换顶点x年合并顶点即使1 (0 * 2)     == 1 * 1合并顶点古怪的1 (3 + 4 * 5) == 4 * 1

诱导::(a->布尔) ->图表a->图表来源 #

构造诱导子图通过移除不满足给定谓词的顶点。复杂性:O(s)个时间、内存和大小,假设谓词恒定时间。

诱导(常数真)x==x诱导(常数假)x==空的诱导(/=x)==移除顶点x个诱导p。诱导q==诱导(\x->px&&qx)是SubgraphOf(诱导px)x==真

诱导Just::图表(也许 吧a) ->图表来源 #

构造诱导子图通过删除顶点来确定给定图形的那是没有什么.复杂性:O(s)个时间、内存和大小。

诱因只是(顶点 没有什么)                               ==空的诱因只是(边缘(只是x)没有什么)                        ==顶点x个诱导Just。功能性维修计划 只是==身份证件诱导Just。功能性维修计划(\x->如果p x那么只是x其他没有什么) ==诱导第页

补充::订单a=>图表a->图表来源 #

图的边补。注意,从示例中可以看出下面,此操作忽略自循环。复杂性:O(n^2*log n)时间,O(n^2)内存。

补充空的==空的补充(顶点x) ==(顶点x)补充(边缘1 2)      == (顶点[1, 2])补充(边缘0 0)      == (边缘0 0)补充(明星1 [2, 3]) == (覆盖(顶点1) (边缘2 3))补语。补码==id