Adding a digestion timer, in a predation model in Netlogo - timer

I am building a coastal ecosystem where the starfish is the top predator and predates on all other 6 species.
I am trying to add a timer maybe 15 ticks whenever the predator feeds on a prey.
This is the code:
to move-starfish
ask starfish [ right random 360
forward starfish-speed set energy energy - 0.5 ]
ask starfish [predate]
end
to predate
let prey0 one-of mussels-here
if prey0 != nobody
[ask prey0 [die] set energy energy + energy-gain-from-mussels ]
let prey1 one-of thais-here
if prey1 != nobody
[ask prey1 [die] set energy energy + energy-gain-from-thais ]
let prey2 one-of limpets-here
if prey2 != nobody
[ask prey2 [die] set energy energy + energy-gain-from-limpets ]
let prey3 one-of mitella-here
if prey3 != nobody
[ask prey3 [die] set energy energy + energy-gain-from-balanus ]
let prey4 one-of balanus-here
if prey4 != nobody
[ask prey4 [die] set energy energy + energy-gain-from-balanus ]
let prey5 one-of chitons-here
if prey5 != nobody
[ask prey5 [die] set energy energy + energy-gain-from-chitons ]
end
I just pasted the parts of the code that are of interest.
I would also, if possible, want to know if instead of energy-gain-from-(mussels) which is a slider I could get the energy the prey had at that time added to the predator.
This is for some University work.

Since you've called it a digestion timer, I gather you don't want the starfish to do anything for 15 ticks after it eats. If this is what you want, add a variable (say digestion) for the starfish and set it to 15 when it eats. In your go statement, ask starfish with [digestion > 0] [set digestion digestion - 1] and change your move starfish to ask starfish with [digestion > 0] [...].
for future reference, ask a separate question for separate problems. But what you want is something like set energy energy + [energy] of prey before asking the prey to die.

Related

Netlogo: How can I set timer counting for multiple turtles at once?

