Recursive Abelian Sandpile algorithm won't return final value
Mostra commenti meno recenti
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 Commenti
jgg
il 22 Gen 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
il 22 Gen 2016
jgg
il 22 Gen 2016
Try walking through your code using the keyboard command and see.
Eric Faulk
il 22 Gen 2016
jgg
il 22 Gen 2016
Do you have an example of a starting sandmatrix so I can try some things?
Eric Faulk
il 22 Gen 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.
Risposta accettata
Più risposte (1)
Walter Roberson
il 23 Gen 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.
Categorie
Scopri di più su Entering Commands in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!