Язык Wolfram, рекурсия RandomChoice

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

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

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


person alan2here    schedule 28.07.2014    source источник
comment
что вы подразумеваете под не осталось решить? это похоже на то, что он должен продолжать, отказываясь, пока он случайно не выберет 2.   -  person agentp    schedule 29.07.2014


Ответы (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 *)

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

person agentp    schedule 29.07.2014

Ваш запрос кажется немного противоречивым: когда случайный выбор выбирает 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, можно использовать While. Здесь тоже происходит рекурсия, но While поддерживает процесс при выборе числа.

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

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

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

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

Это оставшиеся элементы в списке: -

ReleaseHold /@ heldlist

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

person Chris Degnen    schedule 29.07.2014