This programming assignment is the first of a series of assignments
centered around a common theme. The idea is to get some programming
practice in Java, while also improving programming skills
(for example: critical
thinking, problem solving, software engineering).
In this assignment, you will simulate a forest fire
using "trees" on a "landscape". Here, the landscape is
going to be 2-dimensional grid of cells, each of which
either contain a tree or not.
This rudimentary landscape is useful in
studying burn patterns, safety measures and the effects of
a "controlled burn".
For example, here is a 5 x 5 grid with 17 trees, represented
with ones and zeroes (1 = tree).
1 1 1 0 1
0 0 1 0 1
0 1 1 1 0
1 0 1 1 1
1 1 0 1 1
And here is a 3 x 3 grid with 5 trees:
1 1 1
0 0 0
0 1 1
The following "rules" determine the behavior of the system:
- The rows of an M x M grid are numbered 0,...,M-1. Thus,
row number 0 in the first example is:
1 1 1 0 1
Likewise, the columns are numbered 0,...,M-1 (from left to right).
Thus, in the above
5 x 5 example, Cell (2,3) contains a tree, but (3,1) does not.
- The neighbors
of a cell are the four cells to the north, south, east and west
of the cell. Thus, Cell (1,1) has neighbors (0,1), (2,1), (1,0)
and (1,2). Cells at the four corners have only two neighbors each
and cells on the boundary (but not at the corners) have three
neighbors each.
- When a tree catches fire, it ignites every tree in a neighboring
cell. An ignited tree does not ignite its non-neighbors.
- Now consider what happens when a particular tree is ignited.
The tree itself catches fire and ignites its neighbors, which in
turn ignite their neighbors, and so on. All these trees eventually
burn down. Eventually, the burning stops and we are left with
the stumps of a cluster. Thus, a cluster is
a collection of trees, such that any two trees in the cluster
are connected to each other via a string of neighboring trees.
Hence, in the example below
1 1 1
0 0 0
0 1 1
there are two clusters. The cluster
x x x
0 0 0
0 1 1
and the cluster
1 1 1
0 0 0
0 x x
It is clear that if any tree in a cluster is ignited, the entire cluster
will eventually burn.
- We will consider trees with different "burn" properties:
- There will be two types of trees. Let's call them "type-1"
and "type-2" trees.
- Type-1 trees are like the trees described so far: if
any neighboring tree catches fire, they catch fire.
- Type-2 trees are "sturdier". It requires two neighboring
trees to be on fire (simultaneously) for a type-2 tree to catch fire.
Your goal in this project is to identify all the Type-1 clusters
and to consider the effects of a controlled burn on both types.
This simulation that you will write is part of a long
tradition of simulating "macro" behaviors (for example:
a complete burn) that arise from local behavior of small units
(a burning tree ignites its neighbors).
This types of simulations are often called
agent or artificial society simulations.
Next, we will introduce the notion of "time-steps" in
simulating an actual burn:
- We will simulate a forest fire by changing the state of the
landscape at each step. This is similar to changing the
configuration of a chessboard with each move of a player.
Thus, prior to step 1 is the initial configuration. Then, some
trees are ignited. In step 2, we mark the ignited trees as
"burning" and ignite neighbors (according to the "ignite" rules).
In step 3, those that were burning are now considered burnt
(according to "burn rate" rules), and those that were ignited
are marked "burning".
- "Burn" rule for Type-1 trees: they burn completely in one
simulation step once they've started burning.
- "Burn" rule for Type-2 trees: they take two steps to burn
down. (In the first step, they are considered "burning").
- To help clarify what happens in each step, think of the steps
as taking 10 seconds (or whatever) each and presume that all igniting occurs
in a fraction of a second at the end of the 10-second period.
Then, before the first step (Step 1) the ignition pattern is
provided. These ignited trees will burn during Step 1, and thus
they can be considered "burning" during Step 1. Towards the end
of the 10-second Step 1 period, these burning trees ignite
neighbors. Those neighbors then burn in Step 2, etc. Now,
a type-2 tree that was burning in Step 1 will continue to burn
in Step 2.
- Your simulation will run until all trees that get ignited (at
any time) completely burn (as opposed to running the simulation for a fixed
number of steps). Thus, one tree can ignite another, then the
second burns, igniting a third, etc. Since there are a limited
number of trees, the burning cannot continue indefinitely, so the
simulation must end. Some trees that never get ignited, of course,
are left unburned.
Additional notes:
- Start with this template and place all
your code in the file Assign1.java.
You will also need the file UniformRandom.java in the same
directory - you can get this from the announcements section of
the homepage.
- Define and use a Tree class to
hold information about trees.
- Define and use a Landscape
class to hold information about the current status of the landscape.
- Define and use a Cell
class to hold information about an individual cell in the landscape. Make sure Landscape
is a 2D array of Cell's.
- For each object created, ensure that appropriate initialization
is performed in the object's constructor, and that you use
appropriate mutators and accessors.
- Each object should have a toString() method
for use in debugging.
- Since you will write a toString() method for Landscape,
the toString() method should
really write out the a snapshot of the landscape, such as:
1 1 1 0 1
0 0 1 0 1
0 1 1 2 0
X 0 2 1 X
X 1 0 X X
which shows some Type-1 trees, some Type-2 trees and some burned trees.
Examine the file Assign1.java
and observe the following:
- There is a method called createRandomForest
that will take in a landscape
(and its size, M) and
fill it with trees. This method also takes in a parameter called
fillDensity; generally, the higher the fillDensity
the higher the number of trees generated. There is also a parameter
for determining the approximate fraction of type-2 trees.
This method populates a 2D array of
int's each entry of which has the value
0 (no tree present), 1 (type-1 tree present)
or 2 (type-2 tree present).
You do not need to
understand how this method works, but you will need to use it
for estimation.
- The method processLandscapeData()
is given a landscape,
the size M and some information about an ignition-pattern.
This information is: (1) the number to trees to ignite
(simultaneously), getNumTreesToIgnite, and the locations of
the trees to ignite. The locations are specified by X and Y
coordinates. Thus, for example, if the "ignite" locations for a 5 x 5
landscape are (0,1), (1,3), (4,2), then numTreesToIgnite=3
igniteX[0]=0, igniteY[0]=1, igniteX[1]=1, igniteY[1]=3,
igniteX[2]=4, igniteY[2]=2.
- The "ignite" locations may have a type-1 tree, a type-2 tree
or no tree at all. You can think of these as locations where
lightning strikes. Thus, after these first ignitions, you be able to
simulate the effects in successive steps until all burning/ignited
complete their burn. (There may still be standing trees that never
got ignited, of course).
- Note that the initial ignite pattern will ignite each tree
in those initial ignite locations whether Type-1 or Type-2.
Thus, the "need 2 burning neighbors" condition does not apply to
the initially ignited trees.
- The method processLandscapeData()
itself doesn't do much
other than create an instance of Landscape
and call its
simulateForestFire() method.
- About Landscape:
- Clearly, Landscape is a
class (that you will write).
- Landscape has (at least) the methods
simulateForestFire(), getNumTreesBurned(),
getNumClusters() and a 2-parameter constructor, all of
which you will write.
- The real work of simulation occurs in the simulateForestFire()
method.
- Once the simulation is complete, the method
getNumTreesBurned() should return the number of trees that
burned.
- The method getNumClusters()
should return the number of clusters found of the given type. You only
need to make this work for Type-1 trees.
- Landscape should implement the standard
toString() method so that the statement
System.out.println (L);
prints the current snapshot.
- Important: You can add as many methods to the
class as you like, but do not change the signatures of
the methods given.
- Finally, once your code for processing a landscape is working,
you are to estimate, over a large number of random
landscapes, the average number of Type-1 clusters, and the number of trees
burned of each type.
That is, for a particular landscape size M,
if we were to generate many random forests, and if we were
to compute the number of clusters for each landscape,
what would be the average number of clusters over all the landscapes?
Deliverables and submission:
- The source code for program. You can write all your code in the
same file (Assign1.java)
or write each class in a separate file.
- You will estimate the following:
- Report the average number of Type-1 clusters. For this
part of the assignment, you'll need to ensure that only Type-1
trees burn, and that every type-1 cluster is lit.
- If your "ignite" pattern is to ignite all the trees
on the first row, what is the average number of trees of each type that
burn? You are to report this average number of burnt trees for the following
parameters:
- M=4, and each value of fillDensity in the
set {0.1, 0.3, 0.5, 0.7, 0.9}.
- M=8, and each value of fillDensity in the
set {0.1, 0.3, 0.5, 0.7, 0.9}.
Put your results (manually) in a plain text
file called results.txt in
your directory and make sure it's included in your jar-file.
- Use 1000 simulations to average over, for your averages.
- What did you do to ensure that your code is working correctly?
Desribe this in the results.txt file.
- Submit evidence that you thought about the design of your
program before you started coding.
- Your code will be graded
on both correctness and documentation.
- You will need time for experimentation, so plan on getting
your code working well before the due date.
- As usual, follow the submission
instructions.