Functional programming 什么';OCaml中表示图形最常用的数据结构是什么?

Functional programming 什么';OCaml中表示图形最常用的数据结构是什么?,functional-programming,ocaml,Functional Programming,Ocaml,在Java或其他命令式编程中,图形可以表示为矩阵或相邻列表。相邻列表可能最受欢迎,因为它使用数组时紧凑方便 在函数式编程中,我们通常不使用可变数组。那么通常我们如何在OCaml或其他函数式编程中显示图形 将阵列替换为映射 其中列出了4种方法: 边缘条款格式 一种方法是列出所有边,边是一对节点。在这种形式中,对面描绘的图形表示为以下表达式: ['h', 'g'; 'k', 'f'; 'f', 'b'; 'f', 'c'; 'c', 'b'] 我们称之为边缘条款形式。显然,无法表示孤立的

在Java或其他命令式编程中,图形可以表示为
矩阵
相邻列表
相邻列表
可能最受欢迎,因为它使用
数组
时紧凑方便

在函数式编程中,我们通常不使用
可变数组
。那么通常我们如何在OCaml或其他函数式编程中显示图形

将阵列替换为
映射


其中列出了4种方法:

边缘条款格式

一种方法是列出所有边,边是一对节点。在这种形式中,对面描绘的图形表示为以下表达式:

['h', 'g';  'k', 'f';  'f', 'b';  'f', 'c';  'c', 'b']
我们称之为边缘条款形式。显然,无法表示孤立的节点

图形术语表

另一种方法是将整个图形表示为一个数据对象。根据图形作为两个集合(节点和边)对的定义,我们可以使用以下OCaml类型:

type 'a graph_term = { nodes : 'a list;  edges : ('a * 'a) list }
然后,上述示例图表示为:

let example_graph =
{ nodes = ['b'; 'c'; 'd'; 'f'; 'g'; 'h'; 'k'];
  edges = ['h', 'g';  'k', 'f';  'f', 'b';  'f', 'c';  'c', 'b'] }
我们称之为图项形式。注意,列表保持排序,它们实际上是集合,没有重复的元素。每个边在“边”列表中仅显示一次;i、 e.从一个节点x到另一个节点y的边表示为(x,y),耦合(y,x)不存在。图形术语形式是我们的默认表示形式。您可能希望使用集合而不是列表来定义类似的类型

邻接列表表格

第三种表示方法是将与该节点相邻的一组节点与每个节点相关联。我们称之为邻接列表形式

人性化形式

到目前为止,我们介绍的表示非常适合自动化处理,但它们的语法不是非常用户友好。手工输入术语既麻烦又容易出错。我们可以定义一个更紧凑和“人性化”的表示法如下:一个图(带有字符标记的节点)由一串原子和X-Y类型的项表示。原子代表孤立的节点,X-Y项描述边。如果X显示为边的端点,则会自动将其定义为节点。我们的示例可以写成:

"b-c f-c g-h d f-b k-f h-g"

考虑到处理效率,我认为以上4种方法都不够好


对于
记录类型图形术语表单
,没有有效的方法来定位节点(
O(n)
始终)和定位附加到节点的边。

需要考虑两件事:图形的表示和某些图形算法中使用的中间数据结构

我认为邻接列表形式是表示图的最有效的内存方式。可以通过使用这种类型的树或地图来进行一些改进

type Graph a = Map a [a]
但是,当您想要运行一些算法,如“强连接组件”或“拓扑排序”时,这些算法很可能会使用可变数组来实现它


注意,在Haskell这样的语言中,ST monad使临时可变状态(即数组)成为可能,而不是全局状态。使用此函数的函数总体上仍然是纯函数。

您可能会对OCamlGraph库()感兴趣,它提供了各种图形的实现,无论是持久的还是可变的,以及一系列经典算法。

在命令式语言中,图形表示法的选择将取决于您试图解决的问题

函数式语言也是如此


Ocamlgraph提供了足够的抽象,您可以编写独立于底层图形表示的算法,当然,算法的运行时间仍然取决于实现。

您是说“表示”吗?因为,为了仅仅呈现一个图表,我会使用类似graphviz的东西…@Ingo对不起,是的,represent@JacksonTale在我们的系统发育应用程序中,我们在树和图上使用邻接列表形式。这些节点是它们的键与相邻节点(叶子、内部或网状)类型的映射——请参见poy5项目中的tree.ml。@JacksonTale确实不是,我认为它可能是
(a*a list)映射
或其他什么(我不知道它们为什么用ml反向编写类型)@JacksonTale它看起来确实像Haskell。OCaml等价物类似于
A.t list AMap.t
,其中
A
是一个实现
Map.OrderedType
AMap.t=Map.Make(A)
的模块(不过最好使用
Set
,而不是直接列出我们在这里所做的事情:。