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$
4
  • $\begingroup$ TreeForm[(X + Y) (Z + W)]? $\endgroup$ Commented Dec 4, 2018 at 17:22
  • $\begingroup$ No,I meant "Tree" is something like Func[X,Func2[Y]] ( Nested list of function?) $\endgroup$
    – Xminer
    Commented Dec 4, 2018 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
    Commented Dec 4, 2018 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
    Commented Dec 5, 2018 at 9:32

3 Answers 3

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$
3
$\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 and acknowledge you have read our privacy policy.

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