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

代数。图表。非循环。相邻地图

描述

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

本模块定义了相邻地图数据类型和非循环图,如以及相关的操作和算法。避免名称与冲突代数。图表。相邻地图,此模块可以合格导入:

导入合格的代数。图表。非循环。相邻地图为非循环
简介

数据结构

数据 相邻地图来源 #

这个相邻地图数据类型通过映射表示非循环图顶点到其相邻集。尽管内部表示允许对于循环,此模块提供的方法不能用于构造带循环的图形。

这个显示实例是使用基本图构造原语定义的,其中可能,回落到到非循环代数。图表。相邻地图否则:

show empty==“空”显示(收缩1)==“顶点1”显示(收缩$1+2)==“顶点[1,2]”show(收缩$1*2)==“(fromJust.toAcyclic)(边缘12)”show(收缩$1*2*3)==“(fromJust.toAcyclic)(边[(1,2),(1,3),(2,3)]”show(收缩$1*2+3)==“(fromJust.toAcyclic)(覆盖(顶点3)(边1 2)”

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

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

请注意,结果订单细化了是SubgraphOf关系:

是SubgraphOfx y==>x<=y

来自非循环::相邻地图a->相邻地图来源 #

提取底层非循环代数。图表。相邻地图.复杂性:O(1)时间和记忆。

来自非循环空的==空的来自非循环。顶点==顶点来自非循环(收缩$1*3+2)==1*3+2顶点计数.来自非循环==顶点计数
边缘计数.来自非循环==边缘计数
是非循环的.来自非循环==常数真的

基本图构造基元

空的::相邻地图来源 #

构造空图形.

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

顶点::a->相邻地图来源 #

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

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

顶点::订单a=>【a】->相邻地图来源 #

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

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

联盟:: (订单a、,订单b) =>相邻地图a->相邻地图b->相邻地图(要么a b)来源 #

构造不相交联盟两张图中的一张。复杂性:O((n+m)*log(n))时间和O(n+m)内存。

顶点集(联合x y)==设置。工会[设置。地图 左侧(顶点集x),设置。地图 赖特(顶点集y) ]边缘设置(联合x y)==设置。工会[设置。地图(双地图 左侧  左侧) (边缘设置x),设置。地图(双地图 赖特 赖特) (边缘设置y) ]

参加:: (订单a、,订单b) =>相邻地图a->相邻地图b->相邻地图(要么a b)来源 #

构造参加两张图中的一张。复杂性:O((n+m)*log(n))时间和O(n+m)内存。

顶点集(连接x y)==设置。工会[设置。地图 左侧(顶点集x),设置。地图 赖特(顶点集y) ]边缘设置(连接x y)==设置。工会[设置。地图(双地图 左侧  左侧) (边缘设置x),设置。地图(双地图 赖特 赖特) (边缘设置年),设置。地图(双地图 左侧  赖特)(设置。卡特森产品(顶点集x)(顶点集y) )]

图上的关系

是SubgraphOf::订单a=>相邻地图a->相邻地图a->布尔 来源 #

这个是SubgraphOf函数接受两个图形并返回真的如果第一个图形是子图第二个。复杂性:O((n+m)*log(n))时间。

是SubgraphOf空的x==正确是SubgraphOf(顶点x)空的==错误是SubgraphOf(诱导p x)x==真isx的子图(传递闭包x) ==正确是x y的子图==>x<=y

图形属性

栈空::相邻地图a->布尔 来源 #

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

栈空空的==正确是空的(顶点x) ==错误是空的(移除顶点x个$顶点x) ==正确是空的(删除边缘1 2$收缩$1*2)==假

hasVertex公司::订单a=>a->相邻地图a->布尔 来源 #

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

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

hasEdge公司::订单a=>a->a->相邻地图a->布尔 来源 #

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

hasEdge x y轴空的==错误hasEdge x y轴(顶点z) ==错误hasEdge 1 2(收缩$1*2)==真hasEdge x y。删除边缘x年==常数False(错误)hasEdge x y轴==元素(x,y)。边缘列表

顶点计数::相邻地图a->国际 来源 #

图中的顶点数。复杂性:O(1)时间。

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

边缘计数::相邻地图a->国际 来源 #

图中的边数。复杂性:O(n)时间。

边缘计数空的== 0边缘计数(顶点x) ==0edgeCount(收缩$1*2)==1边缘计数==长度.边缘列表

顶点列表::相邻地图a->[a]来源 #

给定图的顶点排序列表。复杂性:O(n)时间和记忆。

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

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

图的边的排序列表。复杂性:O(n+m)时间和O(米)内存。

边缘列表空的== []边缘列表(顶点x) ==[]edgeList(收缩$2*1)==[(2,1)]边缘列表。转置==分类.地图 互换.edgeList(.edge列表)

邻接列表::相邻地图a->[(a,[a])]来源 #

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

邻接列表空的== []邻接列表(顶点x) ==[(x,[])]adjacencyList(收缩$1*2)==[(1,[2]),(2,[])]

顶点集::相邻地图a->设置来源 #

给定图的顶点集。复杂性:O(n)时间和记忆。

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

边缘设置::等式a=>相邻地图a->设置(a、a)来源 #

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

边缘设置空的==设置。空的边缘设置(顶点x) ==设置。空的edgeSet(收缩$1*2)==设置。单子(1,2)

预设::订单a=>a->相邻地图a->设置来源 #

这个预设元素的x个是它的集合吗直接前辈.复杂性:O(n*log(n))时间和O(n)内存。

预设置x空的==设置。空的预设置x(顶点x) ==设置。空的preSet 1(收缩$1*2)==设置。空的preSet 2(收缩$1*2)==设置。来自列表[1]设置。成员x。预设置x==常数False(错误)

postSet(postSet)::订单a=>a->相邻地图a->设置来源 #

这个后置顶点的集合直接继承人.复杂性:O(对数(n))时间和O(1)内存。

后置集x空的==设置。空的postSet x(顶点x) ==设置。空的postSet 1(收缩$1*2)==设置。来自列表[2]postSet 2(收缩$1*2)==设置。空的设置。成员x。postSet x==常数False(错误)

图形转换

移除顶点::订单a=>a->相邻地图a->相邻地图来源 #

从给定的非循环图中删除顶点。复杂性:O(n*log(n))时间。

移除顶点x(顶点x)==空的删除顶点1(顶点2)       ==顶点2移除顶点1(收缩$1*2)==顶点2删除顶点x。移除顶点x==移除顶点x

删除边缘::订单a=>a->a->相邻地图a->相邻地图来源 #

从给定的非循环图中删除边。复杂性:O(对数(n))时间。

removeEdge 12(收缩$1*2)==顶点[1,2]移除边缘x y。removeEdge x y==删除边缘x y移除边缘x y。移除顶点x个==移除顶点x个removeEdge 1 2(收缩$1*2*3)==收缩((1+2)*3)

转置::订单a=>相邻地图a->相邻地图来源 #

转置给定的非循环图。复杂性:O(m*log(n))时间,O(n+m)内存。

转置空的==空的转置(顶点x)==顶点x个转置。转置==id边缘列表.转置==分类.地图 互换.边缘列表

诱导::(a->布尔) ->相邻地图a->相邻地图来源 #

构造诱导子图通过移除不满足给定谓词的顶点。复杂性:O(n+m)时间,假设谓词采用常量时间。

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

诱导Just::订单a=>相邻地图(也许 吧a) ->相邻地图来源 #

构造诱导子图通过删除顶点来确定给定图形的那是没有什么.复杂性:O(n+m)时间。

诱因只是(顶点 没有什么) ==空的诱导Just。顶点.只是==顶点

图形组成

:: (订单a、,订单b) =>相邻地图a->相邻地图b->相邻地图(a、b)来源 #

计算笛卡尔积图的数量。复杂性:O((n+m)*log(n))时间和O(n+m)内存。

边缘列表(盒子(收缩$ 1 * 2) (收缩$ 10 * 20)) == [ ((1,10), (1,20)), ((1,10), (2,10)), ((1,20), (2,20)), ((2,10), (2,20)) ]

直到结果顶点类型之间的同构,此操作是可交换的相联的,具有作为身份空的作为零化.以下~~代表平等,最高可达同构,例如。(x, ()~~x.

框x y ~~框y x盒子x(盒子yz)~~盒子(盒子xy)z方框x(顶点()~~x方框x空的~~空的
转置(方框x y)==方框(转置x)(转置年)顶点计数(方框x y)==顶点计数x个*顶点计数边缘计数(方框x y)<=顶点计数x个*边缘计数年+边缘计数x个*顶点计数

关系操作

传递闭包::订单a=>相邻地图a->相邻地图来源 #

计算传递闭包图形的。复杂性:O(n*m*log(n)^2)时间。

传递闭包空的==空的传递闭包(顶点x)==顶点x个transitiveClosure(收缩$1*2+2*3)==收缩(1*2+1*3+2*3)传递闭包。transitiveClosure==传递闭包

算法

top排序::订单a=>相邻地图a->[a]来源 #

计算a拓扑排序非循环图的。

top排序空的== []top排序(顶点x) ==[x]topSort(收缩$1*(2+4)+3*4)==1,2,3,4]top排序(参加x y)==功能性维修计划 左侧(顶部排序x)++功能性维修计划 赖特(顶部排序y)赖特.top排序==top排序.来自非循环

供应链控制::订单a=>相邻地图a->相邻地图(相邻地图a)来源 #

计算非循环凝结图的每个顶点对应于强连接组件原始图形的。注释组件图是非空的,因此属于类型代数。图表。非空。相邻地图.

供应链控制空的==空的供应链控制(顶点x)==顶点(非空。顶点x)供应链控制(边缘1 1)          ==顶点(非空。边缘1 1)边缘列表美元scc(边缘1 2)==[(非空。顶点1,非空。顶点2       ) ]边缘列表$scc(3*1*4*1*5)==[(非空。顶点3,非空。顶点5       ),(非空。顶点3,非空。小集团1[1,4,1]),(非空。小集团1[1,4,1],非空。顶点5       ) ]

转换为非循环图

到非循环::订单a=>相邻地图a->也许 吧(相邻地图a)来源 #

从给定的邻接映射构造一个非循环图,或返回没有什么如果输入包含循环。

到非循环(路径[1,2,3]) ==只是(缩水1*2+2*3美元)到非循环(集团[3,2,1]) ==只是(转置(缩水1*2*3美元)到非循环(电路[1,2,3]) ==没有什么到非循环。来自非循环==只是

到非循环订单::订单a=>相邻地图a->相邻地图来源 #

从给定的邻接图构造一个非循环图,只保留边(x,y)哪里x<y根据提供的订单 实例。

到非循环订单空的==空的至AcyclicOrd。顶点==顶点toAcyclicOrd(1+2)==收缩toAcyclicOrd(1*2)==收缩(1*3)toAcyclicOrd(2*1)==收缩(1+2)toAcyclicOrd(1*2*1)==收缩(1*2)toAcyclicOrd(1*2*3)==收缩(1*2%3)

收缩::订单a=>相邻地图a->相邻地图来源 #

使用从给定的邻接图构造非循环图供应链控制.如果图是非循环的,则按原样返回。如果图是循环的,那么代表其冷凝过程中的每个强连接成分选择图,并使用这些代表来构建非循环图。

收缩。顶点==顶点收缩。顶点==顶点收缩。来自非循环==身份证件

其他

一致的::订单a=>相邻地图a->布尔 来源 #

检查非循环图的内部表示是否一致,也就是说,所有边都指向现有的顶点,并且图是非循环的。应该不可能创建不一致的相邻地图.

一致的空的==正确一致的(顶点x) ==正确一致的(顶点xs)==正确一致的(联盟x y)==真一致的(参加x y)==真一致的(转置x) ==正确一致的(x y)==真一致的(传递闭包x) ==正确一致的(供应链控制x) ==正确功能性维修计划一致的(到非循环x) /=错误一致的(到非循环订单x) ==正确