Recursive Abelian Sandpile algorithm won't return final value
이전 댓글 표시
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
jgg
2016년 1월 22일
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
2016년 1월 22일
jgg
2016년 1월 22일
Try walking through your code using the keyboard command and see.
Eric Faulk
2016년 1월 22일
jgg
2016년 1월 22일
Do you have an example of a starting sandmatrix so I can try some things?
Eric Faulk
2016년 1월 22일
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.
채택된 답변
추가 답변 (1개)
Walter Roberson
2016년 1월 23일
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.
카테고리
도움말 센터 및 File Exchange에서 Entering Commands에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!