Machine Problem 3

Due Feb 22, on line

Part of the homework for CS:2820, Spring 2021
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Background

The first step in our epidemic model involved creating a population where each person was assigned to some role. The next step is to relate roles to the category of places associated with that role. Place names are not associated with individual places, but rather, with categories of places, where each place in a category can fulfil the same function relative to some role or roles.

place home 4.0 3.0 ;
place work 10.0 9.0 ;
place school 5.0 4.0 ;

Here, the declaration place home 4.0 3.0 declares home to be the name of a category of places. The numbers 4.0 3.0 describe the probability distribution of home sizes. When a new home is created for the model described by the above input, its size is drawn from a log-normal random distribution with a median size of 5.0 and a scatter of 4.0. The median must be greater than zero, and the scatter must not be negative.

Note that, later, places will have other attributes, such as infectivity, the probability of catching the disease as a function of how long a person is in that place and how many people in that place are infectious. For now, we'll ignore this.

This is not a statistics course, but it is useful to play with log-normal distributions a bit. A small Java program is provded that both demonstrates how to draw numbers from a log-normal distribution and allows you to play with such distributions by entering median and scatter values on the command line so that the program can generate a histogram showing the resulting distribution. Here is the output of that program for one run:

median 4.0, scatter 3.0
  0
  1XXXXXXXXX
  2XXXXXXXXXXXXXX
  3XXXXXXXXXXXXXXXXXXXXXXXXXX
  4XXXXXXXXXXXXXXXX
  5XXXXXXXXXX
  6XXXXXXX
  7XXXXXXX
  8XXX
  9XXX
 10XX
 11X
 12X
 13
 14
 15
 16
 17
 18
 19X

When do you draw a new size from this distribution? When a new home is created. Homes are created with a capacity drawn from the distribution, and so long as a home has capacity, new people are added to the home with capacity. A new home needs to be created only when the time comes to add a person to a home and all the existing homes are full.

So how do people get associated with places? By their role.

role worker 0.3
   home
   work ;

The above definiton adds to the material from MP2 by stipulating that each worker must be affiliated with two places, a home and a workplace. As in MP2, the necessary number of Person objects is created, but now, each of these objects is permanently affiliated with (in this case) two Place objects, a home place and a work place.

That affiliation does not imply that the person is currently in either place. We are not yet to the point of thinking about any time-related issues. Rather, this says that when the time comes that we think about the person's travel plans, the person will travel between the listed places. Roles may specify any number of places, although the number of places associated with any particular role is not likely to be big.

Later, we will add some kind of calendar to each place that indicates when the person in a particular role will travel to that place. Calendars themselves are going to be a bit messy because, eventually, we will need to deal with both daily and weekly cycles of activity.

An Example Input File

population 10 ;
place home 4.0 0.0 ;
place work 2.0 1.0 ;
place school 1.0 0.0 ;
role homemaker 0.3
   home ;
role worker 0.4
   home
   work ;
role student 0.3
   home
   school ;

In the above, everyon has a home, and each home has a capacity of exactly 4 people, so we expect 3 homes in the resulting model, but not all will be fully populated because 10 people cannot be evenly distributed between 4 homes.

There should end up being 3 schools, each with one student. The expected number of workplaces is two, but the number of workplaces is unpredictable because workplaces will be created with perhaps one worker and occasionally the capacity may be 4 or, with low probability, even more.

Assignment

Make a Java program that:

Note: If you look at the above sample output, you will see that there is something very unrealistic about the population. The problem is, people were crammed into homes and other places in the order they were created. The result is that there is too much correlation between categories of people and the places they relate to. All the homemakers ended up in the same home, most of the workers ended up in another home, and the students mostly live together. Our specification didn't address this issue, but obviously, later, we'll have to find a way to break this correlation!

Submission

On or before the end of Monday, Feb. 22, you must submit your program using the following shell command on the fastx machine:

~dwjones/submit xxxx Epidemic.java

Substitute your section number for xxxx above, but do not alter the text dwjones.

The program will confirm that you successfully submitted your solution with the message "submiter: succesfull submission of xxxx/HawkID" with xxxx replaced with your section number and HawkID replaced with your HawkID.

You may submit as many times as you want. The last successful submission is the one that will count. As such, it is a good idea to submit as soon as you have code that sort-of works, submit again when you have code that works the way you like, and perhaps submit again when you bring your code up to the highest standard of readability.

Grading

Code that executes correctly is worth half credit (2.5 out of 5 points). Expect demerits for the usual style issues in addition to the "on inspection" criteria given above:

Questions

A student asked: I don't understand the log-normal part. Is this required? Where to use it?

It is required!

Specifically, every time you need to create a place, for example, a home for some specific person, or a school for some specific student, you create that place with a capacity. The capacity of each specific place is set by drawing a random number from a log-normal distribution.

Any time you draw a random number, you are drawing it from some distribution. The Java class Random provides uniform distributions and normal distributions as built-in methods. We need a log-normal distribution.

The code in the log-normal demonstration program draws 100 numbers from such a distribution and then outputs a histogram of the frequency of these numbers. You do not need to do that, but you do need to draw numbers from the distribution, and the code provided shows how to do this!

A student asked: What is the relationship between place and role?

Each role may be associated with one or more places. If two different roles are associated with the same place, then people with those different roles may go to the same places. People in most roles have a home. Both students and teachers go to schools.

A student asked: How is the line of the input file called "place" related to the class Place?

