Agent-Based Simulations

The main purpose of this project is to give you an opportunity to use your linked list within the context of an agent-based simulation.

In this week's simulation, we will have Agents that are on a 2D landscape. They will have positions in a continuous (floating point) 2D space, rather than the grid from the Game of Life. Like in the Game of Life, the agents are active and will implement an updateState method.

For this simulation, we won't have the concept of a scale factor, or you can think of the scale factor as being 1 so that coordinates map to pixels. If your Landscape's size is 500 by 500, then the Agents' positions should be between 0 and 500.

The Agent-based simulations were inspired by Growing Artificial Societies by Epstein and Axtell, two of the first researchers to make use computational modeling to examine social science questions about self-organizing societies.


Tasks

Testing

As you proceed through this project, maintain testing files to exercise the functionality of your code that you have written. Use previous testing files provided to you as templates for the structure.

Wrapping up LinkedLists

  • Implement the Iterable interface

    To enable another program to loop through the list, implement the Iterable interface, which allows a programmer to use a foreach loop structure on our LinkedLists. First, change the class definition for LinkedList to specify that it implements the Iterable interface.

        public class LinkedList<T> implements Iterable<T>

    Then create an Iterator subclass that handles traversing the list. Create a new private class inside the LinkedList class with the following definition.

        private class LLIterator implements Iterator<T>

    Give the class one field, which is of type Node, and which will hold the next node to be provided during a traversal. Then implement the following methods in the class.

    Finally, add the function iterator public Iterator iterator() to the LinkedList class. It should return a new LLIterator with head passed to the constructor, shown as the following code:

        // Return a new LLIterator pointing to the head of the list
        public Iterator<T> iterator() {
        return new LLIterator( this.head );
        }

    The iterator method makes the class actually implement Iterable.

  • Adding a toArrayList method

    Add one final method that converts the LinkedList to an ArrayList with the items in the same order. It should have the signature: public ArrayList<T> toArrayList()

  • Test the LinkedList class

    Download the LLTest file and test the standard LinkedList functions. Compile and run the test code. Debug your code until it works.

  • Agent Class

    Create an abstract class called Agent. The simulations will require making two forms of agents with different updateState() methods. This is an ideal situation for using inheritance, which means starting with a base class: the Agent class.

    The Agent class needs fields to store its x and y position. Use type double for the agent's position.

    The Agent class should implement the following methods:

    SocialAgent

    Create a (non abstract) SocialAgent class. The first agent we will implement will ultimately move towards other agents, creating groups of agents. SocialAgent will extend the Agent class. More information about inheritance.

    Give the child class a boolean field, moved, which will indicate whether the agent moved during its last updateState. It should also have a field that specifies the radius R within which it considers another agent a neighbor.

    The new class will need to override the constructor, and draw methods:

    AntiSocialAgent

    Create an AntiSocialAgent class. As opposed to SocialAgents, AntiSocialAgents try to move away from groups of Agents. AntiSocialAgent will also extend the Agent class.

    Give the child class a boolean field, moved, which will indicate whether the agent moved during its last updateState. It should also have a field that specifies the radius R within which it considers another agent a neighbor.

    The new class will need to override the constructor, and draw methods:

    Landscape

    Create a class called Landscape. It serves the same purpose as the Landscape in the Game of Life simulation, but is different enough that you probably don't want to copy the old one and edit it. Start with a new file. The Landscape will need fields to store its width and height (as ints) and a LinkedList of Agents. Use your implementation of a linked list. The Landscape needs the following methods:

    Visualization

    Make it possible to visualize your Landscape. Download the LandscapeDisplay.java file. It is almost identical to last week.

    Test your visualization by running LandscapeDisplay as your main program. The main program adds 200 agents to the Landscape and then displays them.

    updateState( )

    Add a method to your SocialAgent class, public void updateState(Landscape scape). If there are less than 4 agents within its own radius from itself, it changes both its x and y coordinates by a random value between -10 and 10. Make sure that it stays within the boundary of the window!

    To your AntiSocialAgent class, add an analagous method that would move the Agent if there is more than 1 neighbor within its radius.

    As you code this function, if the (Anti/)SocialAgent moves, set the moved field to true, otherwise set it to false.

    updateAgents( )

    Add a method to your Landscape class, public void updateAgents(). The method should update the state of each agent, in whatever order you'd like.

    SocialAgentSimulation

    Create an AgentSimulation class. It should be modeled after the LifeSimulation class. It would be best to control the Landscape size and the number of agents from the command line, but it is acceptable to hard-code them. Generate and randomly place N agents (N = 200 is reasonable) on the Landscape. Then loop over the time steps, calling updateAgents, repaint, and Thread.sleep as in LifeSimulation. Use a good size radius, such as 15-25, to start your simulation. Do your agents clump together?

      Required simulation image set

    1. Include in your report a picture of the end of the simulation, noting the radius of sensitivity used.
    2. Include in your report a second picture of the end of a simulation that uses a radius that is twice as big as the first case. Note any differences.

    Include a screen shot of the end of each simluation in your report.


    Extensions

    The following are some suggested extensions. You should feel free to pursue your own custom extensions to your project that you find interesting. Please clearly identify your extensions in your report. In your code, make sure the baseline simulations run properly. Making a separate sub-folder for major extensions is recommended.

    1. Try creating other agent types that implement different rule sets. Be intentional about your agent design.
    2. Instead of moving randomly, have your agent move towards other agents, or possibly towards some and away from others.
    3. Experiment with the effects of modifying some of the update rules. These should be compare and contrast. Try to avoid comparing simulations where more than one thing has been changed.

    Report

    Your intended audience for your report are your peers not in the class, but who have taken a CS course. Your report should explain the core CS concept used, present the results of your program, and discuss the meaning of the results: what did you discover and does it make sense?

    Your project report should contain the following elements. Please include a header for each section.

    Handin

    Here's a checklist of everything you should do when you are finished with a project and are ready to turn it in.

    + Create a report and export to pdf


    + Organize your project folder


    + Submit your project on Google Drive