Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

シミュレーション変数の命名変更 #111

Merged
merged 1 commit into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions Data/Simulations/Settings.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ steps_per_year 12 1年あたりのStepの数(step/年)
output_step_frequency 120 何Stepおきに出力するか?(step)
immigration_start_steps 1801 渡来開始Step数目(step)
immigration_end_steps 21600 渡来終了Step数目(step)
init_lifespan_min 180 初期化時の寿命までの最低Step間隔(step)
init_lifespan_grace_period 180 初期化時の寿命までの最低Step間隔(step)
#Space -------------------- #空間 --------------------------------------------------
area honsyu シミュレーションの対象範囲
grid_length 256 集落をグループ分けする際の1グリッド辺の長さ(cell)
cell_group_length 256 集落をグループ分けする際の1グリッド辺の長さ(cell)
immigration_district_id 73 渡来地区ID
land_key district 陸地データのKey
district_key district 地区データのKey
Expand All @@ -25,16 +25,16 @@ marriageable_age_all_weight 101.8 婚姻可能年齢重み
#Childbirth -------------------- #出産 --------------------------------------------------
birth_interval 10 妊娠から出産までのStep間隔(step)
hunter_gatherer_stillbirth_rate 0 狩猟採集死産率 (no effect)
farming_stillbirth_rate 0 水田稲作死産率 (no effect)
agricultural_stillbirth_rate 0 水田稲作死産率 (no effect)
child_agriculture_priority 0.5 片親が農耕文化を持ち、もう一方の片親が農耕文化を持たない時の農耕文化継承の優先度
birthable_age_min 15 出産の最小可能年齢(歳)
birthable_age_max 50 出産の最大可能年齢(歳)
birthable_age_constant 8.5 出産可能年齢定数
birthable_age_threshold 16 出産可能年齢閾値
birthable_age_all_weight 101.8 出産可能年齢重み
childbearing_age_min 15 出産の最小可能年齢(歳)
childbearing_age_max 50 出産の最大可能年齢(歳)
childbearing_age_constant 8.5 出産可能年齢定数
childbearing_age_threshold 16 出産可能年齢閾値
childbearing_age_all_weight 101.8 出産可能年齢重み
#Movement -------------------- #移動 --------------------------------------------------
max_hunter_gatherer_settlement_population 25 狩猟採集集落の最大人数(人)
max_farming_settlement_population 80 水田稲作集落の最大人数(人)
max_agricultural_settlement_population 80 水田稲作集落の最大人数(人)
min_move_distance 1 最小移動距離(cell)
max_move_distance 1600 最大移動距離(cell)
move_probability 0.01 移動確率
Expand Down
52 changes: 27 additions & 25 deletions Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,6 @@ namespace paxs {
}

