1

更新

erlang 中的 digraph 库实现了一种具有副作用的数据类型。对数据类型的每个操作都将其新状态保存在 ets 表中——而不是返回其自身的更改版本,这在函数式语言中更为常见。

从使用的角度来看,问题在于它阻碍了我以方便的方式存储或传递状态,因为它要求我首先“收集”状态,然后才能开始处理它。

到目前为止,我看到的最接近的解决方案是serializer/deserializer,但它们的缺点是它们与 digraphs 的当前结构相关联,而不是在抽象类型上操作——这阻碍了未来的证明解决方案。

更新

Pascal 指出了另一个利用有向图接口的序列化程序,从而消除了上面提到的缺点。它显然要好得多,尽管仍然不方便,但我认为没有更好的选择。


您对如何存储有向图有什么建议?我应该完全使用不同的数据类型吗?

谢谢。

4

2 回答 2

3

您还可以使用 Erlang 的sofs(集合集)模块来获得完整的不可变数据结构,其中包含之后重建相同图形所需的所有数据

clone(Digraph) ->
  Family = sofs:digraph_to_family(Digraph),
  sofs:family_to_digraph(Family).
于 2016-08-11T11:51:11.710 回答
2

我不确定你的担心。有向图存储在 ETS 中的事实在用户界面中是透明的,因此您可能希望更改这一点,以便与另一个进程交换有向图、制作副本或永久存储以防崩溃。

对于前两个主题,很容易在元组中检索有向图的定义,{Cyclic,Protect,[Vertice],[edge]}然后交换它:

digraph_To_Tuple(Di) ->
    Opt = digraph:info(Di),
    Vs = [digraph:vertex(Di,X) || X <- digraph:vertices(Di)],
    Es = [digraph:edge(Di,X) || X <- digraph:edges(Di)],
    {proplists:get_value(cyclicity,Opt),proplists:get_value(protection,Opt),Vs,Es}.

clone (Di) -> 
    {Cyclic,Protect,Vs,Es} = digraph_To_Tuple(Di),                                                                        
    Do = digraph:new([Cyclic,Protect]),                                                                            
    [digraph:add_vertex(Do,V,N) || {V,N} <- Vs ],  
    [digraph:add_edge(Do,E,S,D,N) || {E,S,D,N} <- Es], 
    Do.

最后一个主题是一个真正的问题,因为一旦创建它的进程死亡,一个 ets 就会被销毁。有一些方法可以将所有权转让给其他进程,但在这种情况下,与 ets 实现的独立性就会丢失。更好的可能性是在一个进程中创建有向图并将其传递给其他负责操作它们的进程。

但我不认为在不重写部分或整个模块的情况下拥有另一种类型的存储有任何意义。

于 2013-09-25T12:41:51.883 回答