One particular type of program that lends itself well to using objects is simulation programs. A simulation is a program that models some kind of process or system over time. Simulation programs are very important to many other disciplines.
Some examples of areas that use computer simulation:
Simulations are done by keeping track of several objects, and how they change over time. The objects can possibly interact with each other or outside influences.
As an example of how we could do a simulation on multiple objects, consider the problem of studying a disease outbreak. The general idea is we can keep track of a large number of virtual people, as they move about. Some people will start out sick, and can pass the disease to those they are near.
Below is a simple program which does just such a simulation. There are a number of parameters which control the simulation as it runs. They are grouped in a class so they can be changed in one place:
// a class which just contains some numbers grouped together
class SimulationParameters {
static final int POPULATION = 200;
static final int MOVE_AMOUNT = 2;
static final int HEAL_DAYS = 10;
static final int INITIAL_SICK = 10;
static final double INFECT_DISTANCE = 2.5;
}
To keep track of whether someone is sick or not, we can use an enumeration:
// represents whether a given person is healthy or sick
enum State {
HEALTHY,
INFECTED
};
We then can make a Person class for modeling one person in this simulation. They have variables which store their sate and position, and functions which modify them:
class Person {
// variables used in simulating the person
private State state;
private int days_til_healed;
private double x, y;
// construct a healthy person, randomly positioned in space
Person() {
state = State.HEALTHY;
Random generator = new Random();
x = generator.nextInt(100);
y = generator.nextInt(100);
}
// move the person randomly
void move() {
Random generator = new Random();
// getr a random number between 0 and 1
double val = generator.nextDouble();
// multiply by twice the move amount - this gets us a value between
// negative move amount, and positive move amount
val = val * 2.0 * SimulationParameters.MOVE_AMOUNT;
val = val - SimulationParameters.MOVE_AMOUNT;
// move in the x direction by this much
x += val;
// do the same thing for y
double val2 = generator.nextDouble();
val2 = val2 * 2.0 * SimulationParameters.MOVE_AMOUNT;
val2 = val2 - SimulationParameters.MOVE_AMOUNT;
y += val2;
// don't let them go off the edges
if (x > 100) {
x = 100;
}
if (y > 100) {
y = 100;
}
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
}
// called after each step in the simulation, if this person is sick,
// is it time for them to get better yet?
void checkHeal() {
if (days_til_healed == 0) {
state = State.HEALTHY;
} else {
days_til_healed--;
}
}
// set this person as infected
void setInfected() {
state = State.INFECTED;
days_til_healed = SimulationParameters.HEAL_DAYS;
}
// return the state of this person
boolean isInfected() {
return state == State.INFECTED;
}
// check if this person has been infected by another person
void checkInfected(Person others[]) {
// loop through each other person
for (int i = 0; i < SimulationParameters.POPULATION; i++) {
// find the euclidean distance between them
double distance = Math.sqrt((x - others[i].x) * (x - others[i].x)
+ (y - others[i].y) * (y - others[i].y));
// if they are too close
if (distance < SimulationParameters.INFECT_DISTANCE) {
// if they're sick and we are not, we are now sick too :(
if (state == State.HEALTHY && others[i].state == State.INFECTED) {
setInfected();
}
}
}
}
}
Once we have a class to keep track of an individual person, we can create an array of people, and loop through it, performing the simulation over time:
// the main class which runs the simulation
class DiseaseSimulation {
public static void main(String args[]) {
// make an array of people
Person people[] = new Person[SimulationParameters.POPULATION];
// actually create the people
for (int i = 0; i < SimulationParameters.POPULATION; i++) {
people[i] = new Person();
}
// set the first so many to be sick
for (int i = 0; i < SimulationParameters.INITIAL_SICK; i++) {
people[i].setInfected();
}
Scanner in = new Scanner(System.in);
// keep going until the user says no
boolean cont;
int day = 1;
do {
// go through each person
for (Person p : people) {
// move them
p.move();
// check if they are all better
p.checkHeal();
// check if they are sick
p.checkInfected(people);
}
// count how many people are sick
int sick = 0;
for (Person p : people) {
if (p.isInfected()) {
sick++;
}
}
// print stats
System.out.printf("After %d days, %d people are sick and %d people are well\n",
day, sick, SimulationParameters.POPULATION - sick);
// move to the next day
day++;
// check if we want to continue
System.out.print("Continut (y/n): ");
cont = in.next().charAt(0) == 'y';
} while (cont);
}
}
Some questions we could ask of this simulation:
Copyright © 2024 Ian Finlayson | Licensed under a Creative Commons BY-NC-SA 4.0 License.