Skip to content

Commit

Permalink
fix: Simulation Settings
Browse files Browse the repository at this point in the history
  • Loading branch information
AsPJT committed Jun 5, 2024
1 parent 3d29642 commit 571e4d1
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 118 deletions.
32 changes: 15 additions & 17 deletions Data/Simulations/Settings.tsv
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
key value ja-JP
---------- Time ---------- 時間 --------------------------------------------------
start_julian_day 1319309 シミュレーション開始日(ユリウス日)
area honsyu シミュレーションの対象範囲
unit_group_min 11 単位集団の最小人数
unit_group_max 40 単位集団の最大人数
basic_group_min 41 基礎集団の最小人数
basic_group_max 240 基礎集団の最大人数
composite_settlement_min 82 複合集落の最小人数
steps_per_year 12 1年あたりのステップ数
female 0 女性
male 1 男性
female_marriageable_age_min 13 女性の最小結婚可能年齢(歳)
male_marriageable_age_min 17 男性の最小結婚可能年齢(歳)
female_marriageable_age_max 60 女性の最大結婚可能年齢(歳)
male_marriageable_age_max 70 男性の最大結婚可能年齢(歳)
---------- Space ---------- 空間 --------------------------------------------------
area honsyu シミュレーションの対象範囲
grid_length 512 集落をグループ分けする際の1グリッド辺の長さ
---------- Marriage ---------- 婚姻 --------------------------------------------------
marriage_search_range 320 結婚時に近くの集落からエージェントを探す際の探索距離
female_marriageable_age_min 13 女性の最小婚姻可能年齢(歳)
male_marriageable_age_min 17 男性の最小婚姻可能年齢(歳)
female_marriageable_age_max 60 女性の最大婚姻可能年齢(歳)
male_marriageable_age_max 70 男性の最大婚姻可能年齢(歳)
birthable_age_min 15 出産の最小可能年齢(歳)
birthable_age_max 50 出産の最大可能年齢(歳)
---------- Childbirth ---------- 出産 --------------------------------------------------
birth_interval 10 出産の間隔:10ヶ月(Step)
marriage_search_range 320 結婚時に近くの集落からエージェントを探す際の探索距離
grid_length 512 集落をグループ分けする際の1グリッド辺の長さ
stillbirth_rate 0.16 死産率
child_agriculture_priority 0.7 片親が農耕文化を持ち、もう一方の片親が農耕文化を持たない時の農耕文化継承の優先度
---------- Movement ---------- 移動 --------------------------------------------------
max_settlement_population 80 集落の最大人数(人)
min_move_distance 10 最小移動距離
max_move_distance 800 最大移動距離
min_move_probability 1 移動確率下限
max_move_probability 10 移動確率上限
move_probability_normalization_coefficient 1000 移動確率の正規化係数
child_agriculture_priority 0.7 片親が農耕文化を持ち、もう一方の片親が農耕文化を持たない時の農耕文化継承の優先度
stillbirth_rate 0.16 死産率
move_probability_normalization_coefficient 1000 移動確率の正規化係数
8 changes: 2 additions & 6 deletions Library/PAX_SAPIENTICA/Simulation/Chromosome.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ namespace paxs {
return true;
}

