test-econ-model/pop-simple.hpp

116 lines
2.9 KiB
C++
Raw Permalink Normal View History

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-04 16:55:22 -08:00
#include <matplot/matplot.h>
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
};
2022-12-04 16:55:22 -08:00
static 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