少し遅れたと思いますが、質問は好きです。フォームでツリーを作成する代わりに
{0 -> 1, 0 -> 5, 1 -> 2, 1 -> 3, 1 -> 4}
次の形式のネストされた呼び出しを使用します。ここで、すべての引数は別のノードを表す子です。
0[1[2, 3, 4], 5]
両方の形式は同等であり、相互に変換できます。
Row[{
TreeForm[0[1[2, 3, 4], 5]],
TreePlot[{0 -> 1, 0 -> 5, 1 -> 2, 1 -> 3, 1 -> 4}]
}]

アルゴリズムの仕組みは次のとおりです。引数としてf
、乱数の子を与える関数が必要で、ノードの作成時に呼び出されます。さらに、d
(サブ) ツリーが持つことができる最大の深さを定義する深さがあります。
[分岐を選択]f
同様に呼び出すことができf[]
、乱数の子を返す分岐関数を定義します。2 つまたは 4 つの子を持つツリーが必要な場合は、たとえば を使用できますf[] := RandomChoice[{2, 4}]
。この関数は、ツリーで作成されたノードごとに呼び出されます。
[ツリーの深さを選択] ツリーの最大の深さを選択d
します。この時点で、ランダム性をツリーの生成に組み込むことを望んでいるのかわかりません。ここで行うことは、新しいノードが作成されると、その下にあるツリーの深さが、その親の深さから 1 を引いた値と 0 の間でランダムに選択されるということです。
[ID カウンタの作成] 一意のカウンタ変数count
を作成し、ゼロに設定します。これにより、ノード ID が増加します。新しいノードを作成すると、1 ずつ増加します。
【ノードを作成する】count
ノードIDとして増やして使用します。現在の深度d
がゼロの場合は、ID カウントを持つリーフを返します。それ以外の場合f
は、ノードが取得する子の数を決定するために呼び出します。新しい子ごとに、そのサブツリーの深さをランダムに選択し、0,...,d-1
新しい子ごとに 4. を呼び出します。すべての再帰呼び出しが戻ると、ツリーが構築されます。
幸いなことに、Mathematicaのコードでは、この手順はそれほど冗長ではなく、数行しかありません。上記で説明したことをコードで見つけていただければ幸いです
With[{counter = Unique[]},
generateTree[f_, d_] := (counter = 0; builder[f, d]);
builder[f_, d_] := Block[
{nodeID = counter++, childs = builder[f, #] & /@ RandomInteger[d - 1, f[]]},
nodeID @@ childs
];
builder[f_, 0] := (counter++);
]
次のようなランダムなツリーを作成できます
branching[] := RandomChoice[{2, 4}];
t = generateTree[branching, 6];
TreeForm[t]

または、次の関数を使用して、ツリーを受け入れられるものに変換することもできます。TreePlot
transformTree[tree_] := Module[{transform},
transform[(n_Integer)[childs__]] := (Sow[
n -> # & /@ ({childs} /. h_Integer[__] :> h)];
transform /@ {childs});
Flatten@Last@Reap[transform[tree]
]
それを使用して、多くのランダムツリーを作成します
trees = Table[generateTree[branching, depth], {depth, 3, 7}, {5}];
GraphicsGrid[Map[TreePlot[transformTree[#]] &, trees, {2}]]
