1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use rand::Rng;
use rand_xorshift::XorShiftRng;
use geom::{Duration, Time};
use crate::{Activity, CensusPerson, Config, PersonType, Schedule};
impl CensusPerson {
pub fn generate_schedule(&self, _config: &Config, rng: &mut XorShiftRng) -> Schedule {
let person_type = if rng.gen_bool(0.5) {
PersonType::Student
} else {
PersonType::Worker
};
let mut plan = Vec::new();
let start_time;
match person_type {
PersonType::Student => {
start_time = rand_time(rng, hours(8), hours(11));
if rng.gen_bool(0.95) {
plan.push((Activity::Breakfast, minutes(30)));
}
plan.push((Activity::School, rand_duration(rng, hours(3), hours(6))));
if rng.gen_bool(0.3) {
plan.push((
Activity::Lunch,
rand_duration(rng, minutes(20), minutes(40)),
));
}
plan.push((Activity::School, rand_duration(rng, hours(2), hours(4))));
if rng.gen_bool(0.6) {
plan.push((Activity::Entertainment, hours(2)));
} else {
plan.push((Activity::Errands, rand_duration(rng, minutes(15), hours(1))));
}
plan.push((Activity::Home, hours(8)));
}
PersonType::Worker => {
start_time = rand_time(rng, hours(6), hours(9));
if rng.gen_bool(0.8) {
plan.push((Activity::Breakfast, minutes(15)));
}
plan.push((Activity::Work, rand_duration(rng, hours(4), hours(5))));
plan.push((
Activity::Lunch,
rand_duration(rng, minutes(20), minutes(40)),
));
plan.push((Activity::Work, hours(4)));
if rng.gen_bool(0.8) {
plan.push((Activity::Errands, rand_duration(rng, minutes(15), hours(1))));
}
plan.push((Activity::Home, hours(8)));
}
}
let mut schedule = Vec::new();
let mut now = start_time;
for (activity, duration) in plan {
schedule.push((now, activity));
now += rand_duration(rng, Duration::minutes(30), Duration::hours(1));
now += duration;
}
Schedule {
activities: schedule,
}
}
}
fn rand_duration(rng: &mut XorShiftRng, low: Duration, high: Duration) -> Duration {
assert!(high > low);
Duration::seconds(rng.gen_range(low.inner_seconds()..high.inner_seconds()))
}
fn rand_time(rng: &mut XorShiftRng, low: Duration, high: Duration) -> Time {
Time::START_OF_DAY + rand_duration(rng, low, high)
}
fn minutes(x: usize) -> Duration {
Duration::minutes(x)
}
fn hours(x: usize) -> Duration {
Duration::hours(x)
}