Notes on Lab #10

For this lab, you will implement a "Movement of Ants" cellular automaton in Matlab, by writing the functions to turn and move the ants and change the concentration of pheromone.

Getting Started

As in the previous lab, download and unzip this file containing the generic CA code and this file containing the code specific to the ants problem. Then copy the generic code into the lab10 folder. These folders also conatins some "utility" functions that will be helpful in completing the lab: Like last time, open the folder where you extracted the zip file, but this time click on the icon for the turn file. This will launch Matlab and open the turn file for you.

Like last time, all the code you need for this is at various places in the lecture notes Before you start working, though, you should type

    >> ca(10)

to launch the simulation, with the ants represented as little arrows and the pheromones as gray levels in a single horizontal strip. If you try to Go or Step, nothing will happen, because the turn, move, and pher functions are incomplete. We will fix these in the next steps.

Updating the Grid with Random Turns

Updating the grid is obviously more difficult here than for the spread-of-fire problem. As is often the case in programming, it is easiest to start small with something you can see immediately, then work your way up to the full implementation. For example, it would be nice to start out by watching the ants change direction somehow, without having to consider the pheromone. So your first version of turn might just do this:
  1. Create a grid containing a random number between 1 and 4 at all locations.

  2. Create the new ants grid by copying the random grid from the previous step at the locations where the old ants grid is greater than zero. It is easier to start by making this new grid all zeros, then filling it in at the appropriate locations.

You can tell when you've got this step working by clicking the Step button. Your ants should stay in place but turn in a random direction.

Turning Toward the Pheromone

Now that you've got the ants dancing in place, modify the turn function to make them turn in the direction of the pheromone. The idea will be to keep the code that turns all ants randomly, and then add some code to turn the ants next to the pheromone in the right direction.

To keep things easy, use the seed feature (optional third input) to the program to get a situation in which one or more ants are consistently on or adjacent to the pheromone strip (try ca(10,0), ca(10,1), ca(10,2), etc., until you get something useful). Making the ants turn in the right direction involves three steps:
  1. Finding the amount of pheromone in each direction.

  2. Finding where each direction has more pheromones than the others.

  3. Turning ants in those locations in the proper direction.
For example, to find the amount of pheromone to the north of each grid cell, you can do

    Npher = north(oldphergrid);

then repeat this with the other three directions. Then you can compare each direction with the other three to see where it's the "winner" in terms of pheromone strength:

    Nwins = winner(Npher, Spher, Epher, Wpher);

then repeat this with the other three directions. Finally, you want to turn an ant in a location in the proper direction:

    newantgrid(newantgrid & ewins) = E; % E = 1, N=2, W=3, S=4

where newantgrid is the grid of randomly-turned ants from the previous step. Repeat for the other three directions. Now when you run the simulation you should see most of the ants turn in a random direction, but the ones near the pheromone strip turning toward it, and up the gradient.


Now that the ants are pointed in the right direction (or just a random direction), you're ready to move them by modifying the move function. Recall that there is no true motion in a cellular automaton; instead, we replace the item in a cell with an item in an adjacent cell. For example, to move the entire grid north by one cell, we would replace it by its neighbors from the south:

    newantgrid = south(oldantgrid);

This would be a reasonable "first approximation" model to the actual movement, so go ahead and try it if you like. Of course, we don't want to move all the ants in a single direction; we want to move each ant in the direction that it's pointing. As with the previous steps, it will simplify things to deal with one direction at a time. We can isolate the cells containing ants pointing in a given direction by making all other cells contain zero; then we make a shifted copy of these isolated ants to "move" them. To isolate the ants pointing in a given direction, we exploit the fact that in Matlab (as in many other programming languages) a yes/no distinction is encoded by 1 (yes) and 0 (no). For example to get a north-shifted copy of the north facing ants we can do:

    Nants = south(N*(newantgrid==N)); % north-shifted ants come from the south

We do the same for the other three directions. Finally, we put all four shifted copies together, prohbiting each copy from contributing to a position already occupied (simple collision avoidance):

    newantgrid = zeros(n);
    newantgrid = newantgrid + Nants .* ~newantgrid;

The .* performs element-by-element multiplcation of two matrices (grids), and the ~ turns every zero element of a grid into a 1 and every non-zero element into a 0; hence, it "masks out" the places where newantgrid already has a non-zero value, preventing us from changing them. Of course, you should add three more lines of code for the remaining three directions.

Changing the Pheromone Concentration

Recall the three rules for changing pheromone concentration:
  1. If there's no ant in a cell, the pheromone decreases by 1 at each time step, with a minimum value of 0.

  2. If an ant leaves a cell, the amount of pheromone increases by 1 (ant deposits pheromone).

  3. So long as there is an ant in a cell, the amount of pheromone in the cell stays constant.
Think about how to modify the pher function to implement each of these, and if you get stuck, we'll work on them together. To prevent the pheromone concentration from dropping below zero, you can do this:

    newphergrid = max(newphergrid, 0);

Because we're using a single digit (0-9) to represent pheromone concentration, we'll also need to cap the amount of pheromone at 9. I'll leave it to you to figure this out, based on the line of code above.

Finishing Up

When you're done, zip up and turn in your lab10 folder, also containing your writeup describing (in ordinary language) what you see as you run the simulation. If you have time left over, try implementing one of the additional projects at the end of Module 11.3. For example, you could another strip of pheromone gradient to the initial grid, or you could compensate for the ants lost to collisions by introducing new ants into the cells not currently occupied, with some probability.