Wolfram Language, рекурсия RandomChoice

a = RandomChoice[{a,2}]&
a[]

Есть и другие способы достижения этого примера, но я хочу сделать более сложные вещи, подобные этому, используя этот метод.

Могу ли я получить это, чтобы продолжить, пока нет aОсталось решить, не производя переполнение стека, пытаясь решить {a,2} прежде чем сделать выбор? Вместо этого делать выбор и разрешать только выбранный символ.

2 ответа

Решение

Вот способ иметь RandomChoice оценивать функцию только при выборе:

 g := (Print["evaluate g"]; 42);
 f = ( If[TrueQ[#], g, #] &@RandomChoice[{True, 1, 2, 3, 4}]) &
 Table[f[], {10}]

это печатает "оценивать g" только при случайном выборе и выводит, например.

 (* {2, 42, 3, 1, 3, 2, 4, 42, 2, 4} *)

Это еще один способ, может быть, немного чище:

 f = Unevaluated[{g, 1, 2, 3, 4}][[RandomInteger[{1, 5}]]] &

это работает нормально рекурсивно:

 a = Unevaluated[{a[], 2}][[RandomInteger[{1, 2}]]] &

Хотя, как я сказал в комментарии, он просто возвращает 2 каждый раз, так как повторяется до тех пор, пока не будет выбрано 2.

 a[] (* 2 *)

Я не понимаю всего вопроса, и я думаю, что есть лучший способ выполнить то, что вы хотите.

Ваш запрос кажется немного противоречивым: когда выбирается случайный выбор a Вы хотите, чтобы он повторялся, но если он выбирает номер, вы все равно хотите продолжить, пока нет aосталось.

Следующий код делает это, но рекурсия технически не нужна. Возможно, в вашем приложении это будет применимо.

Первая часть показывает, как вы можете повторить выбор a используя Hold:-

Clear[a]

list = {1, 2, a, 1, a, 3, a, 1, 4, 5};

heldlist = Hold /@ list;

a := Module[{z}, z = RandomChoice[heldlist]; 
  Print["for information, choice was ", z];
  If[MatchQ[z, Hold[_Symbol]],
   heldlist = DeleteCases[heldlist, z, 1, 1];
   If[MemberQ[heldlist, Hold[_Symbol]], ReleaseHold[z]]]] 

a

По этому поводу звоню a рекурсивно один раз, затем выбирает 4 и останавливается, как и ожидалось.

для информации, выбор был Hold[a]

для информации, выбор был Hold[4]

Чтобы процесс продолжался, пока нет a"s While может быть использован. Здесь тоже есть рекурсия, но While продолжает процесс, когда число выбрано.

While[MemberQ[heldlist, Hold[_Symbol]], a]

для информации, выбор был Hold[a]

для информации, выбор был Hold[1]

для информации, выбор был Hold[a]

Это остальные пункты в списке:

ReleaseHold /@ heldlist

{1, 2, 1, 3, 1, 4, 5}

Другие вопросы по тегам