Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用给定数量的节点构建树_Haskell_Tree_Binary Tree_Nodes - Fatal编程技术网

Haskell 使用给定数量的节点构建树

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 =&

我有一个树的数据结构,其中的节点有一个或两个子节点。我可以生成一个给定最大深度的随机树。现在我想用给定的最大节点数(/leaves)生成这三个随机变量。这是我的结构:

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
为零,则根本无法创建任何类型的树,因为每个树的某处至少有一个叶节点。您必须小心,不要构建任何可用叶数太少的子树,使它们无法终止