【问题标题】:Extending a tree in OCaml?在 OCaml 中扩展一棵树?
【发布时间】:2016-10-17 22:25:09
【问题描述】:

我想在 OCaml 中表示游戏树。当前位置是根,根的子节点代表移动后的一些结果位置,依此类推。我想动态扩展这个游戏树(一一添加新的可能动作)。

我有一个“位置”类型。我认为天真的方式是:

type tree = Nil | Node of position * (tree list);;

但这不允许我通过添加新动作来增加我的树,因为列表是不可变的。我也考虑过:

type tree = Nil | Node of position * ((tree list) ref);;

但是每次我想扩展一个节点时,我都必须替换整个子树列表,导致我想有很多无用的空间?所以我能想到的唯一方法如下: type 'a mlist = Empty | Cons of 'a * (('a mlist) ref);; type tree = Nil | Node of position * ((tree mlist) ref);;

但这似乎非常不优雅,特别是因为我基本上永远不会使用 Empty 或 Nil,具体取决于我编写叶子的方式。

【问题讨论】:

  • 树列表引用对我来说看起来完全理智。只要在列表头部添加新树,您就不必担心空间问题。
  • 我认为拉链在这里会很好用。如果他们同意,也许其他人可以扩展它。
  • 哦,谢谢 nlucaroni,我只读过关于二叉树拉链的文章,并没有意识到原来的 Huet 论文正是我所需要的!

标签: tree ocaml


【解决方案1】:

OCaml 中的列表类型是不可变的,所以你不能真正这样做:添加到它的尾部并非易事。

你拥有的可能性是:

  • 通过递归从底部构建树 - 计算值并首先构建树的叶子,然后继续向上到根。这意味着你必须知道你想去多深,这在这里可能不是一个选项,但这个解决方案是纯函数式的,或者
  • 使用一些可变的表示,例如数组。这不是纯函数式的,但如果您需要实现可变性,这是一种选择。

【讨论】:

  • 我正在动态扩展树(根据目前构建的树选择加深或加厚的位置),所以第一项是不可能的。至于第二个,我看不出数组对我有什么帮助:我不知道一个节点最终会有多少个孩子,所以我无法选择数组大小。有问题的游戏是arimaa,其中一个位置的legjal移动数量约为一万,所以我不想为每个节点创建巨大的数组,包括我只会尝试的那些,比如说,十移动。
【解决方案2】:

如果您想继续使用纯函数式: 制作二叉树类型 type 'a tree = Nil | F of 'a | Node of 'a tree * position * 'a tree;;

该类型本身仍然是静态的,但是如果您创建函数以便它们返回一个新树,那么您只需要一个更新函数来使您的树保持最新。您将有更轻松的时间添加和查找元素。这里的好处是通过使用二叉树,您可以更快地找到元素。

否则,您将不得不使用哈希表http://caml.inria.fr/pub/docs/manual-ocaml/libref/Hashtbl.html。它们是某种动态数组。你有一个基本大小和一个增长参数。只要您保持当前数组的大小,什么都不会发生,但是当您添加的元素超过当前大小所支持的数量时,hastable 会根据增长参数进化并变得更大。你必须找到正确的论点,这样你的表格就不会太多无用的空间,但不要经常增长。 :)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2017-10-29
    相关资源
    最近更新 更多