简体   繁体   English

在OCaml中扩展树?

[英]Extending a tree in OCaml?

I want to represent game trees in OCaml. 我想代表OCaml中的游戏树。 The current position is the root, the root's children represent some of the resulting positions after one move, and so forth. 当前位置是根,根的子代代表一动后得到的某些位置,依此类推。 I want to expand this game tree dynamically (adding new possible moves one by one). 我想动态扩展此游戏树(一个接一个地添加新的可能动作)。

I have a "position" type. 我有一个“职位”类型。 The naive way would be I think: 天真的方法是我认为:

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

But this does not allow me to increase my tree by adding new moves becauses lists are not mutable. 但这不允许我通过添加新动作来增加树,因为列表不可更改。 I've also considered: 我还考虑过:

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

But I would have to replace the whole list of subtrees every time I want to expand a node, resulting in a lot of useless space I suppose? 但是,每次我想扩展一个节点时,我都必须替换整个子树列表,这会导致很多我认为无用的空间吗? So the only way I can think of is as follows: type 'a mlist = Empty | Cons of 'a * (('a mlist) ref);; type tree = Nil | Node of position * ((tree mlist) ref);; 因此,我唯一想到的方法如下: type 'a mlist = Empty | Cons of 'a * (('a mlist) ref);; type tree = Nil | Node of position * ((tree mlist) ref);; type 'a mlist = Empty | Cons of 'a * (('a mlist) ref);; type tree = Nil | Node of position * ((tree mlist) ref);;

But it seems extremely inelegant, especially since I could essentially never use either Empty or Nil depending on how I'm coding leaves. 但这似乎非常不雅致,尤其是因为根据编码方式,我基本上从不使用Empty或Nil。

List type in OCaml is immutable, so you can't really do it this way: It is not trivial to add to its tail. OCaml中的列表类型是不可变的,因此您无法通过这种方式真正做到:将其添加到尾部并不容易。

The possibilities you have are: 您拥有的可能性是:

  • Build the tree from the bottom via recursion - calculate the values and first build leafs of the tree, then continue up to the root. 通过递归从底部构建树-计算值并首先构建树的叶子,然后继续到根。 That means you will have to know how deep do you want to go, which may not be an option here, but this solution is pure functional, or 这意味着您将必须知道要走多深,这在这里可能不是一个选择,但是此解决方案是纯功能性的,或者
  • Use some mutable representation, eg arrays. 使用一些可变的表示形式,例如数组。 That is not pure functional, but is an option, if you need to achieve the mutability. 如果您需要实现可变性,那不是纯粹的功能,而是一种选择。

If you want to keep using pure functional : Make a binary tree type type 'a tree = Nil | F of 'a | Node of 'a tree * position * 'a tree;; 如果要继续使用纯函数,请执行以下操作:设置二叉树类型type 'a tree = Nil | F of 'a | Node of 'a tree * position * 'a tree;; type 'a tree = Nil | F of 'a | Node of 'a tree * position * 'a tree;;

The type is still static by itself, but if you create your functions so that they return a new tree, you just have to have an update function who will keep your tree up to date. 该类型本身仍然是静态的,但是如果创建函数以使它们返回新树,则只需要具有一个更新函数即可使树保持最新状态即可。 You will have easier time to add and find elements. 您将可以更轻松地添加和查找元素。 Advantage here is that by using binary tree, you'll be faster in finding the elements. 这里的优势在于,通过使用二叉树,您可以更快地找到元素。

Else, you will have to use hash tables http://caml.inria.fr/pub/docs/manual-ocaml/libref/Hashtbl.html . 否则,您将不得不使用哈希表http://caml.inria.fr/pub/docs/manual-ocaml/libref/Hashtbl.html They are some kind of dynamic array. 它们是某种动态数组。 You have a base size and a growth argument. 您有一个基本大小和一个增长参数。 As long as you keep in size of the current array nothing happen but when you add more elements than the current size is supporting, the hastable evolve and grew bigger depending on the growth argument. 只要您保持当前数组的大小,什么都不会发生,但是当您添加的元素超过当前大小支持的数量时,hastable会演化,并且会根据增长参数而变大。 You'll have to find the correct arguments so you table don't too much useless space but don't grow to often. 您将必须找到正确的参数,以便表不会有太多无用的空间,但又不会经常增加。 :) :)

Hope it was help full 希望这对你有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM