2022-12-01 14:36:33 -08:00
|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <algorithm>
|
2022-12-01 18:35:27 -08:00
|
|
|
#include <string>
|
2022-12-01 14:36:33 -08:00
|
|
|
|
|
|
|
#include "util.hpp"
|
|
|
|
#include "population.hpp"
|
|
|
|
#include "econ.hpp"
|
|
|
|
|
|
|
|
struct PopSimpleResult {
|
|
|
|
std::vector<int> ages;
|
|
|
|
std::vector<int> balances;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum EstateMode {
|
|
|
|
EVEN_REDIST,
|
|
|
|
INHERITANCE
|
|
|
|
};
|
|
|
|
|
|
|
|
PopSimpleResult pop_simple(
|
2022-12-01 18:35:27 -08:00
|
|
|
int duration,
|
|
|
|
int max_age,
|
|
|
|
int init_balance_each,
|
|
|
|
int starting_balance_new,
|
2022-12-01 14:36:33 -08:00
|
|
|
|
|
|
|
// logistic function params
|
2022-12-01 18:35:27 -08:00
|
|
|
int N_o,
|
|
|
|
int N_f,
|
|
|
|
float k,
|
2022-12-01 14:36:33 -08:00
|
|
|
|
|
|
|
// estate mode
|
2022-12-01 18:35:27 -08:00
|
|
|
EstateMode estate_mode
|
2022-12-01 14:36:33 -08:00
|
|
|
) {
|
|
|
|
|
|
|
|
std::vector<int> ages;
|
|
|
|
std::vector<int> balances;
|
|
|
|
ages.assign(N_o, 1);
|
|
|
|
balances.assign(N_o, init_balance_each);
|
|
|
|
|
|
|
|
// Changed/used only if emode=redist
|
|
|
|
int redist_total = 0;
|
|
|
|
int redist_total_next = 0;
|
|
|
|
|
|
|
|
for (int year = 0; year < duration; year++) {
|
|
|
|
// std::cout << year << "\t" << balances.size() << std::endl;
|
|
|
|
|
|
|
|
// age all
|
|
|
|
for (int id = 0; id < ages.size(); id++) {
|
|
|
|
ages.at(id) += 1;
|
|
|
|
if (ages.at(id) > max_age) {
|
2022-12-01 18:35:27 -08:00
|
|
|
int bal = balances.at(id);
|
|
|
|
ages.erase(ages.begin()+id);
|
|
|
|
balances.erase(balances.begin()+id);
|
|
|
|
switch (estate_mode) {
|
2022-12-01 14:36:33 -08:00
|
|
|
case INHERITANCE: {
|
|
|
|
int recipient_id = random_item(balances, true);
|
|
|
|
balances.at(recipient_id) += bal;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case EVEN_REDIST: {
|
|
|
|
redist_total_next += bal;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// (roughly) simulate logistic population growth
|
|
|
|
int diff = logistic_population_func(
|
|
|
|
year, N_o, N_f, k, duration) - balances.size();
|
|
|
|
if (diff > 0) {
|
|
|
|
for (int i = 0; i < diff; i++) {
|
|
|
|
ages.push_back(1);
|
|
|
|
balances.push_back(starting_balance_new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int j = 0; j < balances.size(); j++) {
|
2022-12-01 18:35:27 -08:00
|
|
|
|
2022-12-01 14:36:33 -08:00
|
|
|
// redistribute estates
|
|
|
|
balances.at(j) += redist_total / balances.size();
|
2022-12-01 18:35:27 -08:00
|
|
|
|
2022-12-01 14:36:33 -08:00
|
|
|
// make 3 arbitrary spending decisions -> 30% of savings
|
|
|
|
for (int k = 0; k < 3; k++) {
|
|
|
|
economic_decision_simple(balances, j, 0.1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// reset redist tally
|
|
|
|
redist_total = redist_total_next;
|
|
|
|
redist_total_next = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// std::sort(balances.begin(), balances.end(), std::greater<int>());
|
|
|
|
std::string ext;
|
2022-12-01 18:35:27 -08:00
|
|
|
switch (estate_mode) {
|
2022-12-01 14:36:33 -08:00
|
|
|
case EVEN_REDIST:
|
|
|
|
ext = "even";
|
|
|
|
break;
|
|
|
|
case INHERITANCE:
|
|
|
|
ext = "inheritance";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// dump_balances_and_ages_csv(balances, ages, "pop-simple-results-"+ext);
|
|
|
|
std::cout << "Finished with " << balances.size() << " balances\n";
|
|
|
|
|
|
|
|
PopSimpleResult res;
|
|
|
|
res.ages = ages;
|
2022-12-02 00:39:47 -08:00
|
|
|
res.balances = balances;
|
2022-12-01 14:36:33 -08:00
|
|
|
return res;
|
|
|
|
}
|
2022-12-02 02:00:45 -08:00
|
|
|
|