// シミュレーションの設定で母方に移住するか父方に移住するかを決める
// 母方の場合
// if (isMatrilocality()) {
for (std::size_t i = 0; i < marriageable_agents_index_pair.size(); ++i) {
std::pair<std::size_t, std::size_t> index_pair = marriageable_agents_index_pair[i];
std::uint_least32_t male_id = male_settlement_pair[index_pair.second].first;
Expand All @@ -434,6 +432,7 @@ namespace paxs {
continue;
}
male_settlement_position = close_settlements[j]->getPosition();
// 母方の場合
if (is_matrilocality) {
Agent male_ = close_settlements[j]->getAgentCopy(male_id);
Agent& female_ = agents[marriageable_female_index[index_pair.first]];
Expand All @@ -444,6 +443,7 @@ namespace paxs {
male_.marry(female_id, female_.cgetGenome(), female_.cgetFarming(), female_.cgetHunterGatherer(), female_.cgetLanguage());
agents.emplace_back(male_);
}
// 父方の場合
else {
Agent& male_ = close_settlements[j]->getAgent(male_id);
Agent female_ = agents[marriageable_female_index[index_pair.first]];
Expand All @@ -453,7 +453,7 @@ namespace paxs {

male_.marry(female_id, female_.cgetGenome(), female_.cgetFarming(), female_.cgetHunterGatherer(), female_.cgetLanguage());

male_settlement_position /= SimulationConstants::getInstance()->grid_length;
male_settlement_position /= SimulationConstants::getInstance()->cell_group_length;
add_agent(female_, male_settlement_id, male_settlement_position);
}
is_found = true;
Expand All @@ -467,7 +467,7 @@ namespace paxs {
}

if (is_matrilocality) {
male_settlement_position /= SimulationConstants::getInstance()->grid_length;
male_settlement_position /= SimulationConstants::getInstance()->cell_group_length;
delete_agent(male_id, male_settlement_id, male_settlement_position);
}
else {
Expand All @@ -485,7 +485,6 @@ namespace paxs {
/// @brief 事前更新
void preUpdate(KanakumaLifeSpan& kanakuma_life_span) noexcept {
birth(kanakuma_life_span);
//emigration(kanakuma_life_span);
}

/// @brief On update.
Expand Down Expand Up @@ -631,8 +630,8 @@ namespace paxs {
++loop_count;
}
}
current_key = current_position / SimulationConstants::getInstance()->grid_length;
target_key = target_position / SimulationConstants::getInstance()->grid_length;
current_key = current_position / SimulationConstants::getInstance()->cell_group_length;
target_key = target_position / SimulationConstants::getInstance()->cell_group_length;

if (current_key == target_key) return { 0, Vector2(), Vector2() };

Expand All @@ -652,15 +651,14 @@ namespace paxs {
/// @brief Get the weight population.
/// @brief 重み人口を取得
double getPopulationWeight() const noexcept {
double population_weight = 0;
// 農耕文化の重み
const double ac_weight = SimulationConstants::getInstance()->max_agricultural_settlement_weight;
// 狩猟採集文化の重み
const double hg_weight = SimulationConstants::getInstance()->max_hunter_gatherer_settlement_weight;

double population_weight = 0;
for (std::size_t i = 0; i < agents.size(); ++i) {
if (agents[i].cgetFarming() > 0) { // 農耕
population_weight += SimulationConstants::getInstance()->max_farming_settlement_weight;
}
else { // 狩猟採集
population_weight += SimulationConstants::getInstance()->max_hunter_gatherer_settlement_weight;
}
population_weight += (agents[i].cgetFarming() > 0) ? ac_weight : hg_weight;
}
return population_weight;
}
Expand Down Expand Up @@ -789,7 +787,7 @@ namespace paxs {
if (count == 0) {
// 生業文化別の死産率を格納
const double stillbirth_rate = (agent.cgetFarming() > 0) ?
SimulationConstants::getInstance()->farming_stillbirth_rate :
SimulationConstants::getInstance()->agricultural_stillbirth_rate :
SimulationConstants::getInstance()->hunter_gatherer_stillbirth_rate;

// 死産率 100 %の場合は出産しない
Expand All @@ -798,21 +796,25 @@ namespace paxs {
// 死産
if (SimulationConstants::getInstance()->random_dist_f32(*gen) < stillbirth_rate) continue;
}
// TODO: 直す
//if (!agent.isMarried()) continue;
std::uint_least8_t farming = (agent.cgetFarming() > 0 && agent.cgetPartnerFarming() > 0) ? 255 : (
(agent.cgetFarming() == 0 && agent.cgetPartnerFarming() == 0) ? 0 : (
(SimulationConstants::getInstance()->random_dist_f32(*gen) < SimulationConstants::getInstance()->child_agriculture_priority) ? 255 : 0
const std::uint_least8_t farming =
// 両親が農耕文化であれば両親の半分の値を引き継ぐ
(agent.cgetFarming() > 0 && agent.cgetPartnerFarming() > 0) ?
static_cast<std::uint_least8_t>((int(agent.cgetFarming()) + int(agent.cgetPartnerFarming())) / 2)
// 両親が共に農耕文化を持たない場合は 0
: ((agent.cgetFarming() == 0 && agent.cgetPartnerFarming() == 0) ? 0
// 片親が農耕文化を持つ場合は乱数
: ((SimulationConstants::getInstance()->random_dist_f32(*gen) < SimulationConstants::getInstance()->child_agriculture_priority) ?
// 農耕文化を持つ親から値を引き継ぐ
((agent.cgetFarming() == 0) ? agent.cgetPartnerFarming() : agent.cgetFarming()) :
0
));
Genome genome = Genome::generateFromParents(*gen, agent.cgetGenome(), agent.cgetPartnerGenome());
const Genome genome = Genome::generateFromParents(*gen, agent.cgetGenome(), agent.cgetPartnerGenome());
children.emplace_back(Agent(
UniqueIdentification<HumanIndexType>::generate(),
//0, // TODO: 名前ID
0,
kanakuma_life_span.setLifeSpan(farming > 0, genome.isMale(), *gen),
genome,
farming,
//(((*gen)() % 2) == 0) ? agent.cgetFarming() : agent.cgetPartnerFarming(),
(((*gen)() % 2) == 0) ? agent.cgetHunterGatherer() : agent.cgetPartnerHunterGatherer(),
(((*gen)() % 2) == 0) ? agent.cgetLanguage() : agent.cgetPartnerLanguage()
));
Expand Down Expand Up @@ -910,12 +912,12 @@ namespace paxs {
/// @brief Is able to give birth?
/// @brief 確率で出産するかどうかを返す
bool isAbleToGiveBirth(const double age) noexcept {
auto x = [](double age) { return (age - SimulationConstants::getInstance()->pregnant_age_min_f64) / SimulationConstants::getInstance()->birthable_age_constant; };
auto x = [](double age) { return (age - SimulationConstants::getInstance()->pregnant_age_min_f64) / SimulationConstants::getInstance()->childbearing_age_constant; };
auto weight = [=](double age) {
return std::exp(-std::pow(std::log(x(age)), 2.0) / settlement::sigma_p_2_x_2) / (x(age) * settlement::sigma_x_sqrt_2_x_pi);
};

const double threshold = static_cast<double>(weight(age)) * (SimulationConstants::getInstance()->birthable_age_threshold / SimulationConstants::getInstance()->birthable_age_all_weight); // (16 / 101.8);
const double threshold = static_cast<double>(weight(age)) * (SimulationConstants::getInstance()->childbearing_age_threshold / SimulationConstants::getInstance()->childbearing_age_all_weight); // (16 / 101.8);

return SimulationConstants::getInstance()->random_dist(*gen) < threshold;
}
Expand Down
4 changes: 2 additions & 2 deletions Library/PAX_SAPIENTICA/Simulation/SettlementAgent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ namespace paxs {
/// @brief 出産可能かどうか
bool isAbleToGiveBirth() const noexcept {
const float age_f = static_cast<float>(age) / SimulationConstants::getInstance()->steps_per_year;
return age_f > SimulationConstants::getInstance()->birthable_age_min
&& age_f < SimulationConstants::getInstance()->birthable_age_max && is_married;
return age_f > SimulationConstants::getInstance()->childbearing_age_min
&& age_f < SimulationConstants::getInstance()->childbearing_age_max && is_married;
}

/// @brief Get the partner's ID.
Expand Down
8 changes: 4 additions & 4 deletions Library/PAX_SAPIENTICA/Simulation/SettlementGrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ namespace paxs {
#endif

// ランダムな位置を探す
std::uniform_int_distribution<> dis_x(grid_position.x, grid_position.x + paxs::SimulationConstants::getInstance()->grid_length - 1);
std::uniform_int_distribution<> dis_y(grid_position.y, grid_position.y + paxs::SimulationConstants::getInstance()->grid_length - 1);
std::uniform_int_distribution<> dis_x(grid_position.x, grid_position.x + paxs::SimulationConstants::getInstance()->cell_group_length - 1);
std::uniform_int_distribution<> dis_y(grid_position.y, grid_position.y + paxs::SimulationConstants::getInstance()->cell_group_length - 1);
Vector2 position;

while (black_list.size() < SimulationConstants::getInstance()->grid_length * SimulationConstants::getInstance()->grid_length) {
while (black_list.size() < SimulationConstants::getInstance()->cell_group_length * SimulationConstants::getInstance()->cell_group_length) {
position.x = dis_x(*gen);
position.y = dis_y(*gen);
if (std::find(black_list.begin(), black_list.end(), position) == black_list.end()) {
Expand All @@ -75,7 +75,7 @@ namespace paxs {
}

// 集落を移動
if (black_list.size() == SimulationConstants::getInstance()->grid_length * SimulationConstants::getInstance()->grid_length) {
if (black_list.size() == SimulationConstants::getInstance()->cell_group_length * SimulationConstants::getInstance()->cell_group_length) {
// 居住可能な場所がない
PAXS_WARNING("No place to live.");
}
Expand Down
18 changes: 10 additions & 8 deletions Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ namespace paxs {
}
else {
// 登録されていない場合は新しく地域を作成
SettlementGrid settlement_grid = SettlementGrid(target_key * SimulationConstants::getInstance()->grid_length, environment, gen);
SettlementGrid settlement_grid = SettlementGrid(target_key * SimulationConstants::getInstance()->cell_group_length, environment, gen);
settlement_grid.moveSettlementToThis(settlement_grids[current_index].getSettlement(id));
settlement_grids[target_index] = settlement_grid;
}
Expand Down Expand Up @@ -315,7 +315,7 @@ namespace paxs {
// 近隣8グリッドの集落を取得
std::vector<Settlement*> close_settlements;
Vector2 grid_position = settlement_grid.second.getGridPosition();
grid_position /= SimulationConstants::getInstance()->grid_length;
grid_position /= SimulationConstants::getInstance()->cell_group_length;
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
auto it = settlement_grids.find((grid_position + Vector2(i, j)).to(SettlementGridsType{}));
Expand Down Expand Up @@ -542,11 +542,11 @@ namespace paxs {
settlement_population = (std::min)(settlement_population, static_cast<int>(district_population_it->second));

// 集落をグリッドに配置
Vector2 grid_position = live_position / SimulationConstants::getInstance()->grid_length;
Vector2 grid_position = live_position / SimulationConstants::getInstance()->cell_group_length;
SettlementGridsType key = grid_position.to(SettlementGridsType{});
// グリッドが存在しない場合は作成
if (settlement_grids.find(key) == settlement_grids.end()) {
settlement_grids[key] = SettlementGrid(grid_position * SimulationConstants::getInstance()->grid_length, environment, gen);
settlement_grids[key] = SettlementGrid(grid_position * SimulationConstants::getInstance()->cell_group_length, environment, gen);
}
// 集落を作成
Settlement settlement = Settlement(
Expand All @@ -564,8 +564,9 @@ namespace paxs {
const AgeType set_lifespan = kanakuma_life_span.setLifeSpan((is_farming), genome.isMale(), gen);

AgeType age_value = 0;
if (set_lifespan > SimulationConstants::getInstance()->init_lifespan_min) {
std::uniform_int_distribution<> lifespan_dist{ 0, static_cast<int>(set_lifespan - SimulationConstants::getInstance()->init_lifespan_min) }; // 寿命の乱数分布
if (set_lifespan > SimulationConstants::getInstance()->init_lifespan_grace_period) {
// 寿命の乱数分布
std::uniform_int_distribution<> lifespan_dist{ 0, static_cast<int>(set_lifespan - SimulationConstants::getInstance()->init_lifespan_grace_period) };
age_value = static_cast<AgeType>(lifespan_dist(gen));
}

Expand Down Expand Up @@ -626,8 +627,9 @@ namespace paxs {
const AgeType set_lifespan = kanakuma_life_span.setLifeSpan(is_farming, genome.isMale(), gen);

AgeType age_value = 0;
if (set_lifespan > SimulationConstants::getInstance()->init_lifespan_min) {
std::uniform_int_distribution<> lifespan_dist{ 0, static_cast<int>(set_lifespan - SimulationConstants::getInstance()->init_lifespan_min) }; // 寿命の乱数分布
if (set_lifespan > SimulationConstants::getInstance()->init_lifespan_grace_period) {
// 寿命の乱数分布
std::uniform_int_distribution<> lifespan_dist{ 0, static_cast<int>(set_lifespan - SimulationConstants::getInstance()->init_lifespan_grace_period) };
age_value = static_cast<AgeType>(lifespan_dist(gen));
}

Expand Down
Loading