Domanda

Sto scrivendo un programma Game of Life in Mathematica, tuttavia c'è un avvertimento in quanto devo essere in grado di applicare le regole di riproduzione a una percentuale delle celle, voglio provare un nuovo metodo usando MAPAT ma Liveneighbors non funziona Elementwise, e non riesco a pensare a un modo di risolverlo senza fare esattamente quello che ho fatto prima (un sacco di indicizzazione disordinata), qualcuno ha qualche suggerimento? (Suppongo che questo sarà più efficiente del vecchio metodo, che è elencato di seguito, se non per favore fammelo sapere, sono solo un principiante!).

Cosa sto cercando di fare:

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

Quello che ho già fatto:

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]]]

Grazie!

È stato utile?

Soluzione

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]
  ]

Questa implementazione fa come la tua, tranne che è molto più veloce:

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}

Altri suggerimenti

Supponendo che non devi arrotolare il tuo codice per un problema a casa, hai preso in considerazione l'utilizzo del integrato CellularAutomaton funzione?

Direttamente dalla documentazione, la regola CA 2D:

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

E iterare oltre una griglia 100x100 per 100 passaggi:

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

output of CellularAutomaton

Almeno ti darebbe una linea di base per un confronto di velocità.

Invece di MapAt, potresti usare Part con il Span sintassi per sostituire un intero subarray contemporaneamente:

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

a in MatrixForm

Hth!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top