Haskell 使用给定数量的节点构建树
我有一个树的数据结构,其中的节点有一个或两个子节点。我可以生成一个给定最大深度的随机树。现在我想用给定的最大节点数(/leaves)生成这三个随机变量。这是我的结构:Haskell 使用给定数量的节点构建树,haskell,tree,binary-tree,nodes,Haskell,Tree,Binary Tree,Nodes,我有一个树的数据结构,其中的节点有一个或两个子节点。我可以生成一个给定最大深度的随机树。现在我想用给定的最大节点数(/leaves)生成这三个随机变量。这是我的结构: import System.Random data Tree a = Leaf | NodeTwo (Tree a) (Tree a) | NodeOne (Tree a) deriving (Show) create :: RandomGen g =&
import System.Random
data Tree a = Leaf
| NodeTwo (Tree a) (Tree a)
| NodeOne (Tree a)
deriving (Show)
create :: RandomGen g => Int -> Int -> Int -> Int -> g -> Tree a
create depth maxNodeOne maxNodeTwo maxLeaf g
| (depth == 0) = Leaf
| (x >= a && x < c && (maxNodeTwo /= 0))
= let (g1, g2) = split g in
NodeTwo (create (depth -1) maxNodeOne (maxNodeTwo-1)
maxLeaf g1) (create (depth -1) maxNodeOne
(maxNodeTwo-1) maxLeaf g2)
|(x >= c && x < 2*c && (maxNodeOne /= 0))
= NodeOne (create (depth -1)
(maxNodeOne -1) maxNodeTwo maxLeaf g')
| otherwise = Leaf
where (x, g') = next g
(a, b) = genRange g
c = (b - a) `div` 3
countFnk :: Tree a -> Int
countFnk (Leaf) = 0
countFnk (NodeOne a) = countFnk a
countFnk (NodeTwo a b) = 1 + countFnk a + countFnk b
countLam :: Tree a -> Int
countLam (Leaf) = 0
countLam (NodeOne a) = 1 + countLam a
countLam (NodeTwo a b) = countLam a + countLam b
countLeaf :: Tree a -> Int
countLeaf (Leaf) = 1
countLeaf (NodeOne a) = countLeaf a
countLeaf (NodeTwo a b) = countLeaf a + countLeaf b
导入系统。随机
数据树a=叶
|nodewo(树a)(树a)
|NodeOne(树a)
派生(显示)
创建::RandomGen g=>Int->Int->Int->Int->Int->g->树a
创建深度maxNodeOne maxNodeTwo maxLeaf g
|(深度==0)=叶
|(x>=a&&x=c&&x<2*c&&(maxNodeOne/=0))
=NodeOne(创建(深度-1)
(maxNodeOne-1)maxNodeTwo maxLeaf g')
|否则=叶
其中(x,g')=下一个g
(a,b)=耿
c=(b-a)`div`3
countFnk::树a->Int
countFnk(叶)=0
countFnk(NodeOne a)=countFnk a
countFnk(节点到a b)=1+countFnk a+countFnk b
countLam::树a->Int
countLam(叶)=0
countLam(NodeOne a)=1+countLam a
countLam(NodeTwo a b)=countLam a+countLam b
countLeaf::树a->Int
countLeaf(Leaf)=1
countLeaf(NodeOne a)=countLeaf a
countLeaf(NodeTwo a b)=countLeaf a+countLeaf b
这一尝试当然失败了。我不知道如何减少递归中节点的计数器。我还有一些函数可以获得节点数量(/leaves),但我不知道如何在我的create函数中使用这些函数,因为它们需要一个完成的树来扫描。
感谢您的帮助。最明显的问题是您的
节点出现了问题。到了这一点,你的“预算”是nodewo
s和NodeOne
s。但是你告诉你的新树的两个分支同样的事情:“随意花掉全部预算”!当然,如果他们都这么做,你最终会花掉双倍的预算
您需要某种方法来协商树的每个分支的预算。有很多方法可以做到这一点;例如,允许一个分支访问整个预算,并将剩余的内容提供给第二个分支。或者,在创建任何一个分支之前,您可以决定如何在它们之间分配预算,并且只为每个分支分配总预算的一部分
这两种方法中的任何一种都可能在你的随机性中引入一些偏差,这可能对你有影响,也可能对你没有影响。你应该想一种方法来处理预算会计,以产生你想要的各种随机树
一旦你解决了这个问题,你会遇到其他问题:有一些约束集是不可能建立一个适合它们的树的!最值得注意的是,如果maxLeaf
为零,则根本无法创建任何类型的树,因为每个树的某处至少有一个叶节点。您必须小心,不要构建任何可用叶数太少的子树,使它们无法终止