How can I set timer counting for multiple turtles at once? Below is the sample syntax. With this syntax, if two turtles are present, timer counting will be cumulatively counted by 2 for each tick. Example: 2, 4, 6, 8, ..., another example: If 3 turtles are present, 3, 6, 9, ..., cumulative counting is done for each tick. The decrement timer also has the same problem. In this model, a turtle infinitely born at the origin patch (0 0), and after a certain period of time, the turtles die one by one. This problem occurred even if there were multiple patches, too. I probably need your advice. Thank you.
ask (turtles-on patch 0 0)
[
set count-up count-up + 1
]
I think you are confused about the difference between a global variable and a turtle owned variable. If you have multiple turtles being created at different times, then you probably want each to have its own timer (so that the value can be different for different turtles). If all you want is a global variable to increase or decrease each tick, then don't put it in an ask statement. Just say something like 'set counter counter + 1`.
Here is a complete model that should help you to understand what's going on in your code.
globals [num-turtles counter ave-count-up]
turtles-own [count-up]
to setup
clear-all
set num-turtles 5
reset-ticks
end
to go
set counter counter + 1
if count turtles < num-turtles
[ ask patch 0 0
[ sprout 1
[ set count-up 0 ]
]
]
ask (turtles-on patch 0 0)
[ set count-up count-up + 1
show count-up
]
type "Current value of counter is " print counter
type "Number of turtles: " print count turtles
type "Total of all turtle counters: " print sum [count-up] of turtles
set ave-count-up mean [count-up] of turtles
tick
end

Infinite loop in Modified Value Iteration(MDP GridWorld)

consider a simple GridWorld 3x4 with reward -0.04
[ ][ ][ ][+1]
[ ][W][ ][-1]
[ ][ ][ ][ ]
where W is a wall, +1/-1 are terminal states. An agent can move in any direction, but only 80% of the times he succeeds in going to the planned direction, 10% he goes right (relative to direction), 10% left.
In Policy Iteration algorithm, we first generate a random policy, let's say this policy gets generated:
[L][L][L][+1]
[L][W][L][-1]
[L][L][L][L ]
where L means left.
Now we run Modified value iteration algorithm until the values at neighbouring iterations don't differ much.
We initialize values at 0 (except for terminals states)
[0][0][0][+1]
[0][W][0][-1]
[0][0][0][0 ]
But here's what I don't get:
Since we use the formula 0.8*previousValueFromForwardState + 0.1*previousValueFromLeftState + 0.1*previousValueFromRightState + Reward to fill new states, that pretty much means that whatever is behind the policy direction at state won't change the value in that cell. Since only terminal states +1 and -1 can get the value iteration going and they get always ignored,
wouldn't that just create an infinite loop?
With each iteration, we would always be getting multiples of 0.04, the differences between iterations will always be constant (except for lower right corner, but it won't influence anything...)

Netlogo How do I export the amount of increment counter number with turtle ID and ticks data?

How do I export the amount of increment counter number with turtle ID and ticks data? The following sample program is a part of an increment counter that activates the increment counter when the turtle speed reaches 0 and continues to operate until the turtle dies. The purpose is to take the waiting time of the turtle.
Thank you for your cooperation best regards.
ask turtles [ ;;counter for counting the waiting time
if speed = 0 [
set counter counter + 1
]
]

Creating a 3D plot in Matlab

I want to create a 3D plot of the final fraction of grass covered on the Earth (=in 2 billion years from now) (=A) as a function of a varying death rate of grass (=D) and the growth rate of grass (=G).
The final value of A (at 2 billion years away from now) can be calculated using a loop with the following discritised equation:
A(t+dt) = A(t)*((1-A(t))*G-D)*dt + A(t)
%Define variables and arrays
D=0.1; %constant value
G=0.4; %constant value
A=0.001; %initial value of A at t=0
t=0;
dt=10E6;
startloop=1; %define number of iterations
endloop=200;
timevector=zeros(1,endloop); %create vector with 0
grassvector=zeros(1,endloop);
%Define the loop
for t=startloop:endloop
A=A.*((((1-A).*G)-D)) + A;
grassvector(t)=A;
timevector(t)=t*dt;
end
Now i'm stuck on how to create a 3D plot of this final value of A as a function of a varying G and D. I got this but after a few trials, it keeps giving errors:
%(1) Create array of values for G and D varying between 0 and 1
A=0.001;
G=[0.005:0.005:1]; %Vary from 0.005 to 1 in steps of 0.005
D=[0.005:0.005:1]; %Vary from 0.005 to 1 in steps of 0.005
%(2) Meshgrid both variables = all possible combinations in a matrix
[Ggrid,Dgrid]=meshgrid(G,D);
%(3) Calculate the final grass fraction with varying G and D
D=0.1;
G=0.4;
A=0.001;
t=0;
dt=10E6;
startloop=1; %define number of iterations
endloop=200;
timevector=zeros(1,endloop); %create vector with 0
grassvector=zeros(1,endloop);
%Define the loop
for t=startloop:endloop
A=A.*((((1-A).*Ggrid)-Dgrid)) + A;
grassvector(t)=A;
timevector(t)=t*dt;
end
%(4) mesh together with D and G
...??
Can someone help? Thanks!
Your code is wrong, as grassvector(t)=A; can not be executed, as the sizes are not consistent. However, I think you may want to do:
grassvector=zeros([size(Ggrid),endloop]);
and in the loop:
grassvector(:,:,t)=A;
Also, while completely unnecesary computationally, you may want to initialize A to A=0.001*ones(size(Dgrid)), as it makes more sense logically.
Anyways: this is how you can plot it in the end:
surf(Ggrid,Dgrid,A,'LineStyle','none');
xlabel('growth rate ')
ylabel('death rate ')
zlabel('grass')
colorbar
gives:
But, as I was actually interested in your research, I decided to make a couple of plots to see how fast the grass will grow and stuff. Here is some nice plotting code. You can modify different stuff here to be able to change the appearance of it. I use custom colormaps, so if it doesn't work, delete the colormap(viridis()) line. If you like the colormap, visit this.
fh=figure();
filename='grass.gif';
for t=startloop:endloop
clf
hold on
surf(Ggrid,Dgrid,grassvector(:,:,t),'LineStyle','none');
[c,h]=contour3(Ggrid,Dgrid,grassvector(:,:,t)+0.05,[0:0.1:1],'LineColor',[153,0,18]/255,'LineWidth',2);
clabel(c,h);
xlabel('growth rate ')
ylabel('death rate ')
zlabel('grass')
title(['Years passed: ' num2str(t*dt/1000000) ' million'])
colormap(viridis())
axis([0 1 0 1 0 1])
grid on
view(-120,40);
frame = getframe(fh);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if t == 1;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append','DelayTime',0.1);
end
end
Results:

Fastest way to generate next move in TIC TAC TOE game

In a X's and 0's game (i.e. TIC TAC TOE(3X3)) if you write a program for this give a fast way to generate the moves by the computer. I mean this should be the fastest way possible.
All I could think of at that time is to store all the board configurations in a hash so that getting best position of move is a O(1) operation.
Each board square can be either 0,1, or 2.
0 represents empty square. 1 represents a X & 2 represents 0.
So every square can be filled with either of the three. There are approx 3^9 board configurations.
In simple, we need a hash of size 3^9. For hashing,we can go for base 3 representation. Means each number in base 3 will be 9 digits long each digit corresponding to each square.
To search in hash, we need to find the decimal representation of this 9 digit number.
Now, each square can be associated with row number & column number. In order to identify each square uniquely, we can again make use of base 3 representation.
say SQ[1][2] will be 12 in base 3 which is equivalent to 5 in decimal.
Thus, we have effectively designed an algorithm which is fast enough to calculate the next move in O(1).
But, the interviewer insisted in reducing the space complexity as DOS system doesn't have that much amount of memory.
How can we reduce the space complexity with no change in time complexity?
Please help me so that I do not miss such type of questions in the future.
For a small game like this, a different way of going about this is to pre-compute and store the potential game tree in a table.
Looking first at the situation where the human starts, she obvious has 9 different start positions. A game-play table would contain 9 entry points, then, each pointing to the correct response - you could use the guidelines outlined in this question to calculate the responses - as well as the next level table of human responses. This time there are only 7 possible responses. For the next level there'll be 5, then 3, then just 1. In total, there will be 9 * 7 * 5 * 3 * 1 = 945 entries in the table, but that can be compressed by realizing symmetries, i.e. rotations and flipped colors.
Of course, the situation where the computer starts is similar in principle but the table is actually smaller because the computer will probably want to start by playing the middle piece - or at least avoid certain spots.
There are not 3^9 different board configurations. Just as tomdemuyt says, there are 9! different board configurations, i.e., 9 choices at first, 8 choices next, 7 choices after that, and so on.
Also, we can further reduce the space complexity by accounting for symmetry. For example, for the first move, placing an X in [0,0] is the same as placing it in [0,2], [2,0], and [2,2]. I believe this reduces 9! to 9!/4
We can even reduce that by accounting for which board configurations were winning before the final move (the 9th move). I don't know the number, but a detailed explanation can be found on the Stack Overflow cousin http://en.wikipedia.org/wiki/Tic-tac-toe
The assumption of 3^9 is wrong. This would include for example a board that only has X which is impossible as both players place each turn an X or an O.
My initial thought was that there are (9*8*7*6*5*4*3*2) * 2 possibilities.
First player has 9 choices, second player has 8 choices, first player has 7 etc.
I put * 2 because you might have different best moves depending who starts.
Now 3^9 is 19863 and 9! is 362880, so clearly this is not the superior solution, a lot of 'different scenarios' actually will end up looking exactly the same. Still, the base idea that many of the 19863 board setups are invalid remain.
This piece of code which probably could be replaced by a simple formula tells me that this is the count of positions you want to have a move for.
<script>
a = permuteString( "X........" ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XO......." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOX......" ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXO....." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXOX...." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXOXO..." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
a = permuteString( "XOXOXOX.." ); document.write( Object.keys(a).length + "<br>" );console.log( a );
//Subset of the Array.prototype.slice() functionality for a string
function spliceString( s , i )
{
var a = s.split("");
a.splice( i , 1 );
return a.join("");
}
//Permute the possibilities, throw away equivalencies
function permuteString( s )
{
//Holds result
var result = {};
//Sanity
if( s.length < 2 ) return [];
//The atomic case, if AB is given return { AB : true , BA : true }
if( s.length == 2 )
{
result[s] = true;
result[s.charAt(1)+s.charAt(0)] = true;
return result;
}
//Enumerate
for( var head = 0 ; head < s.length ; head++ )
{
var o = permuteString( spliceString( s , head ) );
for ( key in o )
result[ s.charAt( head ) + key ] = true;
}
return result;
}
</script>
This gives the following numbers:
1st move : 9
2nd move : 72
3rd move : 252
4th move : 756
5th move : 1260
6th move : 1680
7th move : 1260
So in total 5289 moves, this is without even checking for already finished games or symmetry.
These numbers allow you to lookup a move through an array, you can generate this array yourself by looping over all possible games.
T.
The game of Tic Tac Toe is sufficiently simple that optimal algorithm may be implemented by a machine built from Tinker Toys (a brand of sticks and fasteners). Since the level of hardware complexity encapsulated by such a construction is below that of a typical 1970's microprocessor, the time required to find out what moves have been made would in most cases exceed the time required to figure out the next move. Probably the simplest approach would be have a table which, given the presence or absence of markers of a given player (2^9, or 512 entries), would indicate what squares would turn two-in-a-rows into three-in-a-rows. Start by doing a lookup with the pieces owned by the player on move; if any square which would complete a three-in-a-row is not taken by the opponent, take it. Otherwise look up the opponent's combination of pieces; any square it turns up that isn't already occupied must be taken. Otherwise, if the center is available, take it; if only the center is taken, take a corner. Otherwise take an edge.
It might be more interesting to open up your question to 4x4x4 Tic Tac Toe, since that represents a sufficient level of complexity that 1970's-era computer implementations would often take many seconds per move. While today's computers are thousands of times faster than e.g. the Atari 2600, the level of computation at least gets beyond trivial.
If one extends the game to 4x4x4, there will be many possibilities for trading off speed, RAM, and code space. Unlike the original game which has 8 winning lines, the 4x4x4 version has (IIRC) 76. If one keeps track of each line as being in one of 8 states [ten if one counts wins], and for each vacant square one keeps track of how many of the winning lines that pass through it are in what states, it should be possible to formulate some pretty fast heuristics based upon that information. It would probably be necessary to use an exhaustive search algorithm to ensure that heuristics would in fact win, but once the heuristics were validated they should be able to run much faster than would an exhaustive search.

Resources