Pregunta

Estoy escribiendo un programa de juego de la vida en Mathematica, sin embargo, hay una advertencia en que necesito poder aplicar las reglas de reproducción a algún porcentaje de las células, quiero probar un nuevo método usando MAPAT, pero LiveneighBors no funciona. Elementwise, y no puedo pensar en una forma de arreglarlo sin hacer exactamente lo que hice antes (mucha indexación desordenada), ¿alguien tiene alguna sugerencia? (Supongo que esto será más eficiente que el método anterior, que se enumera a continuación, si no hágamelo saber, ¡solo soy un principiante!).

Lo que estoy tratando de hacer:

 Map[ArrayPlot,FixedPointList[MapAt[update[#,liveNeighbors[#]]&,#,coords]&,Board, 1]]

Lo que ya he hecho:

LifeGame[ n_Integer?Positive, steps_] := Module [{Board, liveNeighbors, update},
  Board = Table [Random [Integer], {n}, {n}];
  liveNeighbors[ mat_] := 
   Apply[Plus,Map[RotateRight[mat,#]&,{{-1,-1},{-1, 0},{-1,1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}]];
  update[1, 2] := 1;
  update[_, 3] := 1;
  update[ _, _] := 0;
  SetAttributes[update, Listable];
 Seed = RandomVariate[ProbabilityDistribution[0.7 UnitStep[x] + 0.3 UnitStep[x - 1], {x, 0, 1, 1}], {n, n}];
 FixedPointList[Table[If[Seed[[i, j]] == 1,update[#[[i, j]], liveNeighbors[#][[i, j]]],#[[i, j]]], {i, n}, {j, n}]&, Board, steps]]]

¡Gracias!

¿Fue útil?

Solución

In[156]:= 
LifeGame2[n_Integer?Positive, steps_] := 
 Module[{Board, liveNeighbors, update},
  Board = RandomInteger[1, {n, n}];
  liveNeighbors[mat_] := 
   ListConvolve[{{1, 1, 1}, {1, 0, 1}, {1, 1, 1}}, 
    ArrayPad[mat, 1, "Periodic"]];
  SetAttributes[update, Listable];
  Seed = RandomVariate[BernoulliDistribution[0.3], {n, n}];
  update[0, el_, nei_] := el;
  update[1, 1, 2] := 1;
  update[1, _, 3] := 1;
  update[1, _, _] := 0;
  FixedPointList[MapThread[update, {Seed, #, liveNeighbors[#]}, 2] &, 
   Board, steps]
  ]

Esta implementación hace lo mismo que la suya, excepto que es bastante más rápido:

In[162]:= AbsoluteTiming[
 res1 = BlockRandom[SeedRandom[11]; LifeGame[20, 100]];]

Out[162]= {6.3476347, Null}

In[163]:= Timing[BlockRandom[Seed[11]; LifeGame2[20, 100]] == res1]

Out[163]= {0.047, True}

Otros consejos

Suponiendo que no tenga que rodar su propio código para un problema de tarea, ¿ha considerado solo usar el incorporado? CellularAutomaton ¿función?

Directamente de la documentación, la regla 2d CA:

GameOfLife = {224, {2, {{2, 2, 2}, {2, 1, 2}, {2, 2, 2}}}, {1, 1}};

E iterar más de una cuadrícula de 100x100 para 100 pasos:

ArrayPlot[CellularAutomaton[GameOfLife, RandomInteger[1, {100, 100}], {{{100}}}]]

output of CellularAutomaton

Al menos le daría una línea de base para una comparación de velocidad.

En vez de MapAt, podrías usar Part con el Span Sintaxis para reemplazar una subarray completa a la vez:

a = ConstantArray[0, {5, 5}];
a[[2 ;; 4, 2 ;; 4]] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}

a in MatrixForm

¡Hth!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top