There may be many objects of class Place. For example, the input data used for the example output above created 3 places of kind home, 2 places of kind work and 3 places of kind school. Class Place is for specific places that specific people go to. The lines of the input file marked "place" each name a category of place and assign a probability distribution to the sizes of the places in that category. It may well be that you need an additional Java class in your code for categories of places. You could call it CategoryOfPlace if you like verbose class names. A shorter name like PlaceKind might lead to code that ithat is easier to read.

A student asked: I'm having trouble figuring out when to use the log-normal probability distribution.

Consider the problem of creating a new student. When you create that student, the student must be associated with a home and a school. If there is no space in any home, you must build a new house. Otherwise, you put the student in space in an existing house. If there is no space in a school, you must build a new school. Otherwise, you put the student in an existing school. When you build a new house, you pick the size of the house (the number of beds) from the log-normal distribution for house sizes. When you build a new school, you pick the size of the school (the number of desks) from the log-normal distribution for school sizes. (Here, we don't distinguish between desks for students and desks for teachers. Our model is too crude to make that distinction.)

A student asked: Was there a typo in the example input file given here?

Unfortunately yes. As originally distributed, the entry for one role read

role student 0.3 ;
   home
   school ;

The semicolon on the first line was a mistake. There should be only one semicolon per role, at the end of the list of places associated with that role. The text in the assignment has been corrected to read as follows:

role student 0.3
   home
   school ;

A student asked: I got it to work with just one place per role, but I'm having trouble going beyond that. What should I do.

Only the most trivilal roles will have just one place per role. Nursing-home patients are a good example. All other roles will typically have multiple places. Since the number of places associated with a role is unknown, you will need some kind of elastic data structure to hold them. A linked list is a natural candidate.

Suppose that PlaceKind is the class used to hold descriptions of each kind of place, while Place is the class used for the actual places. One field of each Role object could be declared as an object of class LinkedList<PlaceKind>, and similarly, if PP is the class used to hold a discription of each actual place, each Person object would have a field of class LinkedList<Place>.

A student asked: Since we are printing out all the places for each person, so would class Place hold a list of Person objects, or would class Person hold a list of place objects.

This is a programming prolbem, so of course, both solutions can be made to work, but one of them is simpler than the other.

In database systems, people talk about this as a matter of inverting the relation. Each person is associated with a set of places, and each place is associated with a set of people. Given either one of these for the whole system, we can compute the other.

So which is easier. Consider: The reason you need the data structure for this particular problem is so you can go through the list of all people and print the associated places. That is easy if you have a link from each person to all the places they are associated with, but it is hard (but entirely possible) if you have to search some list of all places for some place associated with this person.

A student asked: Is it OK to nest all my classes inside class Epidemic?

There's no harm in it now, but it will be a problem later when we break our source file into multiple files.

The only real justificaiton for inner classes is if you refer to a variable in an outer class from within an inner class. There are good reasons to do so that we will discuss over the next weeks, but I can't see any need for nesting classes at this point.

The ability to nest classes was, by the way, an afterthought in the design of Java. Simula 67 supported nesting very well. In comparison, the way Java supports it is rather poor.

A student asked: Is it OK to require that all names of categories of places be defined before any roles mention those places?

It seems quite reasonable to require that each specific kind of place be defined before that place is mentioned in any role definition. This is less strict that requiring that all place categories be declared before any role is described, but it accomplishes the same thing.

A student asked: Do we need to support both fatal and non-fatal errors?

You need not support non-fatal errors, but later versions will be required to do so while conforming to the requirement that the progam only produce output if there were no errors in the input. This can be made to work by a small addition to class Errors that I will mention Monday (basically, just count the errors and make the program exit with an error indication if the count is nonzero after reading the whole input file).

A student asked: When do we need to do something with the log-normal distribution?

Think about the flow of information through the problem from the input file to the result:

  1. You begin with the population.

  2. The population combine with the numbers from all the roles lets you compute the number of people in each role. Only when you have this can you create the Person object for each one.

  3. Creating Person object for a person in some particular role requires that that Person be connected to some Place object for each kind of place associated with that person's role. Since no places exist until there is a demand for them, it is the creation of a person object that causes place creation, but only if there is no place of that kind availble to hold that person.

  4. To create or find an existing Place object to hold a person, you need to visit the place-kind information that was initially build from a "place" item in the input. That is the only location where you can find the probability distribution for place sizes, and it is the logical location to keep a record of any existing place of that kind that is not yet full. So creating a person must visit the place-kind information for each kind of place associated with that person's role.

A student asked: How do we give credit appropriately when we base our solutions to MP3 on your solution to MP2?

The answer is similar no matter whose solution you base yours on. First, in the overall header comments, indicate all authors involved in the file with notes indicating that further attributions are buried in the file:

// Epidemic.java
/* Eventually, this will be an epidemic simulator
 * author Douglas W. Jones -- see comments on classes and methods
 * author John Q. Student
 */

Second, on a class that is fully by someone else, me for example, say so and give your source:

/** Class to do something or another
 *  @author Douglas W. Jones -- from distributed solution to MP2
 */

If you lift a class and then modify it, say so, and if your modifications are confined to some section, say that too:

/** Another class that does this or that
 *  @author Douglas W. Jones -- from RoadNetwork.java Feb 19 version
 *  @author John Q. Student -- added methods X, Y and Z
 */

Finally, if some non-trivial method added to a class is entirely yours, add an @author entry to the Javadoc comment to that method saying so!