-1

this question pertains to a video game I'm trying to code.

I'm trying to generate people that have characteristics such as age, sex, religion, income etc, such that each attribute is distributed among the people in a specific way. Currently I'm using a map, which stores objects (with specific integer keys corresponding to specific traits).

public class Person {
    Map<Integer, Object> personalAttributes;
}

I have another class which is a State.

public class State {
Person[] personArray = new Person[200];
//Instantiates a bunch of Persons and puts the into the array
}

However, I want the people to have 50/50 sex, Gaussian age distribution, and custom religion distribution.

This is important because I want to be able to poll them, and get responses based off of their different traits. How would I do this?

  • 1
    Any reason you are using a `Map` instead of an instance variable for each trait? Using a `Map` adds extra overhead to each object that will make each `Person` object bigger and slower than it would be instead with instance data that has setters and getters. – 4castle Jun 09 '16 at 18:07
  • What do you mean by "custom" distribution? Is this like a percentage value for each religion? – 4castle Jun 09 '16 at 18:25
  • How would you do this? Add random number generation to set the attributes of each `Person` in their constructor. – pjs Jun 09 '16 at 18:26
  • @4castle I had used an instance variable for each trait in my original idea; Maybe I will revert back to that. Custom = percentage value for each religion. – Dhanvanthri Natarajan Jun 09 '16 at 18:34

1 Answers1

0

The Random class will be very helpful here, as it provides a nextGaussian() method which returns a normal distribution of floating point numbers with mean 0 and stdev 1.0 which you can scale up and truncate as you wish to fit your max and min age.

For a 50/50 distribution, you could either just alternate between the 2 genders as you iterate, or you could use the Random class again with nextBoolean() to determine gender pseudo-randomly.

For the custom distribution, I'm assuming you want a certain percentage of the population to be in each religion. Just use the index number as you iterate to determine which religion they are in. For example, you could have Religion A have 10% with index 0 - 19, Religion B have 50% with index 20 - 119, and Religion C have 40% with index 120 - 199. (If you want the custom distribution to instead use probability, refer to this question)

All of this together might look like this:

Random rand = new Random();
Person[] people = new Person[200];

for (int i = 0; i < people.length; i++) {
    Person p = new Person();
    people[i] = p;

    // Sex
    p.setSex(rand.nextBoolean() ? "Male" : "Female");
    // p.setSex(i % 2 == 0 ? "Male" : "Female");

    // Age (normal distribution with min 0, max 100, and mean 50
    int age = (int)(rand.nextGaussian() * 50);
    while (Math.abs(age) > 50)
        age = (int)(rand.nextGaussian() * 50);
    p.setAge(age + 50);

    // Religion
    int maxA = (int) (people.length * .1),
        maxB = (int) (people.length * .5) + maxA;
    if (i < maxA)
        p.setReligion("A");
    else if (i < maxB)
        p.setReligion("B");
    else
        p.setReligion("C");
}

// probably shuffle at the end so that religions aren't contiguous

Ideone Test

Community
  • 1
  • 1
4castle
  • 32,613
  • 11
  • 69
  • 106