diff --git a/Data/Simulations/Sample/District.tsv b/Data/Simulations/Sample/District.tsv index bec315947..8136ab94e 100644 --- a/Data/Simulations/Sample/District.tsv +++ b/Data/Simulations/Sample/District.tsv @@ -1,91 +1,91 @@ -id name region min_pop_placed_per_cell max_pop_placed_per_cell init_pop immigrant -1 satsuma 2 4 20 2270 0 -2 osumi 2 4 20 2400 0 -3 hyuga 2 4 20 1820 0 -4 higo 2 4 20 6426 0 -5 bungo 3 4 20 1226 0 -6 chikugo 3 4 20 1410 0 -7 hizen 3 4 20 1148 0 -8 chikuzen 3 4 20 2664 1 -9 buzen 3 4 20 1122 0 -10 iki 3 4 20 288 0 -11 tsushima 3 4 20 234 0 -12 nagato 5 4 20 976 0 -13 suo 5 4 20 1098 0 -14 aki 5 4 20 1540 0 -15 bingo 5 4 20 1588 0 -16 bitchu 5 4 20 1760 0 -17 mimasaka 5 4 20 1564 0 -18 bizen 5 4 20 1246 0 -19 harima 7 4 20 2358 0 -20 iwami 6 4 20 410 0 -21 izumo 6 4 20 866 0 -22 hoki 6 4 20 532 0 -23 oki 6 4 20 132 0 -24 inaba 6 4 20 554 0 -25 tajima 6 4 20 654 0 -26 tango 6 4 20 388 0 -27 tanba 7 4 20 1636 0 -28 iyo 4 4 20 1726 0 -29 tosa 4 4 20 1030 0 -30 awa 4 4 20 1102 0 -31 sanuki 4 4 20 2158 0 -32 awaji 7 4 20 408 0 -33 kii 7 4 20 1346 0 -34 yamato 8 4 20 2266 0 -35 kawachi 8 4 20 1160 0 -36 yamashiro 8 4 20 1130 0 -37 izumi 8 4 20 348 0 -38 settsu 8 4 20 1130 0 -39 wakasa 11 4 20 378 0 -40 echizen 11 4 20 990 0 -41 kaga 11 4 20 538 0 -42 etchu 11 4 20 754 0 -43 noto 11 4 20 468 0 -44 echigo 11 4 20 610 0 -45 sado 11 4 20 396 0 -46 shima 7 4 20 3374 0 -47 ise 7 4 20 2260 0 -48 iga 7 4 20 432 0 -49 owari 9 4 20 1686 0 -50 mikawa 9 4 20 1686 0 -51 totomi 9 4 20 2346 0 -52 suruga 9 4 20 1442 0 -53 izu 9 4 20 514 0 -54 kai 10 4 20 4746 0 -55 sagami 12 4 20 2078 0 -56 musashi 12 4 20 3690 0 -57 shimosa 12 4 20 2820 0 -58 kazusa 12 4 20 2358 0 -59 awa1 12 4 20 990 0 -60 hitachi 13 4 20 3698 0 -61 omi 7 4 20 2236 0 -62 mino 9 4 20 3202 0 -63 hida 10 4 20 1996 0 -64 shinano 10 4 20 10276 0 -65 kozuke 13 4 20 2466 0 -66 shimotsuke 13 4 20 1692 0 -67 mutsu 15 4 20 5740 0 -68 dewa 14 4 20 940 0 -69 ezo_honshu 15 4 20 2000 0 -70 ezo_hokkaido 16 4 20 0 0 -71 ezo_chishima 16 4 20 0 0 -72 ezo_karafuto 16 4 20 0 0 -73 null1 0 4 20 0 0 -74 null2 0 4 20 0 0 -75 null3 0 4 20 0 0 -76 null4 0 4 20 0 0 -77 null5 0 4 20 0 0 -78 null6 0 4 20 0 0 -79 null7 0 4 20 0 0 -80 null8 0 4 20 0 0 -81 null9 0 4 20 0 0 -82 null10 0 4 20 0 0 -83 null11 0 4 20 0 0 -84 null12 0 4 20 0 0 -85 null13 0 4 20 0 0 -86 null14 0 4 20 0 0 -87 null15 0 4 20 0 0 -88 ogasawara 1 4 20 0 0 -89 izu1 1 4 20 0 0 -90 ryukyu 1 4 20 0 0 +id name ja-JP region min_pop_placed_per_cell max_pop_placed_per_cell init_pop immigrant mtdna_region pop_ad725 +1 satsuma 薩摩 2 4 20 2270 0 kyushu_jomon 38400 +2 osumi 大隅 2 4 20 2400 0 kyushu_jomon 40600 +3 hyuga 日向 2 4 20 1820 0 kyushu_jomon 30800 +4 higo 肥後 2 4 20 6426 0 kyushu_jomon 108700 +5 bungo 豊後 3 4 20 1226 0 kyushu_jomon 51600 +6 chikugo 筑後 3 4 20 1410 0 kyushu_jomon 59300 +7 hizen 肥前 3 4 20 1148 0 kyushu_jomon 48300 +8 chikuzen 筑前 3 4 20 2664 100 kyushu_jomon 112000 +9 buzen 豊前 3 4 20 1122 0 kyushu_jomon 47200 +10 iki 壱岐 3 4 20 288 0 kyushu_jomon 12100 +11 tsushima 対馬 3 4 20 234 0 kyushu_jomon 9900 +12 nagato 長門 5 4 20 976 0 chugoku_jomon 43900 +13 suo 周防 5 4 20 1098 0 chugoku_jomon 49400 +14 aki 安芸 5 4 20 1540 0 chugoku_jomon 69200 +15 bingo 備後 5 4 20 1588 0 chugoku_jomon 71400 +16 bitchu 備中 5 4 20 1760 0 chugoku_jomon 79100 +17 mimasaka 美作 5 4 20 1564 0 chugoku_jomon 70300 +18 bizen 備前 5 4 20 1246 0 chugoku_jomon 56000 +19 harima 播磨 7 4 20 2358 0 kinki_jomon 107600 +20 iwami 石見 6 4 20 410 0 chugoku_jomon 40600 +21 izumo 出雲 6 4 20 866 0 chugoku_jomon 85700 +22 hoki 伯耆 6 4 20 532 0 chugoku_jomon 52700 +23 oki 隠岐 6 4 20 132 0 chugoku_jomon 13200 +24 inaba 因幡 6 4 20 554 0 chugoku_jomon 54900 +25 tajima 但馬 6 4 20 654 0 chugoku_jomon 64800 +26 tango 丹後 6 4 20 388 0 chugoku_jomon 38400 +27 tanba 丹波 7 4 20 1636 0 kinki_jomon 74700 +28 iyo 伊予 4 4 20 1726 0 shikoku_jomon 79100 +29 tosa 土佐 4 4 20 1030 0 shikoku_jomon 47200 +30 awa 阿波 4 4 20 1102 0 shikoku_jomon 50500 +31 sanuki 讃岐 4 4 20 2158 0 shikoku_jomon 98800 +32 awaji 淡路 7 4 20 408 0 kinki_jomon 18700 +33 kii 紀伊 7 4 20 1346 0 kinki_jomon 61500 +34 yamato 大和 8 4 20 2266 0 kinki_jomon 171700 +35 kawachi 河内 8 4 20 1160 0 kinki_jomon 87900 +36 yamashiro 山城 8 4 20 1130 0 kinki_jomon 85700 +37 izumi 和泉 8 4 20 348 0 kinki_jomon 26400 +38 settsu 摂津 8 4 20 1130 0 kinki_jomon 85700 +39 wakasa 若狭 11 4 20 378 0 chubu_jomon 23100 +40 echizen 越前 11 4 20 990 0 chubu_jomon 60400 +41 kaga 加賀 11 4 20 538 0 chubu_jomon 32900 +42 etchu 越中 11 4 20 754 0 chubu_jomon 46100 +43 noto 能登 11 4 20 468 0 chubu_jomon 28600 +44 echigo 越後 11 4 20 610 0 chubu_jomon 37300 +45 sado 佐渡 11 4 20 396 0 chubu_jomon 24200 +46 shima 志摩 7 4 20 3374 0 kinki_jomon 154000 +47 ise 伊勢 7 4 20 2260 0 kinki_jomon 103200 +48 iga 伊賀 7 4 20 432 0 kinki_jomon 19800 +49 owari 尾張 9 4 20 1686 0 chubu_jomon 75800 +50 mikawa 参河 9 4 20 1686 0 chubu_jomon 75800 +51 totomi 遠江 9 4 20 2346 0 chubu_jomon 105400 +52 suruga 駿河 9 4 20 1442 0 chubu_jomon 64800 +53 izu 伊豆 9 4 20 514 0 chubu_jomon 23100 +54 kai 甲斐 10 4 20 4746 0 chubu_jomon 34000 +55 sagami 相模 12 4 20 2078 0 kanto_jomon 73600 +56 musashi 武蔵 12 4 20 3690 0 kanto_jomon 130700 +57 shimosa 下総 12 4 20 2820 0 kanto_jomon 99900 +58 kazusa 上総 12 4 20 2358 0 kanto_jomon 83500 +59 awa1 安房 12 4 20 990 0 kanto_jomon 35100 +60 hitachi 常陸 13 4 20 3698 0 kanto_jomon 168000 +61 omi 近江 7 4 20 2236 0 kinki_jomon 102100 +62 mino 美濃 9 4 20 3202 0 chubu_jomon 143900 +63 hida 飛騨 10 4 20 1996 0 chubu_jomon 14300 +64 shinano 信濃 10 4 20 10276 0 chubu_jomon 73600 +65 kozuke 上野 13 4 20 2466 0 kanto_jomon 112000 +66 shimotsuke 下野 13 4 20 1692 0 kanto_jomon 76900 +67 mutsu 陸奥 15 4 20 5740 0 tohoku_jomon 206500 +68 dewa 出羽 14 4 20 940 0 tohoku_jomon 78000 +69 ezo_honshu 蝦夷(本州) 15 4 20 2000 0 tohoku_jomon 0 +70 ezo_hokkaido 蝦夷(北海道) 16 4 20 0 0 hokkaido_jomon 0 +71 ezo_chishima 蝦夷(千島列島) 16 4 20 0 0 hokkaido_jomon 0 +72 ezo_karafuto 蝦夷(樺太) 16 4 20 0 0 hokkaido_jomon 0 +73 toraijin_land 渡来人 0 0 0 0 0 toraijin 0 +74 null_a 0 4 20 0 0 0 +75 null_b 0 4 20 0 0 0 +76 null_c 0 4 20 0 0 0 +77 null_d 0 4 20 0 0 0 +78 null_e 0 4 20 0 0 0 +79 null_f 0 4 20 0 0 0 +80 null_g 0 4 20 0 0 0 +81 null_h 0 4 20 0 0 0 +82 null_i 0 4 20 0 0 0 +83 null_j 0 4 20 0 0 0 +84 null_k 0 4 20 0 0 0 +85 null_l 0 4 20 0 0 0 +86 null_m 0 4 20 0 0 0 +87 null_n 0 4 20 0 0 0 +88 ogasawara 小笠原諸島 1 4 20 0 0 southern_islands_jomon 0 +89 izu1 伊豆諸島 1 4 20 0 0 southern_islands_jomon 0 +90 ryukyu 琉球諸島 1 4 20 0 0 southern_islands_jomon 0 \ No newline at end of file diff --git a/Data/Simulations/Sample/mtDNA.tsv b/Data/Simulations/Sample/mtDNA.tsv new file mode 100644 index 000000000..b037cb03a --- /dev/null +++ b/Data/Simulations/Sample/mtDNA.tsv @@ -0,0 +1,12 @@ +haplo_group_region haplo_dist +korea_jomon D4a/2/D4b/4/M7a/1/N/1 +southern_islands_jomon M7a/6 +kyushu_jomon M7a/21/M80/1/N9a/1/N9b/4 +chugoku_jomon M7a/1 +shikoku_jomon M7a/1/N9b/1 +kinki_jomon N9b/1 +chubu_jomon A/1/A4/1/D4b/1/G2/1/M7/1/M7a/3/M9a/3/N9b/7 +kanto_jomon B4f/1/B5b/1/D4b/1/E1a/1/M7a/7/N/1/N9b/24 +tohoku_jomon D4b/1/D4h/1/M7a/13/N9b/13 +hokkaido_jomon D4h/6/M7a/3/N9b/19 +toraijin B4a/2/B4c/8/B5a/1/B5b/2/D4/5/D4a/5/D4b/19/D4c/8/D4e/3/D4g/8/D4h/3/D4i/2/D4m/1/D5a/2/M7a/41/M9a/3/N9a/6 \ No newline at end of file diff --git a/Data/Simulations/Sample/mtDNA_List.tsv b/Data/Simulations/Sample/mtDNA_List.tsv new file mode 100644 index 000000000..e03abb257 --- /dev/null +++ b/Data/Simulations/Sample/mtDNA_List.tsv @@ -0,0 +1,27 @@ +mtdna +N9b +A +A4 +B4f +E1a +G2 +M80 +N +M7 +M9a +B5b +D4h +N9a +D4b +M7a +D4 +B5a +B4c +B4a +D5a +D4m +D4i +D4g +D4e +D4c +D4a \ No newline at end of file diff --git a/Data/Simulations/Sample/mtDNA_List2.tsv b/Data/Simulations/Sample/mtDNA_List2.tsv new file mode 100644 index 000000000..891c29f05 --- /dev/null +++ b/Data/Simulations/Sample/mtDNA_List2.tsv @@ -0,0 +1,113 @@ +mtdna +A +A* +A14 +A15 +A17 +A18 +A22 +A4 +A5a +A5b +B4* +B4a +B4b +B4c +B4d +B4e +B4f +B5* +B5a +B5b +B6a +C +C1a +C3 +C4 +C4a +C5 +C5a +C5b +C5d +C7a +C7b +D4 +D4* +D4a +D4b +D4c +D4d +D4e +D4g +D4h +D4i +D4j +D4l +D4m +D5a +D5b +D5c +E1* +E1a +F1a +F1b +F1d +F1g +F2g +F2h +F3a +F4a +G1a +G1b +G1c +G2 +G2a +G2b +G3a +G3b +H11 +H15 +H2b +H5b +H6a +HV1 +I1b +I4a +M +M* +M10 +M11 +M7 +M7* +M71 +M7a +M7b +M7c +M8* +M80 +M8a +M9a +N +N9 +N9a +N9b +R +R1b +R9 +T1a +T2a +T2d +U1a +U2e +U4 +U4a +U4c +U5a +U5b +Y +Y1a +Y1b +Z2 +Z3 +Z3a +Z4a \ No newline at end of file diff --git a/Data/Simulations/Settings.tsv b/Data/Simulations/Settings.tsv index 3567abbc2..063057231 100644 --- a/Data/Simulations/Settings.tsv +++ b/Data/Simulations/Settings.tsv @@ -16,7 +16,7 @@ male_marriageable_age_max 70 男性の最大結婚可能年齢(歳) birthable_age_min 15 出産の最小可能年齢(歳) birthable_age_max 50 出産の最大可能年齢(歳) birth_interval 10 出産の間隔:10ヶ月(Step) -marriage_search_range 320 結婚時に近くの集落からエージェントを探す際の探索範囲 +marriage_search_range 320 結婚時に近くの集落からエージェントを探す際の探索距離 grid_length 512 集落をグループ分けする際の1グリッド辺の長さ max_settlement_population 80 集落の最大人数(人) min_move_distance 10 最小移動距離 diff --git a/Library/PAX_MAHOROBA/LocationPoint.hpp b/Library/PAX_MAHOROBA/LocationPoint.hpp index 12bd9622d..44fc7fcf2 100644 --- a/Library/PAX_MAHOROBA/LocationPoint.hpp +++ b/Library/PAX_MAHOROBA/LocationPoint.hpp @@ -678,7 +678,8 @@ 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.getFarmingPopulation() / float(settlement.getPopulation()) * 75.0f; // settlement.getPopulation(); + const float pop_original = settlement.getMostMtDNA() / 27.0f * 75.0f; // settlement.getPopulation(); const std::uint_least8_t pop = (pop_original >= 75) ? 75 : static_cast(pop_original); paxg::Circle(draw_pos, diff --git a/Library/PAX_SAPIENTICA/Simulation/Genome.hpp b/Library/PAX_SAPIENTICA/Simulation/Genome.hpp index 54829efa9..4844aec35 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Genome.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Genome.hpp @@ -69,6 +69,17 @@ namespace paxs { genome.setYDNA(static_cast(dist(engine))); return genome; } + static Genome generateRandomSetMtDNA(const std::uint_least8_t mtdna_) noexcept { + Genome genome; + genome.setChromosome(Chromosome::generateRandom()); + + std::random_device seed_gen; + std::mt19937 engine(seed_gen()); + std::uniform_int_distribution<> dist((std::numeric_limits::min)(), (std::numeric_limits::max)()); + genome.setMtDNA(mtdna_); + genome.setYDNA(static_cast(dist(engine))); + return genome; + } static Genome generateFromParents(const Genome& mother, const Genome& father) noexcept { Genome genome; diff --git a/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp b/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp index a705065c9..b5e219fe6 100644 --- a/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp @@ -16,10 +16,13 @@ ##########################################################################################*/ +#include +#include #include #include #include +#include #include namespace paxs { @@ -32,6 +35,14 @@ namespace paxs { std::uint_least32_t population = 0; // 人口 }; + /// @brief + /// @brief mtDNA の地方区分を表す構造体 + struct mtDNA_Region { + std::vector id{}; + std::vector weight{}; + std::discrete_distribution<> dist{}; + }; + /// @brief A struct that represents a prefecture in Japan. /// @brief 日本の令制国を表す構造体 struct Ryoseikoku { @@ -41,13 +52,179 @@ namespace paxs { std::uint_least32_t settlement_population_min_ad200 = 0; std::uint_least32_t settlement_population_max_ad200 = 0; std::uint_least32_t population[4] = {}; + std::uint_least32_t mtdna_region_hash = 0; }; /// @brief A class that represents a prefecture in Japan. /// @brief 日本の州を表すクラス class JapanProvinces { + private: + + // 項目の ID を返す + std::size_t getMenuIndex(const std::unordered_map& menu, const std::uint_least32_t& str_) const { + return (menu.find(str_) != menu.end()) ? menu.at(str_) : SIZE_MAX; + } + + void inputMtDNA_List(const std::string& japan_provinces_path) noexcept { + + const std::string path = japan_provinces_path + "/mtDNA_List.tsv"; + + paxs::InputFile mtdna_tsv(AppConfig::getInstance()->getRootPath() + path); + if (mtdna_tsv.fail()) { + PAXS_WARNING("Failed to read MtDNA_List TSV file: " + path); + return; + } + // 1 行目を読み込む + if (!(mtdna_tsv.getLine())) { + return; // 何もない場合 + } + // BOM を削除 + mtdna_tsv.deleteBOM(); + // 1 行目を分割する + std::unordered_map menu = mtdna_tsv.splitHashMapMurMur3('\t'); + std::size_t i = 1; + + // 1 行ずつ読み込み(区切りはタブ) + while (mtdna_tsv.getLine()) { + std::vector sub_menu_v = mtdna_tsv.split('\t'); + if ( + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("mtdna")) + ) { + PAXS_WARNING("Failed to read Japan MtDNA_List TSV file: " + path + " at line " + std::to_string(i)); + continue; + } + mtdna_list.emplace_back(sub_menu_v[menu[MurMur3::calcHash("mtdna")]]); + ++i; + } + + } + + void inputMtDNA_Region(const std::string& japan_provinces_path) noexcept { + + const std::string path = japan_provinces_path + "/mtDNA.tsv"; + + paxs::InputFile mtdna_tsv(AppConfig::getInstance()->getRootPath() + path); + if (mtdna_tsv.fail()) { + PAXS_WARNING("Failed to read MtDNA TSV file: " + path); + return; + } + // 1 行目を読み込む + if (!(mtdna_tsv.getLine())) { + return; // 何もない場合 + } + // BOM を削除 + mtdna_tsv.deleteBOM(); + // 1 行目を分割する + std::unordered_map menu = mtdna_tsv.splitHashMapMurMur3('\t'); + std::size_t i = 1; + + // 1 行ずつ読み込み(区切りはタブ) + while (mtdna_tsv.getLine()) { + std::vector sub_menu_v = mtdna_tsv.split('\t'); + if ( + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("haplo_group_region")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("haplo_dist")) + ) { + PAXS_WARNING("Failed to read Japan MtDNA TSV file: " + path + " at line " + std::to_string(i)); + continue; + } + + mtDNA_Region mtdna_region; + std::vector dist = paxs::StringExtensions::split(sub_menu_v[menu[MurMur3::calcHash("haplo_dist")]], '/'); + + if (dist.size() % 2 == 1) { + continue; + } + if (dist.size() <= 1) { + continue; + } + for (int i = 0; i < dist.size(); i += 2) { + for (int j = 0; j < mtdna_list.size();++j) { + // mtDNA の名称の index を取得し、確率分布と一緒に管理 + if (mtdna_list[j] == dist[i]) { + mtdna_region.id.emplace_back(j); + mtdna_region.weight.emplace_back(std::stod(dist[i + 1])); + break; + } + } + } + // 確率分布を生成 + mtdna_region.dist = std::discrete_distribution<>(mtdna_region.weight.begin(), mtdna_region.weight.end()); + + // mtDNA 地方区分のハッシュ + const std::string& mtdna_region_str = sub_menu_v[menu[MurMur3::calcHash("haplo_group_region")]]; + mtdna_region_list.emplace(MurMur3::calcHash(mtdna_region_str.size(), mtdna_region_str.c_str()), mtdna_region); + + ++i; + } + } + + void inputDistrict(const std::string& japan_provinces_path) noexcept { + + const std::string ryoseikoku_tsv_path = japan_provinces_path + "/District.tsv"; + + paxs::InputFile ryoseikoku_tsv(AppConfig::getInstance()->getRootPath() + ryoseikoku_tsv_path); + if (ryoseikoku_tsv.fail()) { + PAXS_WARNING("Failed to read Ryoseikoku TSV file: " + ryoseikoku_tsv_path); + return; + } + // 1 行目を読み込む + if (!(ryoseikoku_tsv.getLine())) { + return; // 何もない場合 + } + // BOM を削除 + ryoseikoku_tsv.deleteBOM(); + // 1 行目を分割する + std::unordered_map menu = ryoseikoku_tsv.splitHashMapMurMur3('\t'); + std::size_t i = 1; + + // 1 行ずつ読み込み(区切りはタブ) + while (ryoseikoku_tsv.getLine()) { + std::vector sub_menu_v = ryoseikoku_tsv.split('\t'); + + if ( + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("id")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("name")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("region")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("min_pop_placed_per_cell")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("max_pop_placed_per_cell")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("init_pop")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("immigrant")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("mtdna_region")) + ) { + PAXS_WARNING("Failed to read Japan region TSV file: " + ryoseikoku_tsv_path + " at line " + std::to_string(i)); + continue; + } + Ryoseikoku ryoseikoku; + ryoseikoku.id = static_cast(std::stoi(sub_menu_v[menu[MurMur3::calcHash("id")]])); + ryoseikoku.name = sub_menu_v[menu[MurMur3::calcHash("name")]]; + ryoseikoku.region_id = static_cast(std::stoi(sub_menu_v[menu[MurMur3::calcHash("region")]])); + ryoseikoku.settlement_population_min_ad200 = std::stoi(sub_menu_v[menu[MurMur3::calcHash("min_pop_placed_per_cell")]]); + ryoseikoku.settlement_population_max_ad200 = std::stoi(sub_menu_v[menu[MurMur3::calcHash("max_pop_placed_per_cell")]]); + ryoseikoku.population[0/*ad200*/] = std::stoi(sub_menu_v[menu[MurMur3::calcHash("init_pop")]]); + ryoseikoku.population[1/*ad725*/] = std::stoi(sub_menu_v[menu[MurMur3::calcHash("immigrant")]]); + + const std::string& mtdna_region_str = sub_menu_v[menu[MurMur3::calcHash("mtdna_region")]]; + ryoseikoku.mtdna_region_hash = MurMur3::calcHash(mtdna_region_str.size(), mtdna_region_str.c_str()); + ryoseikoku_list.emplace_back(ryoseikoku); + ++i; + } + + } + public: - explicit JapanProvinces(const std::string& japan_region_tsv_path, const std::string& ryoseikoku_tsv_path) noexcept { + explicit JapanProvinces(const std::string& japan_provinces_path) noexcept { + + //const std::string japan_region_tsv_path = japan_provinces_path + "/JapanRegion.tsv"; + + inputMtDNA_List(japan_provinces_path); + inputMtDNA_Region(japan_provinces_path); + inputDistrict(japan_provinces_path); + + } + + // 古い実装 + explicit JapanProvinces(const std::string& japan_region_tsv_path, const std::string& ryoseikoku_tsv_path, int aaa) noexcept { std::vector> 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); @@ -124,6 +301,18 @@ namespace paxs { return ryoseikoku_list[0]; } + std::uint_least8_t getMtDNA(const std::uint_least8_t id, std::mt19937& gen) noexcept { + for (const auto& ryoseikoku : ryoseikoku_list) { + if (ryoseikoku.id == id) { + auto& weight_list = mtdna_region_list.at(ryoseikoku.mtdna_region_hash); + return weight_list.id[weight_list.dist(gen)]; + } + } + PAXS_WARNING("Failed to get Ryoseikoku: " + std::to_string(id)); + + auto& weight_list = mtdna_region_list.at(ryoseikoku_list[0].mtdna_region_hash); + return weight_list.id[weight_list.dist(gen)]; + } /// @brief 日本の令制国のIDから人口を取得する /// @param id 日本の令制国のID @@ -166,6 +355,9 @@ namespace paxs { private: std::vector japan_regions; // 日本の地方区分 std::vector ryoseikoku_list; // 日本の令制国 + std::unordered_map mtdna_region_list; // mtDNA 地方区分 + //std::vector mtdna_region_hash_list; // mtDNA ハッシュ計算用 + std::vector mtdna_list; // mtDNA }; diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index 711c8edea..9069621cb 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -343,6 +343,23 @@ namespace paxs { return farming_population; } + /// @brief Get the most mtDNA. + /// @brief 最多 mtDNA を取得 + std::size_t getMostMtDNA() const noexcept { + //std::vector dna_list{}; + //std::vector dna_count_list{}; + + std::size_t mtdna_max = 0; + + for (std::size_t i = 0; i < agents.size(); ++i) { + //for (std::size_t i = 0; i < agents.size(); ++i) { + //if (dna == agents[i].cgetGenome().getMtDNA()) + //} + mtdna_max += agents[i].cgetGenome().getMtDNA(); + } + return mtdna_max / agents.size(); + } + /// @brief Divide the settlement. /// @brief 集落を分割 Settlement divide() noexcept { diff --git a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp index a5d0e8f40..86b038e63 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp @@ -45,7 +45,7 @@ namespace paxs { explicit SettlementSimulator(const std::string& map_list_path, const std::string& japan_provinces_path, const unsigned seed = 0) noexcept : environment(std::make_unique(map_list_path)), gen(seed) { - japan_provinces = std::make_unique(japan_provinces_path + "/JapanRegion.tsv", japan_provinces_path + "/District.tsv"); + japan_provinces = std::make_unique(japan_provinces_path); // ランダムに移動確率を設定 std::uniform_int_distribution<> move_probability_dist{ SimulationConstants::getInstance()->min_move_probability, SimulationConstants::getInstance()->max_move_probability }; @@ -59,7 +59,7 @@ namespace paxs { gen = std::mt19937(seed); japan_provinces.reset(); - japan_provinces = std::make_unique(japan_provinces_path + "/JapanRegion.tsv", japan_provinces_path + "/District.tsv"); + japan_provinces = std::make_unique(japan_provinces_path); // ランダムに移動確率を設定 std::uniform_int_distribution<> move_probability_dist{ SimulationConstants::getInstance()->min_move_probability, SimulationConstants::getInstance()->max_move_probability }; @@ -109,6 +109,30 @@ namespace paxs { std::chrono::system_clock::time_point start_time, end_time, move_time, m_start_time, m_end_time; start_time = std::chrono::system_clock::now(); // 計測開始 + if (step_count % 120 == 0) { + std::size_t pop_num = 0; // 人口数 + std::size_t sat_num = 0; // 集落数 + std::size_t ryopop[90]{}; + + // 地名を描画 + for (const auto& agent : getSettlementGrids()) { + for (const auto& settlement : agent.second.cgetSettlements()) { + ++sat_num; // 集落数を増加させる + pop_num += settlement.getPopulation(); // 人口数を増加させる + + const std::uint_least8_t ryo_id = environment->template getData(MurMur3::calcHash("gbank"), settlement.getPosition()); + if (ryo_id < 90) { + ryopop[ryo_id]+= settlement.getPopulation(); // 地区ごとに人口数を増加させる + } + } + } + pop_ofs << step_count << '\t' << sat_num << '\t' << pop_num << '\t'; + for (int i = 0; i < 90; ++i) { + pop_ofs << ryopop[i] << '\t'; + } + pop_ofs << step_count << '\n'; + } + std::vector> move_list; for (auto& settlement_grid : settlement_grids) { std::vector& settlements = settlement_grid.second.getSettlements(); @@ -194,6 +218,7 @@ namespace paxs { settlement_grid.second.divideSettlements(); } + ++step_count; end_time = std::chrono::system_clock::now(); // 計測終了 processing_time = static_cast(std::chrono::duration_cast(end_time - start_time).count() / 1000.0); } @@ -233,6 +258,7 @@ namespace paxs { KanakumaLifeSpan kanakuma_life_span; std::uint_least64_t emigration_count = 0; + std::uint_least64_t step_count = 0; // 陸の位置のリストを取得 std::vector land_positions; @@ -250,6 +276,8 @@ namespace paxs { }; std::unique_ptr> live_list; + std::ofstream pop_ofs = std::ofstream("pop.txt"); + /// @brief () /// @brief 集落をランダムに配置する前の初期化処理 bool initRandomizeSettlements() { @@ -368,7 +396,7 @@ namespace paxs { settlement.resizeAgents(settlement_population); for (int i = 0; i < settlement_population; ++i) { - Genome genome = Genome::generateRandom(); + Genome genome = Genome::generateRandomSetMtDNA(japan_provinces->getMtDNA((farming>0)? 73/*toraijin*/ : ryoseikoku_id, gen)); const std::uint_least32_t set_lifespan = kanakuma_life_span.setLifeSpan(genome.getGender(), gen); std::uniform_int_distribution<> lifespan_dist{ 0, static_cast(set_lifespan - 1) }; // 性別の乱数分布 @@ -421,7 +449,7 @@ namespace paxs { for (auto& settlement : settlements) { std::vector agents(add_population); for (int i = 0; i < add_population; ++i) { - Genome genome = Genome::generateRandom(); + Genome genome = Genome::generateRandomSetMtDNA(japan_provinces->getMtDNA((farming > 0) ? 73/*toraijin*/ : ryoseikoku_id, gen)); const std::uint_least32_t set_lifespan = kanakuma_life_span.setLifeSpan(genome.getGender(), gen); std::uniform_int_distribution<> lifespan_dist{ 0, static_cast(set_lifespan - 1) }; // 性別の乱数分布 diff --git a/Projects/UnitTest/Source/Simulations/JapanProvincesUnitTest.cpp b/Projects/UnitTest/Source/Simulations/JapanProvincesUnitTest.cpp index 3e6749541..a1db77ee0 100644 --- a/Projects/UnitTest/Source/Simulations/JapanProvincesUnitTest.cpp +++ b/Projects/UnitTest/Source/Simulations/JapanProvincesUnitTest.cpp @@ -46,10 +46,9 @@ TEST (JapanProvincesUnitTest, constructor) { std::cout << paxs::AppConfig::getInstance()->getRootPath() << std::endl; - const std::string japan_region_tsv_path = "Projects/UnitTest/Data/Simulations/JapanRegion.tsv"; - const std::string ryoseikoku_tsv_path = "Projects/UnitTest/Data/Simulations/Ryoseikoku.tsv"; + const std::string japan_region_tsv_path = "Projects/UnitTest/Data/Simulations"; - paxs::JapanProvinces japan_provinces(japan_region_tsv_path, ryoseikoku_tsv_path); + paxs::JapanProvinces japan_provinces(japan_region_tsv_path); EXPECT_EQ(japan_provinces.getJapanRegionPopulation(0), 0); EXPECT_EQ(japan_provinces.getJapanRegionPopulation(2), 64600);