Hi, I am trying to make a predator-prey simulation and I've mapped structs in containers. One struct is one animal and the container represents either the predator or the prey. Now I want a prey to be eaten when it moves within a certain range of a predator. How do I delete a struct? Be easy on me, I'm a bit new to MATLAB. (;
Here's the code: the important part is below %ROOFDIEREN ---> %ETEN.
% VARIABELEN
numDays = 50;
geboortekansPrey = 0.00;
geboortekansPred = 0.00;
minleeftijdPrey = 10;
minleeftijdPred = 10;
axis = 100;
W = 0:1:axis;
r = 2;
% MAPPEN MET INITIËLE DIEREN
predMap = containers.Map('KeyType', 'double', 'ValueType', 'any');
pred = struct('x', 1, 'y', 1, 'age', 25);
predMap(1) = pred;
preyMap = containers.Map('KeyType', 'double', 'ValueType', 'any');
prey = struct('x', 2, 'y', 2, 'age', 15);
preyMap(1) = prey;
prey = struct('x', 3, 'y', 3, 'age', 20);
preyMap(2) = prey;
% DAGEN
for t = 1:numDays
disp(['day ', num2str(t),':']);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PROOIDIEREN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('Prooidieren:');
for p = 1:length(preyMap)
newPrey = preyMap(p);
% COÖRDINATEN
d = rand * r;
rad = rand * 2 * pi;
newpreyx = newPrey.x + cos(rad) * d;
newpreyy = newPrey.y + sin(rad) * d;
while newpreyx<0 || newpreyx>axis || newpreyy<0 || newpreyy>axis
d = rand * r;
rad = rand * 2 * pi;
newpreyx = newPrey.x + cos(rad) * d;
newpreyy = newPrey.y + sin(rad) * d;
end
newPrey.x = newpreyx;
newPrey.y = newpreyy;
% LEEFTIJD
newPrey.age = newPrey.age + 1;
preyMap(p) = newPrey;
% WEERGAVE
Leeftijd = sprintf('Leeftijd: %d', preyMap(p).age);
disp(Leeftijd)
Plaats = sprintf('Coördinaten: (%d, %d)', preyMap(p).x, preyMap(p).y);
disp(Plaats)
% GEBOORTE
if preyMap(p).age > minleeftijdPrey
out=rand;
if out<geboortekansPrey
prey = struct('x', W(randi([1,numel(W)])), 'y', W(randi([1,numel(W)])), 'age', 0);
preyMap(length(preyMap) + 1) = prey;
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ROOFDIEREN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
disp('Roofdieren:');
for q = 1:length(predMap)
newPred = predMap(q);
% COÖRDINATEN
d = rand * r;
rad = rand * 2 * pi;
newpredx = newPred.x + cos(rad) * d;
newpredy = newPred.y + sin(rad) * d;
while newpredx<0 || newpredx>axis || newpredy<0 || newpredy>axis
d = rand * r;
rad = rand * 2 * pi;
newpredx = newPred.x + cos(rad) * d;
newpredy = newPred.y + sin(rad) * d;
end
newPred.x = newpredx;
newPred.y = newpredy;
% LEEFTIJD
newPred.age = newPred.age + 1;
% ETEN
if abs(newPred.x - newPrey.x)<v && abs(newPred.y - newPrey.y)<v
delete??????
end
predMap(q) = newPred;
% WEERGAVE
Leeftijd = sprintf('Leeftijd: %d', predMap(q).age);
disp(Leeftijd)
Plaats = sprintf('Coördinaten: (%d, %d)', predMap(q).x, predMap(q).y);
disp(Plaats)
% GEBOORTE
if predMap(q).age > minleeftijdPred
out=rand;
if out<geboortekansPred
pred = struct('x', W(randi([1,numel(W)])), 'y', W(randi([1,numel(W)])), 'age', 0);
predMap(length(predMap) + 1) = prey;
end
end
end
end

2 个评论

You probably want the Euclidean distance instead:
%change this
abs(newPred.x - newPrey.x)<v && abs(newPred.y - newPrey.y)<v
%to this
hypot(newPred.x - newPrey.x,newPred.y - newPrey.y)<v
Otherwise the prey will get eaten in a square are, not a circle.
It looks like your actual goal is to remove the prey animal from the database, can you confirm this? In that case you should loop through all the preys to see if any of them is close to the predator.
Yes, wow I can't believe I missed that. That is indeed my goal.

请先登录,再进行评论。

 采纳的回答

If my guesses are correct, the code below should be close to what you need.
%replace this
if abs(newPred.x - newPrey.x)<v && abs(newPred.y - newPrey.y)<v
delete??????
end
%with this
for p=numel(preyMap):-1:1%loop backwards
newPrey=preyMap(p);
if hypot(newPred.x - newPrey.x,newPred.y - newPrey.y)<v
preyMap(p)=[];%remove entry
end
end

5 个评论

I do get an error with dot indexing now and the simulation stops on day two.
It doesn't always stop on day two because of all of the random variables, but it always does at some point in the run. It seems to get stuck at newPrey.x whenever a prey gets eaten.
I have never worked with maps before, so I (wrongly) assumed you were using a struct array. The documentation describes you need to use the remove function to remove entries from a map, so probably something like this:
remove(preyMap,p)
It kind of works now, thanks! However, the coordinations are only integers now.
Because you are using a container you need to keep track of the keys you have removed. If you change to a struct array you wouldn't need to do that. Luckily, we can use the keys function.
v=2;%you forgot to define this predation range
% VARIABELEN
numDays = 50;
geboortekansPrey = 0.00;
geboortekansPred = 0.00;
minleeftijdPrey = 10;
minleeftijdPred = 10;
axis = 100;
W = 0:1:axis;
r = 2;
% MAPPEN MET INITIËLE DIEREN
predMap = containers.Map('KeyType', 'double', 'ValueType', 'any');
pred = struct('x', 1, 'y', 1, 'age', 25);
predMap(1) = pred;
preyMap = containers.Map('KeyType', 'double', 'ValueType', 'any');
prey = struct('x', 2, 'y', 2, 'age', 15);
preyMap(1) = prey;
prey = struct('x', 3, 'y', 3, 'age', 20);
preyMap(2) = prey;
% DAGEN
for t = 1:numDays
fprintf('\nday %d:\n',t);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PROOIDIEREN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('Prooidieren:\n');
for p = cell2mat(keys(preyMap))
newPrey = preyMap(p);
% COÖRDINATEN
d = rand * r;
rad = rand * 2 * pi;
newpreyx = newPrey.x + cos(rad) * d;
newpreyy = newPrey.y + sin(rad) * d;
while newpreyx<0 || newpreyx>axis || newpreyy<0 || newpreyy>axis
d = rand * r;
rad = rand * 2 * pi;
newpreyx = newPrey.x + cos(rad) * d;
newpreyy = newPrey.y + sin(rad) * d;
end
newPrey.x = newpreyx;
newPrey.y = newpreyy;
% LEEFTIJD
newPrey.age = newPrey.age + 1;
preyMap(p) = newPrey;
% WEERGAVE
fprintf('Leeftijd: %d\n', preyMap(p).age);
fprintf('Coördinaten: (%.2f, %.2f)\n', preyMap(p).x, preyMap(p).y);
% GEBOORTE
if preyMap(p).age > minleeftijdPrey
out=rand;
if out<geboortekansPrey
prey = struct('x', W(randi([1,numel(W)])), 'y', W(randi([1,numel(W)])), 'age', 0);
preyMap(length(preyMap) + 1) = prey;
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ROOFDIEREN
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fprintf('Roofdieren:\n');
for q = cell2mat(keys(predMap))
newPred = predMap(q);
% COÖRDINATEN
d = rand * r;
rad = rand * 2 * pi;
newpredx = newPred.x + cos(rad) * d;
newpredy = newPred.y + sin(rad) * d;
while newpredx<0 || newpredx>axis || newpredy<0 || newpredy>axis
d = rand * r;
rad = rand * 2 * pi;
newpredx = newPred.x + cos(rad) * d;
newpredy = newPred.y + sin(rad) * d;
end
newPred.x = newpredx;
newPred.y = newpredy;
% LEEFTIJD
newPred.age = newPred.age + 1;
% ETEN
for p = cell2mat(keys(preyMap))
newPrey=preyMap(p);
if hypot(newPred.x - newPrey.x,newPred.y - newPrey.y)<v
remove(preyMap,p);%remove entry
end
end
predMap(q) = newPred;
% WEERGAVE
fprintf('Leeftijd: %d\n', predMap(q).age);
fprintf('Coördinaten: (%.2f, %.2f)\n', predMap(q).x, predMap(q).y);
% GEBOORTE
if predMap(q).age > minleeftijdPred
out=rand;
if out<geboortekansPred
pred = struct('x', W(randi([1,numel(W)])), 'y', W(randi([1,numel(W)])), 'age', 0);
predMap(length(predMap) + 1) = prey;
end
end
end
end

请先登录,再进行评论。

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Software Development Tools 的更多信息

产品

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by