java面向对象解决实际问题【母牛生产问题】
程序员文章站
2022-07-12 17:07:54
...
问题: 已知一只母牛4岁开始生产(人工受孕),12岁停止生产,产下的母牛概率为50%,每只母牛每年只生一只牛, 生下来的牛视为0岁。15岁送入屠宰场,现有一只母牛(0岁),请问25年后有多少只牛?
- 使用程序进行模拟此场景,计算25年后牛数量的期望值(平均值)
- 使用面向对象的思想去处理问题,会变得更加清晰明了
- 问题分析:
- 核心对象: 牛
- 核心属性: 性别(影响是否可生育),年龄(影响是否可生育,是否能继续存活)
- 核心行为: 成长(随时间流逝牛会长大,影响其年龄),生育(产出新牛)
- 根据上述分析编写牛类
public class Niu {
/**
* 性别 1==>母牛 0==>公牛
*/
private int sex;
/**
* 年龄 生下来0岁,4岁开始生牛,12岁停止生产,15岁送屠宰场
*/
private int age;
Niu(int sex) {
this.sex = sex;
// 一只新生牛的初始化岁数
this.age = 0;
}
public void grow() {
this.age = this.age + 1;
}
public void produce(List<Niu> list) {
if (sex != 1 || age < 4 || age > 11) {
// 公牛不会生产 年龄限制不能生产
return;
}
// 母牛开始生产了 生产的性别随机使用ThreadLocalRandom随机生成 0公牛 1母牛
Niu newNiu = new Niu(ThreadLocalRandom.current().nextInt(2));
// 将牛放入家
list.add(newNiu);
}
// 省略getter方法
}
- 程序模拟分析
- 开始时牛场只有一只母牛
- 时间经过一年,所有的牛都会成长1岁
- 部分满足条件的牛会被屠宰,部分满足条件的牛会进行生育
- 25年后,模拟结束
- 根据上述分析,编写模拟程序
public class MuNiuProblem {
public static void main(String[] args) {
long start = System.currentTimeMillis();
MuNiuProblem problem = new MuNiuProblem();
// 展示每次模拟的详情记录
boolean logEnable = false;
// 模拟次数
int simulate = 1000000;
int max = -1;
int min = -1;
int sum = 0;
// 开始模拟
for (int i = 0; i < simulate; i++) {
// 执行一次模拟,获取25年后牛的数量
int temp = problem.answer(logEnable);
// 累加到sum总
sum += temp;
// 初始化max min
if (i == 0) {
max = min = temp;
continue;
} else if ((i + 1) % 100000 == 0) {
System.out.println("模拟进行中,已模拟" + (i + 1) + "次");
}
// 更新 max min
max = max < temp ? temp : max;
min = min > temp ? temp : min;
}
// 输出模拟结果
long end = System.currentTimeMillis();
System.out.printf("%d次模拟用时%d s\r\n", simulate, (end - start) / 1000);
System.out.println(simulate + "次模拟最大值" + max);
System.out.println(simulate + "次模拟最小值" + min);
System.out.println(simulate + "次模拟平均值" + sum*1.0 / simulate);
}
private int answer(boolean logEnable) {
// 初始化牛场
List<Niu> list = new ArrayList<>();
// 初始化母牛
Niu firstNiu = new Niu(1);
list.add(firstNiu);
// 25年光阴 每次循环过去了一年
for (int i = 0; i < 25; i++) {
// 所有的牛都增长了1岁,然后过滤年满15岁的牛 已送入屠宰场
list.forEach(Niu::grow);
list.removeIf(n -> n.getAge() > 14);
// 新生牛的家
ArrayList<Niu> home = new ArrayList<>();
for (Niu niu : list) {
niu.produce(home);
}
list.addAll(home);
if (logEnable) {
showState(list, i + 1);
}
}
return list.size();
}
/**
* 输出详情记录
*/
private static void showState(List<Niu> list, int year) {
int count1 = 0;
int count2 = 0;
for (Niu niu : list) {
if (niu.getSex() == 0) {
count1++;
} else {
count2++;
}
}
System.out.printf("%d年后一共有牛%d只,其中母牛%d只,公牛%d只\r\n", year, list.size(), count2, count1);
}
}
- 通过程序模拟得出结果,25年后剩下牛数量的期望约为230只
下一篇: 一些提问