Recursive Abelian Sandpile algorithm won't return final value
Mostrar comentarios más antiguos
I am trying to implement a simple abelian sandpile algorithm using a recursive call. The function takes a matrix of positive numbers as input. I structured my code as follows:
function[thematrix] = abelian(sandmatrix)
for c = 1:size(sandmatrix,2)
for n = 1:size(sandmatrix,1)
if sandmatrix(n,c) >= 4
sandmatrix(n,c) = sandmatrix(n,c)-4
sandmatrix(n+1,c) = sandmatrix(n+1,c) + 1
sandmatrix(n,c+1) = sandmatrix(n,c+1) + 1
sandmatrix(n-1,c) = sandmatrix(n-1,c) + 1
sandmatrix(n,c-1) = sandmatrix(n,c-1) + 1
if any(max(sandmatrix) >= 4)
abelian(sandmatrix)
else
break
end
end
end
end
The code seems to run well, and produces the sandpile behavior that I would expect. However, it isn't returning the final sandpile. Instead, it stores the one prior to the final one, (with a single 4 left in the matrix) and starts the recursion over again.
0 0 0 0 0 0 0
0 0 1 2 1 0 0
0 1 0 3 0 1 0
0 2 3 0 2 2 0
0 1 0 2 4 0 0
0 0 1 2 0 0 0
0 0 0 0 0 0 0
Is my break in the wrong spot? Any help would be appreciated.
7 comentarios
jgg
el 22 de En. de 2016
I'm not familiar with the algorithm, so I can't say what it should be doing, but this
abelian(sandmatrix)
Looks wrong. You're not assigning the recursive call to anything here, so you never "pop" out of the recursion.
Eric Faulk
el 22 de En. de 2016
jgg
el 22 de En. de 2016
Try walking through your code using the keyboard command and see.
Eric Faulk
el 22 de En. de 2016
jgg
el 22 de En. de 2016
Do you have an example of a starting sandmatrix so I can try some things?
Eric Faulk
el 22 de En. de 2016
Does this do what you intend for the second case:
function[thematrix] = abelian(sandmatrix)
global val;
for c = 1:size(sandmatrix,2)
for n = 1:size(sandmatrix,1)
if sandmatrix(n,c) >= 4
sandmatrix(n,c) = sandmatrix(n,c)-4;
sandmatrix(n+1,c) = sandmatrix(n+1,c) + 1;
sandmatrix(n,c+1) = sandmatrix(n,c+1) + 1;
sandmatrix(n-1,c) = sandmatrix(n-1,c) + 1;
sandmatrix(n,c-1) = sandmatrix(n,c-1) + 1;
if any(max(sandmatrix) >= 4)
abelian(sandmatrix);
else
val = sandmatrix;
break;
end
end
end
thematrix = val;
end
There must be a more efficient way to do this though. Hopefully someone else has a suggestion.
Respuesta aceptada
Más respuestas (1)
Walter Roberson
el 23 de En. de 2016
function [sandmatrix] = abelian(sandmatrix)
for c = 1:size(sandmatrix,2)
for n = 1:size(sandmatrix,1)
if sandmatrix(n,c) >= 4
sandmatrix(n,c) = sandmatrix(n,c)-4
sandmatrix(n+1,c) = sandmatrix(n+1,c) + 1
sandmatrix(n,c+1) = sandmatrix(n,c+1) + 1
sandmatrix(n-1,c) = sandmatrix(n-1,c) + 1
sandmatrix(n,c-1) = sandmatrix(n,c-1) + 1
if any(max(sandmatrix) >= 4)
sandmatrix = abelian(sandmatrix);
else
break
end
end
end
end
I am not convinced this should be looping over c and n though. I suspect it should be searching for a point that is >= 4 rather than looping. I could be wrong, though, as I am not familiar with this algorithm.
Categorías
Más información sobre Entering Commands en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!