12 #include <boost/property_tree/xml_parser.hpp> 13 #include <boost/property_tree/ptree.hpp> 14 #include <trng/lcg64.hpp> 27 using uint =
unsigned int;
40 void generate(
const string& prefix);
44 void writeCities(
const string& target_cities);
47 void writePop(
const string& target_pop)
const;
50 void writeHouseholds(
const string& target_households)
const;
53 void writeClusters(
const string& target_clusters)
const;
56 void checkForValidXML()
const;
59 void makeHouseholds();
71 double getCityPopulation()
const;
74 double getVillagePopulation()
const;
89 vector<pair<GeoCoordinate, map<double, vector<uint>>>>
91 vector<pair<GeoCoordinate, map<double, vector<uint>>>> distance_map;
95 if (m_output) cerr <<
"Building distance map for the next cluster type [0%]";
98 uint total = m_cities.size() + m_villages.size();
100 for (
auto& city: m_cities) {
101 if (m_output) cerr <<
"\rBuilding distance map for the next cluster type [" << done / total <<
"%]";
104 double current_radius = radius;
105 uint used_clusters = 0;
106 vector<bool> clusters_used = vector<bool>(clusters.size(),
false);
108 distance_map.push_back(make_pair(city.m_coord, map<
double, vector<uint>>()));
110 while (used_clusters != clusters.size()) {
112 for (
uint i = 0; i < clusters.size(); ++i) {
113 if ((!clusters_used.at(i)) &&
114 calc.
getDistance(city.m_coord, clusters.at(i).m_coord) <= current_radius) {
115 distance_map.back().second[current_radius].push_back(i);
116 clusters_used.at(i) =
true;
121 current_radius *= factor;
128 for (
auto& village: m_villages) {
129 if (m_output) cerr <<
"\rBuilding distance map for the next cluster type [" << done / total <<
"%]";
132 double current_radius = radius;
133 uint used_clusters = 0;
134 vector<bool> clusters_used = vector<bool>(clusters.size(),
false);
136 distance_map.push_back(make_pair(village.m_coord, map<
double, vector<uint>>()));
138 while (used_clusters != clusters.size()) {
140 for (
uint i = 0; i < clusters.size(); ++i) {
141 if (!clusters_used.at(i) &&
142 calc.
getDistance(village.m_coord, clusters.at(i).m_coord) <= current_radius) {
143 distance_map.back().second[current_radius].push_back(i);
144 clusters_used.at(i) =
true;
149 current_radius *= factor;
155 if (m_output) cerr <<
"\rBuilding distance map for the next cluster type [100%]...\n";
163 vector<pair<GeoCoordinate, map<double, vector<uint>>>>
164 makeDistanceMap(
double radius,
double factor,
const vector<vector<T>>& clusters)
const {
165 vector<pair<GeoCoordinate, map<double, vector<uint>>>> distance_map;
169 for (
auto& city: m_cities) {
171 double current_radius = radius;
172 uint used_clusters = 0;
173 vector<bool> clusters_used = vector<bool>(clusters.size(),
false);
175 distance_map.push_back(make_pair(city.m_coord, map<
double, vector<uint>>()));
177 while (used_clusters != clusters.size()) {
179 for (
uint i = 0; i < clusters.size(); ++i) {
180 if ((!clusters_used.at(i)) &&
181 calc.
getDistance(city.m_coord, clusters.at(i).front().m_coord) <= current_radius) {
182 distance_map.back().second[current_radius].push_back(i);
183 clusters_used.at(i) =
true;
188 current_radius *= factor;
194 for (
auto& village: m_villages) {
196 double current_radius = radius;
197 uint used_clusters = 0;
198 vector<bool> clusters_used = vector<bool>(clusters.size(),
false);
200 distance_map.push_back(make_pair(village.m_coord, map<
double, vector<uint>>()));
202 while (used_clusters != clusters.size()) {
204 for (
uint i = 0; i < clusters.size(); ++i) {
205 if (!clusters_used.at(i) &&
206 calc.
getDistance(village.m_coord, clusters.at(i).front().m_coord) <= current_radius) {
207 distance_map.back().second[current_radius].push_back(i);
208 clusters_used.at(i) =
true;
213 current_radius *= factor;
227 for (
auto& coord_map_pair: distance_map) {
228 if (coord_map_pair.first == coordinate) {
231 for (
auto it = coord_map_pair.second.begin(); it != coord_map_pair.second.end(); ++it) {
232 if (it->first <= radius) {
233 result.insert(result.end(), it->second.begin(), it->second.end());
241 return vector<uint>();
245 void placeHouseholds();
252 ClusterType cluster_type,
bool add_location =
true) {
255 if (min_age == 0 && max_age == 0) {
256 people = m_people.size();
258 for (
uint age = min_age; age <= max_age; age++) {
259 people += m_age_distribution[age];
263 people = ceil(fraction * people);
265 uint needed_clusters = ceil(
double(people) / size);
266 uint city_village_size = getCityPopulation() + getVillagePopulation();
270 vector<double> fractions;
272 fractions.push_back(
double(city.m_max_size) /
double(city_village_size));
276 fractions.push_back(
double(village.m_max_size) /
double(city_village_size));
280 for (
uint i = 0; i < needed_clusters; i++) {
282 cerr <<
"\rPlacing " << cluster_name <<
" [" << min(
uint(
double(i) / m_households.size() * 100), 100U)
284 uint village_city_index = dist(m_rng);
286 if (village_city_index < m_cities.size()) {
290 new_cluster.
m_coord = m_cities.at(village_city_index).m_coord;
291 new_cluster.
m_id = m_next_id;
293 clusters.push_back(new_cluster);
296 m_locations[make_pair(cluster_type, new_cluster.
m_id)] = new_cluster.
m_coord;
302 new_cluster.
m_coord = m_villages.at(village_city_index - m_cities.size()).m_coord;
303 new_cluster.
m_id = m_next_id;
305 clusters.push_back(new_cluster);
308 m_locations[make_pair(cluster_type, new_cluster.
m_id)] = new_cluster.
m_coord;
312 if (m_output) cerr <<
"\rPlacing " << cluster_name <<
" [100%]...\n";
319 void makeUniversities();
322 void sortWorkplaces();
329 void makeCommunities();
336 for (
uint i = 0; i < clusters.size(); i++) {
337 if (calc.
getDistance(coord, clusters.at(i).m_coord) <= radius) {
345 void assignToSchools();
348 void assignToUniversities();
351 void removeFromUniMap(vector<pair<
GeoCoordinate, map<
double, vector<uint>>>>& distance_map,
uint index)
const;
355 bool removeFromMap(vector<pair<
GeoCoordinate, map<
double, vector<uint>>>>& distance_map,
uint index)
const;
362 void assignCloseStudent(
SimplePerson& person,
double start_radius,
363 vector<pair<
GeoCoordinate, map<
double, vector<uint>>>>& distance_map);
373 bool assignCloseEmployee(
SimplePerson& person,
double start_radius,
374 vector<pair<
GeoCoordinate, map<
double, vector<uint>>>>& distance_map);
377 void assignToCommunities(vector<pair<
GeoCoordinate, map<
double, vector<uint>>>>& distance_map,
378 vector<SimpleCluster>& clusters,
380 const string& name =
"");
vector< SimpleHousehold > m_households
All the people
vector< SimpleCity > m_cities
The households (a household is a vector of indices in the vector above)
U m_rng
The content of the xml file
vector< SimpleCluster > m_workplaces
The villages
vector< SimpleCluster > m_primary_communities
The workplaces
Usage is very simple, construct with a vector of probabilities, then use as a distribution from the s...
vector< SimplePerson > m_people
The total amount of people to be generated (according to the xml)
vector< vector< SimpleCluster > > m_mandatory_schools_clusters
TODO refactor this, it should be this structure from the beginning (see m_mandatory_schools) ...
Time Dependent Person DataType.
map< pair< ClusterType, uint >, GeoCoordinate > m_locations
The size of workplaces (histogram)
uint m_total
The random generator
vector< SimpleCluster > m_mandatory_schools
The secondary communities
util::GeoCoordinate m_coord
boost::property_tree::ptree m_props
map< uint, uint > m_age_distribution
The next id for the nex cluster/school/... ID's are supposed to be unique
bool m_output
The universities: One univ is a vector of clusters, ordering is the same as the cities they belong to...
vector< uint > getClustersWithinRange(double radius, const vector< pair< GeoCoordinate, map< double, vector< uint >>>> &distance_map, GeoCoordinate coordinate) const
Get the clusters that are within the range of a certain coordinate and radius (both given as an argum...
Definition of ClusterType.
vector< pair< GeoCoordinate, map< double, vector< uint > > > > makeDistanceMap(double radius, double factor, const vector< vector< T >> &clusters) const
Specialization of makeDistanceMap, except now the clusters aren't a vector of clusters anymore...
vector< vector< SimpleCluster > > m_optional_schools
Mandatory schools (Not divided in clusters!!!)
vector< SimpleCluster > m_villages
The cities
ClusterType
Enumerates the cluster types.
void placeClusters(uint size, uint min_age, uint max_age, double fraction, C &clusters, string cluster_name, ClusterType cluster_type, bool add_location=true)
Spreads the clusters of people with these constraints over the cities and villages size: the size of ...
double getDistance(const GeoCoordinate &coord1, const GeoCoordinate &coord2) const
static const GeoCoordCalculator & getInstance()
Singleton pattern.
vector< uint > getClusters(GeoCoordinate coord, double radius, const vector< T > &clusters) const
Get all clusters within a certain radius of the given point, choose those clusters from the given vec...
vector< SimpleCluster > m_secondary_communities
The primary communities
map< uint, uint > m_household_size
The age distribution (histogram)
uint m_next_id
The clusters of the mandatory schools, this should be refactored
map< uint, uint > m_work_size
The household size (histogram)
vector< pair< GeoCoordinate, map< double, vector< uint > > > > makeDistanceMap(double radius, double factor, const vector< T > &clusters) const
Precompute the distances between the locations of the clusters (given as an argument) and the distric...