Throughputs[TreeList_] :=
Module[{tree, uses, offered, saturated, recursion, flows, nfl, isets, rt, tt, g, h, G, H, i},
(* Definitions *)
tree[n_] := {Flatten[{n, (tree[#][[1]] & /@
Flatten[ Position[TreeList, {n, __}]])}], TreeList[[n]][[2]],
tree /@ Flatten[ Position[TreeList, {n, __}]]} ;
offered[t_, ind_] :=
Min[t[[2]],
If[MemberQ[ind, t[[1, 1]] ], Infinity , 0] +
Plus @@ (offered[#, ind] & /@ Last[t])];
saturated[{}, ind_] := {Null, Null, False};
saturated[t_, ind_] :=
If[offered[t, ind] == t[[2]], {Intersection[ind, t[[1]]], t[[2]], True},
If[(i =
Position[Last[saturated[#, ind]] & /@ Last[t],
True]) == {}, {Null, Null, False},
saturated[Last[t][[i // First // First]], ind] ]];
recursion[ind_] := Module[{sat, ii, iii, r, gg, c},
{ii, c} = Drop[saturated[tt, ind], -1];
iii = Complement[ind, {#}] & /@ ii;
gg = g /@ iii;
hh = h /@ iii;
r = Last /@ TreeList[[ii]] ;
c -= Plus @@ r;
gg = r.gg/c;
hh = (If[MemberQ[ii, #], gg + g[Complement[ind, {#}]], 0] & /@ flows +
r.hh)/c;
{gg, hh} ];
(* Initializations *);
flows = Position[TreeList, {_, _, _}] // Flatten; nfl = Length[flows];
isets = Table[KSubsets[flows, k], {k, nfl}] // Flatten[#, 1] &;
rt = Position[TreeList, {Null, __}] // First // First;
tt = tree[rt];
(* Actual recursion *)
{G, H} = {g[{}], h[{}]} = {1, Table[0, {i, nfl}]};
{G, H} += ({g[#], h[#]} = recursion[#]) & /@ isets;
{G, (G/H), flows} // Simplify]
(* needs also the definition of the function
KSubsets *)