static Chromosome generateFromParents(const Chromosome& mother, const Chromosome& father) noexcept {
std::random_device seed_gen;
std::mt19937 engine(seed_gen());
static Chromosome generateFromParents(std::mt19937& engine, const Chromosome& mother, const Chromosome& father) noexcept {
std::uniform_int_distribution<std::uint_least64_t> dist((std::numeric_limits<std::uint_least64_t>::min)(), (std::numeric_limits<std::uint_least64_t>::max)());
std::uint_least64_t random_value = dist(engine);

Expand All @@ -93,9 +91,7 @@ namespace paxs {
return child;
}

static Chromosome generateRandom() noexcept {
std::random_device seed_gen;
std::mt19937 engine(seed_gen());
static Chromosome generateRandom(std::mt19937& engine) noexcept {
std::uniform_int_distribution<> dist((std::numeric_limits<std::uint_least8_t>::min)(), (std::numeric_limits<std::uint_least8_t>::max)());

Chromosome random_chromosome;
Expand Down
20 changes: 7 additions & 13 deletions Library/PAX_SAPIENTICA/Simulation/Genome.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,37 +58,31 @@ namespace paxs {
return chromosome.getGender();
}

static Genome generateRandom() noexcept {
static Genome generateRandom(std::mt19937& engine) noexcept {
Genome genome;
genome.setChromosome(Chromosome::generateRandom());
genome.setChromosome(Chromosome::generateRandom(engine));

std::random_device seed_gen;
std::mt19937 engine(seed_gen());
std::uniform_int_distribution<> dist((std::numeric_limits<std::uint_least8_t>::min)(), (std::numeric_limits<std::uint_least8_t>::max)());
genome.setMtDNA(static_cast<std::uint_least8_t>(dist(engine)));
genome.setYDNA(static_cast<std::uint_least8_t>(dist(engine)));
return genome;
}
static Genome generateRandomSetMtDNA(const std::uint_least8_t mtdna_) noexcept {
static Genome generateRandomSetMtDNA(std::mt19937& engine, const std::uint_least8_t mtdna_) noexcept {
Genome genome;
genome.setChromosome(Chromosome::generateRandom());
genome.setChromosome(Chromosome::generateRandom(engine));

std::random_device seed_gen;
std::mt19937 engine(seed_gen());
std::uniform_int_distribution<> dist((std::numeric_limits<std::uint_least8_t>::min)(), (std::numeric_limits<std::uint_least8_t>::max)());
genome.setMtDNA(mtdna_);
genome.setYDNA(static_cast<std::uint_least8_t>(dist(engine)));
return genome;
}

static Genome generateFromParents(const Genome& mother, const Genome& father) noexcept {
static Genome generateFromParents(std::mt19937& engine, const Genome& mother, const Genome& father) noexcept {
Genome genome;
genome.setChromosome(Chromosome::generateFromParents(mother.cgetChromosome(), father.cgetChromosome()));
genome.setChromosome(Chromosome::generateFromParents(engine, mother.cgetChromosome(), father.cgetChromosome()));

std::random_device seed_gen;
std::mt19937 engine(seed_gen());
genome.setMtDNA(mother.getMtDNA());
if (genome.cgetChromosome().getGender() == SimulationConstants::getInstance()->female) {
if (genome.cgetChromosome().getGender() == female_value) {
genome.setYDNA(mother.getYDNA());
}
else {
Expand Down
12 changes: 6 additions & 6 deletions Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,12 @@ namespace paxs {
if (dist.size() <= 1) {
continue;
}
for (int i = 0; i < dist.size(); i += 2) {
for (int j = 0; j < mtdna_list.size();++j) {
for (int j = 0; j < dist.size(); j += 2) {
for (int k = 0; k < mtdna_list.size();++k) {
// mtDNA の名称の index を取得し、確率分布と一緒に管理
if (mtdna_list[j] == dist[i]) {
mtdna_region.id.emplace_back(j);
mtdna_region.weight.emplace_back(std::stod(dist[i + 1]));
if (mtdna_list[k] == dist[j]) {
mtdna_region.id.emplace_back(k);
mtdna_region.weight.emplace_back(std::stod(dist[j + 1]));
break;
}
}
Expand Down Expand Up @@ -224,7 +224,7 @@ namespace paxs {
}

// 古い実装
explicit JapanProvinces(const std::string& japan_region_tsv_path, const std::string& ryoseikoku_tsv_path, int aaa) noexcept {
explicit JapanProvinces(const std::string& japan_region_tsv_path, const std::string& ryoseikoku_tsv_path) noexcept {
std::vector<std::vector<std::string>> japan_region_tsv = File::readTSV(AppConfig::getInstance()->getRootPath() + japan_region_tsv_path);
if (japan_region_tsv.empty()) {
PAXS_WARNING("Failed to read Japan region TSV file: " + japan_region_tsv_path);
Expand Down
40 changes: 20 additions & 20 deletions Library/PAX_SAPIENTICA/Simulation/KanakumaLifeSpan.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*##########################################################################################
PAX SAPIENTICA Library 💀🌿🌏
PAX SAPIENTICA Library 💀🌿🌏
[Planning] 2023-2024 As Project
[Production] 2023-2024 As Project
[Contact Us] [email protected] https://github.com/AsPJT/PAX_SAPIENTICA
[License] Distributed under the CC0 1.0. https://creativecommons.org/publicdomain/zero/1.0/
[Planning] 2023-2024 As Project
[Production] 2023-2024 As Project
[Contact Us] [email protected] https://github.com/AsPJT/PAX_SAPIENTICA
[License] Distributed under the CC0 1.0. https://creativecommons.org/publicdomain/zero/1.0/
##########################################################################################*/

Expand Down Expand Up @@ -47,52 +47,52 @@ namespace paxs {

/// @brief 英語未翻訳
/// @brief 寿命を決定する
std::uint_least32_t setAdultLifeSpan(const std::uint_least8_t gender_, std::mt19937& gen) {
AgeType setAdultLifeSpan(const std::uint_least8_t gender_, std::mt19937& gen) {
// もし大人だったら
if (gender_ == 0) { // 女性の場合
const std::uint_least32_t adult_type = static_cast<std::uint_least32_t>(life_male_adult_num(gen));
const AgeType adult_type = static_cast<AgeType>(life_male_adult_num(gen));

if (adult_type <= 14) { // 成年
return static_cast<std::uint_least32_t>(life_adult_exp_dist(gen));
return static_cast<AgeType>(life_adult_exp_dist(gen));
}
else if (adult_type <= (14 + 26)) { // 熟年
return static_cast<std::uint_least32_t>(life_mature_exp_dist(gen));
return static_cast<AgeType>(life_mature_exp_dist(gen));
}
// 老年
return static_cast<std::uint_least32_t>(life_older_exp_dist(gen));
return static_cast<AgeType>(life_older_exp_dist(gen));
}
else if (gender_ == 1) { // 男性の場合
const std::uint_least32_t adult_type = static_cast<std::uint_least32_t>(life_female_adult_num(gen));
const AgeType adult_type = static_cast<AgeType>(life_female_adult_num(gen));

if (adult_type <= 19) { // 成年
return static_cast<std::uint_least32_t>(life_adult_exp_dist(gen));
return static_cast<AgeType>(life_adult_exp_dist(gen));
}
else if (adult_type <= (19 + 19)) { // 熟年
return static_cast<std::uint_least32_t>(life_mature_exp_dist(gen));
return static_cast<AgeType>(life_mature_exp_dist(gen));
}
}
// 老年
return static_cast<std::uint_least32_t>(life_older_exp_dist(gen));
return static_cast<AgeType>(life_older_exp_dist(gen));
}

/// @brief 英語未翻訳
/// @brief 寿命を決定する
std::uint_least32_t setLifeSpan(const std::uint_least8_t gender_, std::mt19937& gen) {
AgeType setLifeSpan(const std::uint_least8_t gender_, std::mt19937& gen) {

if (life_person_num(gen) <= 37) { // もし子供だったら
const std::uint_least32_t child_type = static_cast<std::uint_least32_t>(life_child_num(gen));
const AgeType child_type = static_cast<AgeType>(life_child_num(gen));

if (child_type <= 6) { // 乳児
return static_cast<std::uint_least32_t>(life_infant_exp_dist(gen));
return static_cast<AgeType>(life_infant_exp_dist(gen));
}
else if (child_type <= (6 + 22)) { // 幼児
return static_cast<std::uint_least32_t>(life_toddler_exp_dist(gen));
return static_cast<AgeType>(life_toddler_exp_dist(gen));
}
else if (child_type <= (6 + 22 + 5)) { // 小児
return static_cast<std::uint_least32_t>(life_child_exp_dist(gen));
return static_cast<AgeType>(life_child_exp_dist(gen));
}
// 若年
return static_cast<std::uint_least32_t>(life_young_exp_dist(gen));
return static_cast<AgeType>(life_young_exp_dist(gen));
}
// もし大人だったら
return setAdultLifeSpan(gender_, gen);
Expand Down
14 changes: 7 additions & 7 deletions Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ namespace paxs {
std::vector<std::size_t> marriageable_female_index;
for (std::size_t i = 0; i < agents.size(); ++i) {
// 結婚可能かどうか
if (agents[i].isAbleToMarriage() && agents[i].getGender() == SimulationConstants::getInstance()->female) {
if (agents[i].isAbleToMarriage() && agents[i].getGender() == female_value) {
if (!isMarried(agents[i].getAge())) continue;
// 妊娠していたら婚姻しない(婚姻可能と定義すると再婚者のデータで上書きされ子供への継承が不自然になる)
if (agents[i].getBirthIntervalCount() > 0) continue;
Expand Down Expand Up @@ -207,7 +207,7 @@ namespace paxs {
std::vector<std::pair<std::uint_least32_t, std::uint_least32_t>> male_settlement_pair;
for (auto& close_settlement : close_settlements) {
for (auto& agent : close_settlement->cgetAgents()) {
if (agent.isAbleToMarriage() && agent.getGender() == SimulationConstants::getInstance()->male) {
if (agent.isAbleToMarriage() && agent.getGender() == male_value) {
male_settlement_pair.emplace_back(agent.getId(), close_settlement->getId());
}
}
Expand Down Expand Up @@ -246,7 +246,7 @@ namespace paxs {
Agent& female_ = agents[marriageable_female_index[index_pair.first]];

female_.marry(male_id, male_.cgetGenome(), male_.cgetFarming(), male_.cgetHunterGatherer());
const std::uint_least64_t female_id = female_.getId();
const HumanIndexType female_id = female_.getId();

male_.marry(female_id, female_.cgetGenome(), female_.cgetFarming(), female_.cgetHunterGatherer());
agents.emplace_back(male_);
Expand Down Expand Up @@ -369,7 +369,7 @@ namespace paxs {

// パートナー同士は同じ集落に振り分ける
for (Agent& agent : agents) {
if (agent.isMarried() && agent.getGender() == SimulationConstants::getInstance()->female) {
if (agent.isMarried() && agent.getGender() == female_value) {
auto it = std::find_if(new_settlement_agents.begin(), new_settlement_agents.end(), [agent](const Agent& a) { return a.getId() == agent.getPartnerId(); });
if (it != new_settlement_agents.end()) {
agents.emplace_back(*it);
Expand All @@ -380,7 +380,7 @@ namespace paxs {
}

for (Agent& agent : new_settlement_agents) {
if (agent.isMarried() && agent.getGender() == SimulationConstants::getInstance()->female) {
if (agent.isMarried() && agent.getGender() == female_value) {
auto it = std::find_if(agents.begin(), agents.end(), [agent](const Agent& a) { return a.getId() == agent.getPartnerId(); });
if (it != agents.end()) {
new_settlement_agents.emplace_back(*it);
Expand Down Expand Up @@ -426,7 +426,7 @@ namespace paxs {
}
// TODO: 直す
//if (!agent.isMarried()) continue;
Genome genome = Genome::generateFromParents(agent.cgetGenome(), agent.cgetPartnerGenome());
Genome genome = Genome::generateFromParents(*gen, agent.cgetGenome(), agent.cgetPartnerGenome());
children.emplace_back(Agent(
UniqueIdentification<std::uint_least32_t>::generate(),
//0, // TODO: 名前ID
Expand Down Expand Up @@ -458,7 +458,7 @@ namespace paxs {
void emigration(KanakumaLifeSpan& kanakuma_life_span, std::uint_least64_t& count) noexcept {
if (agents.size() >= 60) {

Genome genome = Genome::generateRandom();
Genome genome = Genome::generateRandom(*gen);
const std::uint_least32_t set_lifespan = kanakuma_life_span.setLifeSpan(genome.getGender(), *gen);

std::uniform_int_distribution<> lifespan_dist{
Expand Down
Loading

0 comments on commit 571e4d1

Please sign in to comment.