diff --git a/Data/Simulations/Sample/District.tsv b/Data/Simulations/Sample/District.tsv index a39466bfd..482304a90 100644 --- a/Data/Simulations/Sample/District.tsv +++ b/Data/Simulations/Sample/District.tsv @@ -3,13 +3,13 @@ 2 osumi 大隅 2 4 20 2400 0 0 kyushu_jomon 40600 3 hyuga 日向 2 4 20 1820 0 0 kyushu_jomon 30800 4 higo 肥後 2 4 20 6426 0 0 kyushu_jomon 108700 -5 bungo 豊後 3 4 20 1226 0 0.001 kyushu_jomon 51600 -6 chikugo 筑後 3 4 20 1410 0 0.001 kyushu_jomon 59300 -7 hizen 肥前 3 4 20 1148 0 0.001 kyushu_jomon 48300 -8 chikuzen 筑前 3 4 20 2664 5 0.001 kyushu_jomon 112000 -9 buzen 豊前 3 4 20 1122 0 0.001 kyushu_jomon 47200 -10 iki 壱岐 3 4 20 288 0 0.001 kyushu_jomon 12100 -11 tsushima 対馬 3 4 20 234 0 0.001 kyushu_jomon 9900 +5 bungo 豊後 3 4 20 1226 0 0 kyushu_jomon 51600 +6 chikugo 筑後 3 4 20 1410 0 0 kyushu_jomon 59300 +7 hizen 肥前 3 4 20 1148 0 0 kyushu_jomon 48300 +8 chikuzen 筑前 3 4 20 2664 1 0.0003 kyushu_jomon 112000 +9 buzen 豊前 3 4 20 1122 0 0 kyushu_jomon 47200 +10 iki 壱岐 3 4 20 288 0 0 kyushu_jomon 12100 +11 tsushima 対馬 3 4 20 234 0 0 kyushu_jomon 9900 12 nagato 長門 5 4 20 976 0 0 chugoku_jomon 43900 13 suo 周防 5 4 20 1098 0 0 chugoku_jomon 49400 14 aki 安芸 5 4 20 1540 0 0 chugoku_jomon 69200 diff --git a/Data/Simulations/Settings.tsv b/Data/Simulations/Settings.tsv index 0c69a081f..0f9703ab5 100644 --- a/Data/Simulations/Settings.tsv +++ b/Data/Simulations/Settings.tsv @@ -4,22 +4,29 @@ start_julian_day 1319309 シミュレーション開始日(ユリウス日) steps_per_year 12 1年あたりのStepの数(step/年) output_step_frequency 120 何Stepおきに出力するか?(step) immigration_start_steps 2401 渡来開始Step数目(step) +immigration_end_steps 21600 渡来終了Step数目(step) init_lifespan_min 180 初期化時の寿命までの最低Step間隔(step) #Space -------------------- #空間 -------------------------------------------------- area honsyu シミュレーションの対象範囲 -grid_length 512 集落をグループ分けする際の1グリッド辺の長さ(cell) +grid_length 256 集落をグループ分けする際の1グリッド辺の長さ(cell) immigration_district_id 73 渡来地区ID land_key district 陸地データのKey district_key district 地区データのKey #Marriage -------------------- #婚姻 -------------------------------------------------- maternal_residence_probability 0.5 母方居住婚の確率 -marriage_search_range 320 結婚時に近くの集落からエージェントを探す際の探索距離(cell) +marriage_search_range 200 結婚時に近くの集落からエージェントを探す際の探索距離(cell) 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 出産の最大可能年齢(歳) +marriageable_age_constant 8.5 婚姻可能年齢定数 +marriageable_age_threshold 0.98 婚姻可能年齢閾値 +marriageable_age_all_weight 101.8 婚姻可能年齢重み +birthable_age_constant 8.5 出産可能年齢定数 +birthable_age_threshold 16.0 出産可能年齢閾値 +birthable_age_all_weight 101.8 出産可能年齢重み #Childbirth -------------------- #出産 -------------------------------------------------- birth_interval 10 妊娠から出産までのStep間隔(step) hunter_gatherer_stillbirth_rate 0 狩猟採集死産率 @@ -28,8 +35,6 @@ child_agriculture_priority 0.7 片親が農耕文化を持ち、もう一方の #Movement -------------------- #移動 -------------------------------------------------- max_hunter_gatherer_settlement_population 25 狩猟採集集落の最大人数(人) max_farming_settlement_population 80 水田稲作集落の最大人数(人) -min_move_distance 10 最小移動距離 -max_move_distance 800 最大移動距離 -min_move_probability 1 移動確率下限 -max_move_probability 1 移動確率上限 -move_probability_normalization_coefficient 1000 移動確率の正規化係数 +min_move_distance 50 最小移動距離(cell) +max_move_distance 800 最大移動距離(cell) +move_probability 0.05 移動確率 diff --git a/Library/PAX_MAHOROBA/LocationPoint.hpp b/Library/PAX_MAHOROBA/LocationPoint.hpp index 5cd2be3d1..dff49503e 100644 --- a/Library/PAX_MAHOROBA/LocationPoint.hpp +++ b/Library/PAX_MAHOROBA/LocationPoint.hpp @@ -508,6 +508,8 @@ namespace paxs { #ifdef PAXS_USING_SIMULATOR // エージェントの位置を管理 class AgentLocation { + private: + std::size_t select_draw = 1; public: /// @brief Get the mercator coordinate from the XYZTile coordinate. @@ -619,7 +621,15 @@ namespace paxs { void draw(const double jdn, std::unordered_map& agents, const double map_view_width, const double map_view_height, const double map_view_center_x, const double map_view_center_y - )const { + )/*const Siv3D Key は非 const */ { + +#ifdef PAXS_USING_SIV3D + if (s3d::Key1.pressed()) select_draw = 1; + else if (s3d::Key2.pressed()) select_draw = 2; + else if (s3d::Key3.pressed()) select_draw = 3; + else if (s3d::Key4.pressed()) select_draw = 4; +#endif + // 地名を描画 for (const auto& agent : agents) { for (const auto& settlement : agent.second.cgetSettlements()) { @@ -661,11 +671,28 @@ namespace paxs { // エージェント // if (lli.lpe == MurMur3::calcHash("agent1")) { - // const std::size_t pop_original = settlement.getFarmingPopulation(); // settlement.getPopulation(); - //const float pop_original = settlement.getFarmingPopulation() / float(settlement.getPopulation()) * 75.0f; // settlement.getPopulation(); - //const float pop_original = settlement.getMostMtDNA() / 27.0f * 75.0f; // settlement.getPopulation(); - const double pop_original = settlement.getSNP() * 75.0; // settlement.getPopulation(); - + double pop_original = 0.0; + switch (select_draw) + { + case 1: + // const std::size_t + // pop_original = settlement.getFarmingPopulation(); + pop_original = static_cast(settlement.getPopulation()); + break; + case 2: + //const float + pop_original = settlement.getFarmingPopulation() / float(settlement.getPopulation()) * 75.0; + break; + case 3: + //const float + pop_original = settlement.getMostMtDNA() / 27.0 * 75.0; + break; + case 4: + //const double + pop_original = settlement.getSNP() * 75.0; + break; + } + const std::uint_least8_t pop = (pop_original >= 75) ? 75 : static_cast(pop_original); paxg::Circle(draw_pos, 1.0f + (settlement.getPopulation() / 40.0f)//2.0f diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index c807c5476..58f31d993 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -318,13 +318,12 @@ namespace paxs { /// @brief Move. /// @brief 移動 /// @return 集落グリッドを移動したかどうか - std::tuple move(std::mt19937& engine, int move_probability) noexcept { + std::tuple move(std::mt19937& engine) noexcept { Vector2 current_key; Vector2 target_key; // 確率で移動 - std::uniform_int_distribution<> dist(0, SimulationConstants::getInstance()->move_probability_normalization_coefficient); - if (dist(engine) > move_probability) return { 0, Vector2(), Vector2() }; + if (SimulationConstants::getInstance()->random_dist(engine) > SimulationConstants::getInstance()->move_probability) return { 0, Vector2(), Vector2() }; // 座標を移動 // 移動距離0~max_move_distance @@ -582,12 +581,12 @@ namespace paxs { bool isMarried(const double age) noexcept { // 婚姻可能年齢の上限値以上だったら結婚しない if (age >= SimulationConstants::getInstance()->female_marriageable_age_max) return false; - auto x = [](double age) { return (age - SimulationConstants::getInstance()->female_marriageable_age_min_f64) / 8.5; }; + auto x = [](double age) { return (age - SimulationConstants::getInstance()->female_marriageable_age_min_f64) / SimulationConstants::getInstance()->marriageable_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(weight(age)) * (0.98 / 101.8); + const double threshold = static_cast(weight(age)) * (SimulationConstants::getInstance()->marriageable_age_threshold / SimulationConstants::getInstance()->marriageable_age_all_weight); // (0.98 / 101.8); return SimulationConstants::getInstance()->random_dist(*gen) < threshold; } @@ -595,12 +594,12 @@ namespace paxs { /// @brief Is able to give birth? /// @brief 確率で出産するかどうかを返す bool isAbleToGiveBirth(const double age) noexcept { - auto x = [](double age) { return (age - 14) / 8.5; }; + auto x = [](double age) { return (age - SimulationConstants::getInstance()->pregnant_age_min_f64) / SimulationConstants::getInstance()->birthable_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(weight(age)) * (16.0 / 101.8); + const double threshold = static_cast(weight(age)) * (SimulationConstants::getInstance()->birthable_age_threshold / SimulationConstants::getInstance()->birthable_age_all_weight); // (16 / 101.8); return SimulationConstants::getInstance()->random_dist(*gen) < threshold; } diff --git a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp index 7337d77c4..bc7c39f62 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp @@ -47,10 +47,6 @@ namespace paxs { environment(std::make_unique(map_list_path)), gen(seed) { japan_provinces = std::make_unique(japan_provinces_path); kanakuma_life_span.japan_provinces = japan_provinces.get(); - - // ランダムに移動確率を設定 - std::uniform_int_distribution<> move_probability_dist{ SimulationConstants::getInstance()->min_move_probability, SimulationConstants::getInstance()->max_move_probability }; - move_probability = move_probability_dist(gen); } /// @brief 環境を設定 void setEnvironment(const std::string& map_list_path, const std::string& japan_provinces_path, /*const int z,*/ const unsigned seed = 0) noexcept { @@ -62,10 +58,6 @@ namespace paxs { japan_provinces.reset(); japan_provinces = std::make_unique(japan_provinces_path); kanakuma_life_span.japan_provinces = japan_provinces.get(); - - // ランダムに移動確率を設定 - std::uniform_int_distribution<> move_probability_dist{ SimulationConstants::getInstance()->min_move_probability, SimulationConstants::getInstance()->max_move_probability }; - move_probability = move_probability_dist(gen); } /// @brief @@ -182,7 +174,7 @@ namespace paxs { continue; } - auto [target_id, current_key, target_key] = settlements[i].move(gen, move_probability); + auto [target_id, current_key, target_key] = settlements[i].move(gen); if (target_id != 0) { move_list.emplace_back(target_id, current_key, target_key); @@ -202,7 +194,8 @@ namespace paxs { } } // 前901年から稲作文化開始 - if (step_count >= SimulationConstants::getInstance()->immigration_start_steps) { + if (step_count >= SimulationConstants::getInstance()->immigration_start_steps && + step_count <= SimulationConstants::getInstance()->immigration_end_steps) { randomizeSettlements(false, 255, 0, 255/*渡来人は SNP:255*/); } @@ -283,7 +276,8 @@ namespace paxs { } // 前901年から処理開始 - if (step_count >= SimulationConstants::getInstance()->immigration_start_steps) { + if (step_count >= SimulationConstants::getInstance()->immigration_start_steps && + step_count <= SimulationConstants::getInstance()->immigration_end_steps) { // 渡来数を増やす japan_provinces->update(); } @@ -327,7 +321,6 @@ namespace paxs { std::shared_ptr environment; std::unique_ptr japan_provinces; - int move_probability = 0; // 移動確率 std::mt19937 gen; // 乱数生成器 diff --git a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp index d3d19893e..6c34f0ca0 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp @@ -82,9 +82,20 @@ namespace paxs { std::uint_least32_t male_marriageable_age_max = 70; // 出産可能:15歳以上50歳未満 std::uint_least32_t birthable_age_min = 15; + double birthable_age_min_f64 = 15.0; std::uint_least32_t birthable_age_max = 50; // 出産の間隔:10ヶ月 std::uint_least8_t birth_interval = 10; + // 妊娠可能 + double pregnant_age_min_f64 = birthable_age_min_f64 - static_cast(birth_interval) / static_cast(steps_per_year); + // 婚姻可能年齢定数 + double marriageable_age_constant = 8.5; + double marriageable_age_threshold = 0.98; + double marriageable_age_all_weight = 101.8; + // 出産可能年齢定数 + double birthable_age_constant = 8.5; + double birthable_age_threshold = 16.0; + double birthable_age_all_weight = 101.8; // 結婚時に近くの集落からエージェントを探す際の探索範囲 std::uint_least32_t marriage_search_range = 60; @@ -95,6 +106,7 @@ namespace paxs { // 渡来開始ステップ数 std::uint_least64_t immigration_start_steps = 2401; + std::uint_least64_t immigration_end_steps = 21600; // 渡来地区 ID std::uint_least8_t immigration_district_id = 73; @@ -111,12 +123,8 @@ namespace paxs { std::uint_least32_t min_move_distance = 10; // 最大移動距離 std::uint_least32_t max_move_distance = 800; - // 移動確率下限 - int min_move_probability = 1; - // 移動確率上限 - int max_move_probability = 10; - // 移動確率の正規化係数 - int move_probability_normalization_coefficient = 1000; + // 移動確率 + double move_probability = 1; // 片親が農耕文化を持ち、もう一方の片親が農耕文化を持たない時の農耕文化継承の優先度 double child_agriculture_priority = 0.7; @@ -182,14 +190,23 @@ namespace paxs { stoiFunc(kvt, MurMur3::calcHash("female_marriageable_age_max"), [&](const std::string& str_) {female_marriageable_age_max = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("male_marriageable_age_max"), [&](const std::string& str_) {male_marriageable_age_max = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("birthable_age_min"), [&](const std::string& str_) {birthable_age_min = static_cast(std::stoul(str_)); }); + birthable_age_min_f64 = static_cast(birthable_age_min); stoiFunc(kvt, MurMur3::calcHash("birthable_age_max"), [&](const std::string& str_) {birthable_age_max = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("birth_interval"), [&](const std::string& str_) {birth_interval = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("marriage_search_range"), [&](const std::string& str_) {marriage_search_range = static_cast(std::stoul(str_)); }); marriage_search_range_pow2 = marriage_search_range * marriage_search_range; + stoiFunc(kvt, MurMur3::calcHash("marriageable_age_constant"), [&](const std::string& str_) {marriageable_age_constant = std::stod(str_); }); + stoiFunc(kvt, MurMur3::calcHash("marriageable_age_threshold"), [&](const std::string& str_) {marriageable_age_threshold = std::stod(str_); }); + stoiFunc(kvt, MurMur3::calcHash("marriageable_age_all_weight"), [&](const std::string& str_) {marriageable_age_all_weight = std::stod(str_); }); + stoiFunc(kvt, MurMur3::calcHash("birthable_age_constant"), [&](const std::string& str_) {birthable_age_constant = std::stod(str_); }); + stoiFunc(kvt, MurMur3::calcHash("birthable_age_threshold"), [&](const std::string& str_) {birthable_age_threshold = std::stod(str_); }); + stoiFunc(kvt, MurMur3::calcHash("birthable_age_all_weight"), [&](const std::string& str_) {birthable_age_all_weight = std::stod(str_); }); + stoiFunc(kvt, MurMur3::calcHash("grid_length"), [&](const std::string& str_) {grid_length = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("immigration_start_steps"), [&](const std::string& str_) {immigration_start_steps = static_cast(std::stoul(str_)); }); + stoiFunc(kvt, MurMur3::calcHash("immigration_end_steps"), [&](const std::string& str_) {immigration_end_steps = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("immigration_district_id"), [&](const std::string& str_) {immigration_district_id = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("init_lifespan_min"), [&](const std::string& str_) {init_lifespan_min = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("max_farming_settlement_population"), [&](const std::string& str_) {max_farming_settlement_weight = 1.0 / static_cast(std::stoul(str_)); }); @@ -197,14 +214,13 @@ namespace paxs { stoiFunc(kvt, MurMur3::calcHash("min_move_distance"), [&](const std::string& str_) {min_move_distance = static_cast(std::stoul(str_)); }); stoiFunc(kvt, MurMur3::calcHash("max_move_distance"), [&](const std::string& str_) {max_move_distance = static_cast(std::stoul(str_)); }); - stoiFunc(kvt, MurMur3::calcHash("min_move_probability"), [&](const std::string& str_) {min_move_probability = std::stoi(str_); }); - stoiFunc(kvt, MurMur3::calcHash("max_move_probability"), [&](const std::string& str_) {max_move_probability = std::stoi(str_); }); - stoiFunc(kvt, MurMur3::calcHash("move_probability_normalization_coefficient"), [&](const std::string& str_) {move_probability_normalization_coefficient = std::stoi(str_); }); + stoiFunc(kvt, MurMur3::calcHash("move_probability"), [&](const std::string& str_) {move_probability = std::stod(str_); }); stoiFunc(kvt, MurMur3::calcHash("child_agriculture_priority"), [&](const std::string& str_) {child_agriculture_priority = std::stod(str_); }); stoiFunc(kvt, MurMur3::calcHash("hunter_gatherer_stillbirth_rate"), [&](const std::string& str_) {hunter_gatherer_stillbirth_rate = std::stod(str_); }); stoiFunc(kvt, MurMur3::calcHash("farming_stillbirth_rate"), [&](const std::string& str_) {farming_stillbirth_rate = std::stod(str_); }); stoiFunc(kvt, MurMur3::calcHash("maternal_residence_probability"), [&](const std::string& str_) {maternal_residence_probability = std::stod(str_); }); + pregnant_age_min_f64 = birthable_age_min_f64 - static_cast(birth_interval) / static_cast(steps_per_year); } }; diff --git a/Library/PAX_SAPIENTICA/Version.hpp b/Library/PAX_SAPIENTICA/Version.hpp index e9757ff8a..2430c2c94 100644 --- a/Library/PAX_SAPIENTICA/Version.hpp +++ b/Library/PAX_SAPIENTICA/Version.hpp @@ -19,7 +19,7 @@ // 正式バージョン数値 #ifndef PAX_SAPIENTICA_LIBRARY_VERSION -#define PAX_SAPIENTICA_LIBRARY_VERSION (20240712L) +#define PAX_SAPIENTICA_LIBRARY_VERSION (20240715L) #endif // PAX_SAPIENTICA 主要バージョン ( 0 がテスト版 , 1 から正式リリース版 ) [vX.a.a] @@ -34,12 +34,12 @@ // PAX_SAPIENTICA 微修正バージョン [v6.0.a.a.X] #ifndef PAX_SAPIENTICA_LIBRARY_PATCHLEVEL -#define PAX_SAPIENTICA_LIBRARY_PATCHLEVEL (0) +#define PAX_SAPIENTICA_LIBRARY_PATCHLEVEL (1) #endif // バージョン名 ( https://github.com/AsPJT/PAX_SAPIENTICA ) #ifndef PAX_SAPIENTICA_LIBRARY_VERSION_NAME -#define PAX_SAPIENTICA_LIBRARY_VERSION_NAME "1.2.0 KIZAMIME TOTTAIMON" +#define PAX_SAPIENTICA_LIBRARY_VERSION_NAME "1.2.1 KIZAMIME TOTTAIMON" #endif //char name[ @@ -51,6 +51,7 @@ 更新履歴 バージョン | 更新日 | 概要 6.0.1.0.X | 2024/0X/XX | コピペ用 + 6.0.1.2.1 | 2024/07/15 | シミュレーションの全定数の入力データ化 6.0.1.2.0 | 2024/07/12 | シミュレーション更新版 6.0.1.1.10 | 2024/07/11 | 生命表の入力機能を追加 6.0.1.1.9 | 2024/06/16 | シミュレーションの入力データ読み込みの最適化