1
$\begingroup$

In detail, I want to generate randomly something like
Divide[Add[X,Times[X,Y]],Times[X,3]]
or
{Divide,{Add,X,{Times{X,Y}}},{Times,X,3}}

(Specified Function(# of argument is from 2 to 5)) + Specified Symbol+Random Integer)
,but I don't know how to implement this. Are there any good example?

$\endgroup$
  • $\begingroup$ TreeForm[(X + Y) (Z + W)]? $\endgroup$ – Henrik Schumacher Dec 4 '18 at 17:22
  • $\begingroup$ No,I meant "Tree" is something like Func[X,Func2[Y]] ( Nested list of function?) $\endgroup$ – Xminer Dec 4 '18 at 17:34
  • 1
    $\begingroup$ I'm not sure I understand the question. Mathematica expressions are already trees. Look at ClearAll[x,y]; TreeForm[x + y]! $\endgroup$ – Pillsy Dec 4 '18 at 18:26
  • $\begingroup$ Yes,Mathematica's expression is already tree. but I wanted to create "Tree" or "Expression" randomly for using meta-programming. For example, Tree(max-depth 2 & head is "Plus") is Plus[a1,a2]. I should have use something like "Nested Function" but "Tree", Anyway thanks! $\endgroup$ – Xminer Dec 5 '18 at 9:32
4
$\begingroup$

This version is a bit more involved than the other answers given above, but it respects the condition on the arities of the functions.

ClearAll[plus, times, div, m, f, g, h];
m = 5;
f[a_, n_] := Symbol[FromCharacterCode[96 + n] <> ToString@a];
g[a_, n_] /; (n <= 1) := f[a, n];
g[a_, n_] := Replace[RandomChoice[{1, 2}], {1 -> f[a, n], 2 -> h[a + m + 1, n - 1]}];
h[a_, n_] /; (n <= 1) := g[a, n];
h[a_, n_] := Replace[RandomChoice[{
    {plus, RandomInteger[{2, m}]}, {times, RandomInteger[{2, 5}]}, {div, 2}
}], {s_, t_} :> s @@ Map[g[a + #, n] &, Range@t]];
h[n_] := h[0, n];

Most of the awkwardness is due to the fact that the accumulator a tries to force the creation of a new symbol each time. You can test it as follows:

h[5] // FullForm
(*
    plus[e1, times[d9, div[c17, plus[a31, a32, b27, a34]], d11, times[c19, plus[a33, a34, b29, a36]]], div[d10, plus[plus[b25, b26, b27, a34, b29], plus[b26, a33]]], e4]
*)

h[3] // FullForm
(* div[plus[a14, a15, b10, a17], c2] *)
$\endgroup$
2
$\begingroup$
B[B[A, A], B[A, A]] //. {B :> RandomChoice[{1, 1, 1, 1} -> {mult, div, add, sub}], A :> RandomChoice[{1, 1, 1, 1, 5} -> {mult[A, A], sub[A, A], div[A, A], add[A, A], RandomInteger[{1, 10}]}]}

I've made the initial condition non-trivial so that you'll always get a somewhat interesting result instead of, eg, just a number

add[add[add[2, 7], 7], div[mult[mult[2, 10], 5], add[div[add[1, 7], 10], 8]]]

Replace add, div, etc with Plus, Divide, ... for actual Mathematica expressions. As for variable argument lists, I'll leave that as an exercise for the reader!

$\endgroup$
1
$\begingroup$

The following example might show you a way forward. We define a recursive random function that builds a tree.

heads = {f, g};
factor = 0.9;
randomtree[mean_] := RandomChoice[heads]@@Table[randomtree[factor*mean], 
   RandomVariate[PoissonDistribution[mean]]]

randomtree[2.2]
(* g[
 g[f[f[f[], 
    f[f[f[f[g[]], g[g[f[f[g[f[], f[]], g[]]], g[]], f[]]]]]]]]] *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.