F#树递归&从叶子遍历时计算结果

时间:2017-04-28 23:30:40

标签: f# tree tail-recursion

我正在寻找一些指针/片段来解决以下任务。

type Rel = 
{
  id:int,
  from:int,
  to:int,
  percent:float
  IsLeafNode:string
}

我有以下数据

id  from to percent isLeafNode`

1   A    B  0.6     N

2   A    C  0.4     N

3   B    D  0.2     N

4   B    E  0.8     Y

5   C    F  1.0     N

6   D    G  1.0     Y

7   F    H  0.7     Y

8   F    B  0.3     N

9   I    J  1.0     N

10  J    K  1.0     Y

我需要构建一个树或图形,例如from和to之间的关系,并将一些特定节点(在本例中为A和I)的百分比乘以叶节点,并计算起始id到叶级Id和计算的百分比。我正在寻找以下结果

1 - 6 (A to G via B,D)       = 0.6 * 0.2 * 1.0 = 0.12

1 - 4 (A to E via B)         = 0.6 * 0.8 = 0.48

1 - 7 (A to H via C,F)       = 0.4 * 1.0 * 0.7 = 0.28

1 - 6 (A to G via C,F,B,D,G) = 0.4 * 1.0 * 0.3 * 0.2 * 1.0 = 0.024

1 - 4 (A to E via C,F,B,E)   = 0.4 * 1.0 * 0.3 * 0.8 = 0.096

9 - 10(I to K via J)         = 1.0 * 1.0 = 1.0

我正在尝试确定要使用的结构类型以及如何使用一些已经解析的节点,例如B在解决A的左侧时已经解决了; F到B应该能够使用已计算的B到G和B到E的百分比。我使用这种方法处理了大量数据,最多可达50级。

只占用前几个节点,这就是我正在做的事情

type internal LeafNode
{
    ID:int;
    to:string;
    percent:float;
}

type internal ChurnNode =
{
    ID:int;
    from:string;
    percent:float;
}

type internal Tree<'L,'N> =
    | Leaf of 'L
    | Node of 'N * Tree<'L,'N> seq

type internal Eq = Tree<LeafNode, ChurnNode>

let rec Fold fLeaf fNode acc (tree: Tree<'L,'N>) : 'r =
    let recurse = Fold fLeaf fNode
    match tree with
        | Leaf leafInfo ->
            fLeaf acc leafINfo
        | Node (nodeInfo, children) ->
             let localAcc = fNode acc nodeInfo
             let finalAcc = children |> Seq.fold recurse localAcc
             finalAcc  //return

let ComputePercent eq =
    let fleaf acc (leaf:LeafNode) =
        acc * leaf.percent
    let fNode acc (node:ChurnNode) =
        acc * node.percent
    Fold fleaf fNode 1.0 eq

let RunProcess() =
    let nodeA = {ID=0;from="A";percent=1.0}
    let nodeB = {ID=1;from="B";percent=0.6} 
    let leafC = {ID=2;to="C";percent=0.4}
    let leafD = {ID=2;to="D";percent=0.2}
    let leafE = {ID=2;to="E";percent=0.8}

    let t = Node(nodeA, [NodeB, [Leaf(leafD); Leaf(leafE)]; Leaf(leafC)]

    t |> ComputePercentage

A至B至D&amp; E,该代码返回1.0 * 0.6 * 0.2 * 0.8但是我需要A到B到D = 1.0 * 0.6 * 0.2并且A到B到E = 1.0 * 0.6 * 0.8。你能告诉我如何用叶子重置累加器。可能是我在这里错了脚,但这对我来说有点棘手。

0 个答案:

没有答案