From 53b9d2aa020abb3ec65c831cd4d3c44606a3fa33 Mon Sep 17 00:00:00 2001 From: wanotaitei Date: Thu, 11 Jul 2024 23:30:11 +0900 Subject: [PATCH] add: input life span --- Data/Simulations/Sample/District.tsv | 182 +++++++++--------- Data/Simulations/Sample/LifeSpan.tsv | 102 ++++++++++ Data/Simulations/Settings.tsv | 4 +- Library/PAX_MAHOROBA/Main.hpp | 2 +- .../PAX_SAPIENTICA/Simulation/Environment.hpp | 4 +- .../Simulation/JapanProvinces.hpp | 134 +++++++++---- .../Simulation/KanakumaLifeSpan.hpp | 127 ++++++------ .../PAX_SAPIENTICA/Simulation/Settlement.hpp | 33 ++-- .../Simulation/SettlementSimulator.hpp | 32 +-- .../Simulation/SimulationConst.hpp | 22 ++- .../PAX_SAPIENTICA/Simulation/Simulator.hpp | 4 +- 11 files changed, 414 insertions(+), 232 deletions(-) create mode 100644 Data/Simulations/Sample/LifeSpan.tsv diff --git a/Data/Simulations/Sample/District.tsv b/Data/Simulations/Sample/District.tsv index 937bfed48..a39466bfd 100644 --- a/Data/Simulations/Sample/District.tsv +++ b/Data/Simulations/Sample/District.tsv @@ -1,91 +1,91 @@ -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 5 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 +id name ja-JP region min_pop_placed_per_cell max_pop_placed_per_cell init_pop immigrant increased_immigration mtdna_region pop_ad725 +1 satsuma 薩摩 2 4 20 2270 0 0 kyushu_jomon 38400 +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 +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 +15 bingo 備後 5 4 20 1588 0 0 chugoku_jomon 71400 +16 bitchu 備中 5 4 20 1760 0 0 chugoku_jomon 79100 +17 mimasaka 美作 5 4 20 1564 0 0 chugoku_jomon 70300 +18 bizen 備前 5 4 20 1246 0 0 chugoku_jomon 56000 +19 harima 播磨 7 4 20 2358 0 0 kinki_jomon 107600 +20 iwami 石見 6 4 20 410 0 0 chugoku_jomon 40600 +21 izumo 出雲 6 4 20 866 0 0 chugoku_jomon 85700 +22 hoki 伯耆 6 4 20 532 0 0 chugoku_jomon 52700 +23 oki 隠岐 6 4 20 132 0 0 chugoku_jomon 13200 +24 inaba 因幡 6 4 20 554 0 0 chugoku_jomon 54900 +25 tajima 但馬 6 4 20 654 0 0 chugoku_jomon 64800 +26 tango 丹後 6 4 20 388 0 0 chugoku_jomon 38400 +27 tanba 丹波 7 4 20 1636 0 0 kinki_jomon 74700 +28 iyo 伊予 4 4 20 1726 0 0 shikoku_jomon 79100 +29 tosa 土佐 4 4 20 1030 0 0 shikoku_jomon 47200 +30 awa 阿波 4 4 20 1102 0 0 shikoku_jomon 50500 +31 sanuki 讃岐 4 4 20 2158 0 0 shikoku_jomon 98800 +32 awaji 淡路 7 4 20 408 0 0 kinki_jomon 18700 +33 kii 紀伊 7 4 20 1346 0 0 kinki_jomon 61500 +34 yamato 大和 8 4 20 2266 0 0 kinki_jomon 171700 +35 kawachi 河内 8 4 20 1160 0 0 kinki_jomon 87900 +36 yamashiro 山城 8 4 20 1130 0 0 kinki_jomon 85700 +37 izumi 和泉 8 4 20 348 0 0 kinki_jomon 26400 +38 settsu 摂津 8 4 20 1130 0 0 kinki_jomon 85700 +39 wakasa 若狭 11 4 20 378 0 0 chubu_jomon 23100 +40 echizen 越前 11 4 20 990 0 0 chubu_jomon 60400 +41 kaga 加賀 11 4 20 538 0 0 chubu_jomon 32900 +42 etchu 越中 11 4 20 754 0 0 chubu_jomon 46100 +43 noto 能登 11 4 20 468 0 0 chubu_jomon 28600 +44 echigo 越後 11 4 20 610 0 0 chubu_jomon 37300 +45 sado 佐渡 11 4 20 396 0 0 chubu_jomon 24200 +46 shima 志摩 7 4 20 3374 0 0 kinki_jomon 154000 +47 ise 伊勢 7 4 20 2260 0 0 kinki_jomon 103200 +48 iga 伊賀 7 4 20 432 0 0 kinki_jomon 19800 +49 owari 尾張 9 4 20 1686 0 0 chubu_jomon 75800 +50 mikawa 参河 9 4 20 1686 0 0 chubu_jomon 75800 +51 totomi 遠江 9 4 20 2346 0 0 chubu_jomon 105400 +52 suruga 駿河 9 4 20 1442 0 0 chubu_jomon 64800 +53 izu 伊豆 9 4 20 514 0 0 chubu_jomon 23100 +54 kai 甲斐 10 4 20 4746 0 0 chubu_jomon 34000 +55 sagami 相模 12 4 20 2078 0 0 kanto_jomon 73600 +56 musashi 武蔵 12 4 20 3690 0 0 kanto_jomon 130700 +57 shimosa 下総 12 4 20 2820 0 0 kanto_jomon 99900 +58 kazusa 上総 12 4 20 2358 0 0 kanto_jomon 83500 +59 awa1 安房 12 4 20 990 0 0 kanto_jomon 35100 +60 hitachi 常陸 13 4 20 3698 0 0 kanto_jomon 168000 +61 omi 近江 7 4 20 2236 0 0 kinki_jomon 102100 +62 mino 美濃 9 4 20 3202 0 0 chubu_jomon 143900 +63 hida 飛騨 10 4 20 1996 0 0 chubu_jomon 14300 +64 shinano 信濃 10 4 20 10276 0 0 chubu_jomon 73600 +65 kozuke 上野 13 4 20 2466 0 0 kanto_jomon 112000 +66 shimotsuke 下野 13 4 20 1692 0 0 kanto_jomon 76900 +67 mutsu 陸奥 15 4 20 5740 0 0 tohoku_jomon 206500 +68 dewa 出羽 14 4 20 940 0 0 tohoku_jomon 78000 +69 ezo_honshu 蝦夷(本州) 15 4 20 2000 0 0 tohoku_jomon 0 +70 ezo_hokkaido 蝦夷(北海道) 16 4 20 0 0 0 hokkaido_jomon 0 +71 ezo_chishima 蝦夷(千島列島) 16 4 20 0 0 0 hokkaido_jomon 0 +72 ezo_karafuto 蝦夷(樺太) 16 4 20 0 0 0 hokkaido_jomon 0 +73 toraijin_land 渡来人 0 0 0 0 0 0 toraijin 0 +74 null_a 0 4 20 0 0 0 0 +75 null_b 0 4 20 0 0 0 0 +76 null_c 0 4 20 0 0 0 0 +77 null_d 0 4 20 0 0 0 0 +78 null_e 0 4 20 0 0 0 0 +79 null_f 0 4 20 0 0 0 0 +80 null_g 0 4 20 0 0 0 0 +81 null_h 0 4 20 0 0 0 0 +82 null_i 0 4 20 0 0 0 0 +83 null_j 0 4 20 0 0 0 0 +84 null_k 0 4 20 0 0 0 0 +85 null_l 0 4 20 0 0 0 0 +86 null_m 0 4 20 0 0 0 0 +87 null_n 0 4 20 0 0 0 0 +88 ogasawara 小笠原諸島 1 4 20 0 0 0 southern_islands_jomon 0 +89 izu1 伊豆諸島 1 4 20 0 0 0 southern_islands_jomon 0 +90 ryukyu 琉球諸島 1 4 20 0 0 0 southern_islands_jomon 0 diff --git a/Data/Simulations/Sample/LifeSpan.tsv b/Data/Simulations/Sample/LifeSpan.tsv new file mode 100644 index 000000000..ce9d5f2a5 --- /dev/null +++ b/Data/Simulations/Sample/LifeSpan.tsv @@ -0,0 +1,102 @@ +age jomon_male_ndx jomon_female_ndx yayoi_male_ndx yayoi_female_ndx +0 30 30 30 30 +1 2.437705134 2.422221692 2.391664237 2.402062336 +2 1.78945613 1.783878323 1.783796459 1.784209906 +3 1.334924021 1.334230387 1.348162321 1.343924269 +4 1.018727091 1.020392441 1.037648899 1.032267532 +5 0.802479272 0.80361532 0.817713344 0.81334164 +6 0.655778375 0.655791861 0.663089697 0.660941915 +7 0.556825112 0.555287235 0.554270665 0.554839259 +8 0.486852049 0.483506373 0.475012313 0.477999064 +9 0.431286386 0.427241682 0.413921596 0.418442538 +10 0.379890123 0.375480512 0.36199534 0.366542513 +11 0.326440371 0.323371647 0.314746101 0.317706727 +12 0.273664438 0.272972387 0.272283859 0.272645501 +13 0.227152567 0.228494286 0.236388819 0.233889181 +14 0.193239192 0.196509734 0.211201647 0.206382746 +15 0.176802932 0.18083179 0.199790013 0.193499826 +16 0.181770948 0.186105135 0.206235376 0.199596173 +17 0.218122631 0.221631598 0.237455448 0.232445229 +18 0.30687301 0.305921021 0.303795888 0.30494173 +19 0.494121381 0.479514382 0.423414456 0.441616446 +20 0.851916615 0.794502894 0.608177675 0.664244346 +21 1.424597695 1.281297953 0.847014532 0.969428944 +22 2.123243782 1.853118085 1.083143842 1.288936974 +23 2.640908518 2.259568974 1.22334685 1.491187448 +24 2.734948092 2.339028266 1.234072146 1.516167154 +25 2.478298002 2.12678264 1.144802036 1.396951423 +26 2.103173353 1.827071636 1.030797587 1.238265276 +27 1.807526449 1.593703948 0.949286702 1.119640269 +28 1.645967406 1.463937761 0.913807667 1.06056258 +29 1.613966771 1.443971372 0.926131516 1.064434539 +30 1.691364255 1.507964485 0.966798629 1.110491657 +31 1.842519231 1.627588623 1.010207701 1.172278342 +32 2.029201896 1.767595875 1.034218125 1.223660583 +33 2.200065547 1.884478782 1.022731479 1.241001967 +34 2.306966127 1.94995506 0.987397994 1.227020118 +35 2.319052333 1.948511324 0.949396937 1.196497467 +36 2.231009411 1.887497335 0.933648277 1.172451165 +37 2.063633009 1.784747726 0.963244019 1.176417896 +38 1.849662209 1.659019816 1.04782017 1.214855668 +39 1.623028808 1.526338079 1.194627061 1.288402816 +40 1.409226715 1.397704032 1.39062875 1.382478267 +41 1.22406508 1.28002472 1.59882713 1.472219417 +42 1.072568002 1.175990741 1.768753534 1.533158667 +43 0.953597564 1.086158829 1.846739038 1.544598672 +44 0.863205559 1.009154763 1.823708068 1.507486837 +45 0.796424567 0.943210818 1.725908514 1.436095705 +46 0.749309739 0.887546418 1.59950999 1.352446875 +47 0.718824301 0.842064123 1.487330769 1.277532464 +48 0.70337853 0.809176925 1.410961593 1.224237062 +49 0.702602234 0.792330015 1.381409887 1.200891855 +50 0.716481905 0.795683896 1.400848971 1.211375297 +51 0.745044982 0.824016534 1.468668084 1.258048175 +52 0.785880921 0.876845521 1.577337844 1.336813219 +53 0.832274594 0.948785429 1.710513546 1.436872811 +54 0.871980345 1.020808086 1.833807319 1.532328581 +55 0.88658257 1.061135757 1.896968739 1.584047052 +56 0.859087487 1.039919578 1.854514709 1.556154509 +57 0.78152153 0.943786462 1.687737838 1.431629198 +58 0.662597209 0.794674622 1.427898664 1.232892595 +59 0.524652985 0.630252194 1.132974556 1.003536444 +60 0.391348654 0.481811993 0.857017245 0.785181167 +61 0.278968582 0.364634353 0.630198421 0.602655117 +62 0.192746591 0.279339354 0.460086918 0.462847725 +63 0.130716415 0.220847284 0.340958277 0.362712193 +64 0.087911997 0.183030724 0.262283331 0.295399004 +65 0.059083993 0.161032325 0.214369145 0.254453411 +66 0.03986605 0.151187331 0.188891595 0.234103668 +67 0.027049047 0.151098625 0.180480534 0.230453855 +68 0.018460498 0.158379372 0.184924333 0.239679595 +69 0.041234224 0.169434873 0.197510171 0.256281492 +70 0.000146375 0.179075981 0.211901598 0.27228928 +71 0.00000007768994035 0.180407873 0.218595877 0.276492496 +72 0 0.169943384 0.21114322 0.262516494 +73 0 0.149624169 0.189768335 0.232502444 +74 0 0.12507817 0.160752581 0.194993998 +75 0 0.102442262 0.13245485 0.159883167 +76 0 0.084464904 0.109194615 0.131786838 +77 0 0.071653458 0.092215395 0.111703462 +78 0 0.063141588 0.080656337 0.09834685 +79 0 0.057478158 0.072738066 0.089451728 +80 0 0.053460216 0.066959162 0.083130151 +81 0 0.049932576 0.061891463 0.077563894 +82 0 0.046228586 0.05673737 0.071709793 +83 0 0.042162199 0.051288511 0.065285754 +84 0 0.037846429 0.045683276 0.058480348 +85 0 0.03364408 0.040334494 0.051869619 +86 0 0.029812584 0.035519858 0.045857162 +87 0 0.026495249 0.031379928 0.040662453 +88 0 0.023703378 0.02790621 0.036297154 +89 0 0.021337669 0.024969709 0.032601186 +90 0 0.019294027 0.022441381 0.029409245 +91 0 0.01746355 0.020191846 0.026550903 +92 0 0.01577806 0.018140045 0.023920666 +93 0 0.014211485 0.016252987 0.021479294 +94 0 0.012756934 0.014519076 0.019217095 +95 0 0.011425773 0.012946487 0.01715196 +96 0 0.010223948 0.01153748 0.015292617 +97 0 0.009150679 0.010287199 0.013636824 +98 0 0.008198401 0.00918395 0.012171745 +99 0 0.007352375 0.008208899 0.010873638 +100 0 0.06246772 0.069174862 0.088069649 \ No newline at end of file diff --git a/Data/Simulations/Settings.tsv b/Data/Simulations/Settings.tsv index c933fff21..0c69a081f 100644 --- a/Data/Simulations/Settings.tsv +++ b/Data/Simulations/Settings.tsv @@ -22,8 +22,8 @@ birthable_age_min 15 出産の最小可能年齢(歳) birthable_age_max 50 出産の最大可能年齢(歳) #Childbirth -------------------- #出産 -------------------------------------------------- birth_interval 10 妊娠から出産までのStep間隔(step) -hunter_gatherer_stillbirth_rate 0.18 狩猟採集死産率 -farming_stillbirth_rate 0.16 水田稲作死産率 +hunter_gatherer_stillbirth_rate 0 狩猟採集死産率 +farming_stillbirth_rate 0 水田稲作死産率 child_agriculture_priority 0.7 片親が農耕文化を持ち、もう一方の片親が農耕文化を持たない時の農耕文化継承の優先度 #Movement -------------------- #移動 -------------------------------------------------- max_hunter_gatherer_settlement_population 25 狩猟採集集落の最大人数(人) diff --git a/Library/PAX_MAHOROBA/Main.hpp b/Library/PAX_MAHOROBA/Main.hpp index ddf66e82c..274e872aa 100644 --- a/Library/PAX_MAHOROBA/Main.hpp +++ b/Library/PAX_MAHOROBA/Main.hpp @@ -8,7 +8,7 @@ [License] Distributed under the CC0 1.0. https://creativecommons.org/publicdomain/zero/1.0/ ##########################################################################################*/ - +//#define PAXS_DEVELOPMENT #ifndef PAX_MAHOROBA_MAIN_HPP #define PAX_MAHOROBA_MAIN_HPP diff --git a/Library/PAX_SAPIENTICA/Simulation/Environment.hpp b/Library/PAX_SAPIENTICA/Simulation/Environment.hpp index ffd7f0f75..3942cc62b 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Environment.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Environment.hpp @@ -122,7 +122,7 @@ namespace paxs { /// @brief Get the land position list. /// @brief 陸の位置リストの取得 void getLandPositions(std::vector& keys) const { - std::get>(*data_map.at(MurMur3::calcHash("district"))).getKeys(keys); + std::get>(*data_map.at(SimulationConstants::getInstance()->land_key)).getKeys(keys); } /// @brief Is it possible to live? @@ -161,7 +161,7 @@ namespace paxs { /// @brief 陸地かどうかの判定 virtual bool isLand(const Vector2& position) const noexcept { try { - auto value = getData(MurMur3::calcHash("district"), position); + auto value = getData(SimulationConstants::getInstance()->land_key, position); return static_cast(value) >= static_cast(1); } catch (const std::exception&) { diff --git a/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp b/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp index 01df1c02c..6ecef4fb0 100644 --- a/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace paxs { @@ -43,6 +44,19 @@ namespace paxs { std::discrete_distribution<> dist{}; }; + /// @brief + /// @brief 生命表 + struct lifeSpan { + std::vector weight_farming_female{}; // 農耕民の女性の重み + std::vector weight_farming_male{}; // 農耕民の男性の重み + std::vector weight_hunter_gatherer_female{}; // 狩猟採集民の女性の重み + std::vector weight_hunter_gatherer_male{}; // 狩猟採集民の男性の重み + std::discrete_distribution<> dist_farming_female{}; + std::discrete_distribution<> dist_farming_male{}; + std::discrete_distribution<> dist_hunter_gatherer_female{}; + std::discrete_distribution<> dist_hunter_gatherer_male{}; + }; + /// @brief A struct that represents a prefecture in Japan. /// @brief 日本の地区を表す構造体 struct District { @@ -51,7 +65,10 @@ namespace paxs { std::uint_least8_t region_id = 0; // 対応する地方区分ID 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 init_pop = 0; + std::uint_least32_t immigrant = 0; + double immigrant_f64 = 0; + double increased_immigration = 0; std::uint_least32_t mtdna_region_hash = 0; }; @@ -99,6 +116,56 @@ namespace paxs { } + void inputLifeSpan(const std::string& japan_provinces_path) noexcept { + + const std::string path = japan_provinces_path + "/LifeSpan.tsv"; + + paxs::InputFile life_span_tsv(AppConfig::getInstance()->getRootPath() + path); + if (life_span_tsv.fail()) { + PAXS_WARNING("Failed to read LifeSpan TSV file: " + path); + return; + } + // 1 行目を読み込む + if (!(life_span_tsv.getLine())) { + return; // 何もない場合 + } + // BOM を削除 + life_span_tsv.deleteBOM(); + // 1 行目を分割する + std::unordered_map menu = life_span_tsv.splitHashMapMurMur3('\t'); + std::size_t i = 1; + + // 1 行ずつ読み込み(区切りはタブ) + while (life_span_tsv.getLine()) { + std::vector sub_menu_v = life_span_tsv.split('\t'); + if ( + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("jomon_male_ndx")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("jomon_female_ndx")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("yayoi_male_ndx")) || + sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("yayoi_female_ndx")) + ) { + PAXS_WARNING("Failed to read Japan LifeSpan TSV file: " + path + " at line " + std::to_string(i)); + + life_span.weight_farming_female.emplace_back(0.0); + life_span.weight_farming_male.emplace_back(0.0); + life_span.weight_hunter_gatherer_female.emplace_back(0.0); + life_span.weight_hunter_gatherer_male.emplace_back(0.0); + continue; + } + life_span.weight_farming_female.emplace_back(std::stod(sub_menu_v[menu[MurMur3::calcHash("yayoi_female_ndx")]])); + life_span.weight_farming_male.emplace_back(std::stod(sub_menu_v[menu[MurMur3::calcHash("yayoi_male_ndx")]])); + life_span.weight_hunter_gatherer_female.emplace_back(std::stod(sub_menu_v[menu[MurMur3::calcHash("jomon_female_ndx")]])); + life_span.weight_hunter_gatherer_male.emplace_back(std::stod(sub_menu_v[menu[MurMur3::calcHash("jomon_male_ndx")]])); + ; + // 確率分布を生成 + life_span.dist_farming_female = std::discrete_distribution<>(life_span.weight_farming_female.begin(), life_span.weight_farming_female.end()); + life_span.dist_farming_male = std::discrete_distribution<>(life_span.weight_farming_male.begin(), life_span.weight_farming_male.end()); + life_span.dist_hunter_gatherer_female = std::discrete_distribution<>(life_span.weight_hunter_gatherer_female.begin(), life_span.weight_hunter_gatherer_female.end()); + life_span.dist_hunter_gatherer_male = std::discrete_distribution<>(life_span.weight_hunter_gatherer_male.begin(), life_span.weight_hunter_gatherer_male.end()); + ++i; + } + } + void inputMtDNA_Region(const std::string& japan_provinces_path) noexcept { const std::string path = japan_provinces_path + "/mtDNA.tsv"; @@ -201,8 +268,10 @@ namespace paxs { district.region_id = static_cast(std::stoi(sub_menu_v[menu[MurMur3::calcHash("region")]])); district.settlement_population_min_ad200 = std::stoi(sub_menu_v[menu[MurMur3::calcHash("min_pop_placed_per_cell")]]); district.settlement_population_max_ad200 = std::stoi(sub_menu_v[menu[MurMur3::calcHash("max_pop_placed_per_cell")]]); - district.population[0/*ad200*/] = std::stoi(sub_menu_v[menu[MurMur3::calcHash("init_pop")]]); - district.population[1/*ad725*/] = std::stoi(sub_menu_v[menu[MurMur3::calcHash("immigrant")]]); + district.init_pop = std::stoi(sub_menu_v[menu[MurMur3::calcHash("init_pop")]]); + district.immigrant = std::stoi(sub_menu_v[menu[MurMur3::calcHash("immigrant")]]); + district.immigrant_f64 = static_cast(district.immigrant); + district.increased_immigration = std::stod(sub_menu_v[menu[MurMur3::calcHash("increased_immigration")]]); const std::string& mtdna_region_str = sub_menu_v[menu[MurMur3::calcHash("mtdna_region")]]; district.mtdna_region_hash = MurMur3::calcHash(mtdna_region_str.size(), mtdna_region_str.c_str()); @@ -220,47 +289,19 @@ namespace paxs { inputMtDNA_List(japan_provinces_path); inputMtDNA_Region(japan_provinces_path); inputDistrict(japan_provinces_path); + inputLifeSpan(japan_provinces_path); } - // 古い実装 - explicit JapanProvinces(const std::string& japan_region_tsv_path, const std::string& district_tsv_path) 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); - } - - std::vector> district_tsv = File::readTSV(AppConfig::getInstance()->getRootPath() + district_tsv_path); - if (district_tsv.empty()) { - PAXS_WARNING("Failed to read District TSV file: " + district_tsv_path); - } - - for (std::size_t i = 1; i < japan_region_tsv.size(); ++i) { - try { - JapanRegion japan_region; - japan_region.id = static_cast(std::stoi(japan_region_tsv[i][0])); - japan_region.name = japan_region_tsv[i][1]; - japan_region.population = std::stoi(japan_region_tsv[i][2]); - japan_regions.emplace_back(japan_region); - } catch (const std::invalid_argument&) { - PAXS_WARNING("Failed to read Japan region TSV file: " + japan_region_tsv_path + " at line " + std::to_string(i)); - } - } - - for (std::size_t i = 1; i < district_tsv.size(); ++i) { - try { - District district; - district.id = static_cast(std::stoi(district_tsv[i][0])); - district.name = district_tsv[i][1]; - district.region_id = static_cast(std::stoi(district_tsv[i][2])); - district.settlement_population_min_ad200 = std::stoi(district_tsv[i][3]); - district.settlement_population_max_ad200 = std::stoi(district_tsv[i][4]); - district.population[0/*ad200*/] = std::stoi(district_tsv[i][5]); - district.population[1/*ad725*/] = std::stoi(district_tsv[i][6]); - district_list.emplace_back(district); - } catch (const std::invalid_argument&) { - PAXS_WARNING("Failed to read District TSV file: " + district_tsv_path + " at line " + std::to_string(i)); - } + /// @brief + /// @brief 更新処理 + void update() noexcept { + for (auto& district : district_list) { + // 渡来人増加が0の場合は処理しない + if (district.increased_immigration == 0.0) continue; + // 渡来人の増加 + district.immigrant_f64 += district.increased_immigration; + district.immigrant = static_cast(district.immigrant_f64); } } @@ -320,6 +361,14 @@ namespace paxs { return mtdna_list.size(); } + AgeType getLifeSpan(const bool is_farming, const bool is_female, std::mt19937& gen) noexcept { + return static_cast((is_farming)? + ((is_female) ? life_span.dist_farming_female(gen): + life_span.dist_farming_male(gen)) : + ((is_female) ? life_span.dist_hunter_gatherer_female(gen) : + life_span.dist_hunter_gatherer_male(gen))); + } + /// @brief 日本の地区のIDから人口を取得する /// @param id 日本の地区のID @@ -328,7 +377,7 @@ namespace paxs { std::uint_least32_t getDistrictPopulationAd200(const std::uint_least8_t id) const noexcept { for (const auto& district : district_list) { if (district.id == id) { - return district.population[0/*ad200*/]; + return district.init_pop; } } PAXS_WARNING("Failed to get District population: " + std::to_string(id)); @@ -365,6 +414,7 @@ namespace paxs { std::unordered_map mtdna_region_list; // mtDNA 地方区分 //std::vector mtdna_region_hash_list; // mtDNA ハッシュ計算用 std::vector mtdna_list; // mtDNA + lifeSpan life_span; }; diff --git a/Library/PAX_SAPIENTICA/Simulation/KanakumaLifeSpan.hpp b/Library/PAX_SAPIENTICA/Simulation/KanakumaLifeSpan.hpp index d1a03fe28..3a027d41b 100644 --- a/Library/PAX_SAPIENTICA/Simulation/KanakumaLifeSpan.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/KanakumaLifeSpan.hpp @@ -19,6 +19,7 @@ #include #include +#include namespace paxs { @@ -27,75 +28,81 @@ namespace paxs { class KanakumaLifeSpan { private: - // 金隈遺跡の寿命データ + //// 金隈遺跡の寿命データ - std::uniform_int_distribution<> life_person_num{ 1, 136 }; // 金隈遺跡の寿命データによる人間の数 - std::uniform_int_distribution<> life_child_num{ 1, 35 }; // 金隈遺跡の寿命データによる子供の数 + //std::uniform_int_distribution<> life_person_num{ 1, 136 }; // 金隈遺跡の寿命データによる人間の数 + //std::uniform_int_distribution<> life_child_num{ 1, 35 }; // 金隈遺跡の寿命データによる子供の数 - std::uniform_int_distribution<> life_male_adult_num{ 1, 38 }; // 金隈遺跡の寿命データによる男性の数 - std::uniform_int_distribution<> life_female_adult_num{ 1, 44 }; // 金隈遺跡の寿命データによる女性の数 + //std::uniform_int_distribution<> life_male_adult_num{ 1, 38 }; // 金隈遺跡の寿命データによる男性の数 + //std::uniform_int_distribution<> life_female_adult_num{ 1, 44 }; // 金隈遺跡の寿命データによる女性の数 - std::uniform_int_distribution<> life_infant_exp_dist{ 1, 1 * SimulationConstants::getInstance()->steps_per_year }; // 乳児の寿命の乱数分布 - std::uniform_int_distribution<> life_toddler_exp_dist{ 1 * SimulationConstants::getInstance()->steps_per_year + 1, 6 * SimulationConstants::getInstance()->steps_per_year }; // 幼児の寿命の乱数分布 - std::uniform_int_distribution<> life_child_exp_dist{ 6 * SimulationConstants::getInstance()->steps_per_year + 1, 12 * SimulationConstants::getInstance()->steps_per_year }; // 小児の寿命の乱数分布 - std::uniform_int_distribution<> life_young_exp_dist{ 12 * SimulationConstants::getInstance()->steps_per_year + 1, 20 * SimulationConstants::getInstance()->steps_per_year }; // 若年の寿命の乱数分布 - std::uniform_int_distribution<> life_adult_exp_dist{ 20 * SimulationConstants::getInstance()->steps_per_year + 1, 40 * SimulationConstants::getInstance()->steps_per_year }; // 成年の寿命の乱数分布 - std::uniform_int_distribution<> life_mature_exp_dist{ 40 * SimulationConstants::getInstance()->steps_per_year + 1, 60 * SimulationConstants::getInstance()->steps_per_year }; // 熟年の寿命の乱数分布 - std::uniform_int_distribution<> life_older_exp_dist{ 60 * SimulationConstants::getInstance()->steps_per_year + 1, 80 * SimulationConstants::getInstance()->steps_per_year }; // 老年の寿命の乱数分布 + //std::uniform_int_distribution<> life_infant_exp_dist{ 1, 1 * SimulationConstants::getInstance()->steps_per_year }; // 乳児の寿命の乱数分布 + //std::uniform_int_distribution<> life_toddler_exp_dist{ 1 * SimulationConstants::getInstance()->steps_per_year + 1, 6 * SimulationConstants::getInstance()->steps_per_year }; // 幼児の寿命の乱数分布 + //std::uniform_int_distribution<> life_child_exp_dist{ 6 * SimulationConstants::getInstance()->steps_per_year + 1, 12 * SimulationConstants::getInstance()->steps_per_year }; // 小児の寿命の乱数分布 + //std::uniform_int_distribution<> life_young_exp_dist{ 12 * SimulationConstants::getInstance()->steps_per_year + 1, 20 * SimulationConstants::getInstance()->steps_per_year }; // 若年の寿命の乱数分布 + //std::uniform_int_distribution<> life_adult_exp_dist{ 20 * SimulationConstants::getInstance()->steps_per_year + 1, 40 * SimulationConstants::getInstance()->steps_per_year }; // 成年の寿命の乱数分布 + //std::uniform_int_distribution<> life_mature_exp_dist{ 40 * SimulationConstants::getInstance()->steps_per_year + 1, 60 * SimulationConstants::getInstance()->steps_per_year }; // 熟年の寿命の乱数分布 + //std::uniform_int_distribution<> life_older_exp_dist{ 60 * SimulationConstants::getInstance()->steps_per_year + 1, 80 * SimulationConstants::getInstance()->steps_per_year }; // 老年の寿命の乱数分布 public: - /// @brief 英語未翻訳 - /// @brief 寿命を決定する - AgeType setAdultLifeSpan(const bool is_male_, std::mt19937& gen) { - // もし大人だったら - if (!is_male_) { // 女性の場合 - const AgeType adult_type = static_cast(life_male_adult_num(gen)); - - if (adult_type <= 14) { // 成年 - return static_cast(life_adult_exp_dist(gen)); - } - else if (adult_type <= (14 + 26)) { // 熟年 - return static_cast(life_mature_exp_dist(gen)); - } - // 老年 - return static_cast(life_older_exp_dist(gen)); - } - else { // 男性の場合 - const AgeType adult_type = static_cast(life_female_adult_num(gen)); - - if (adult_type <= 19) { // 成年 - return static_cast(life_adult_exp_dist(gen)); - } - else if (adult_type <= (19 + 19)) { // 熟年 - return static_cast(life_mature_exp_dist(gen)); - } - } - // 老年 - return static_cast(life_older_exp_dist(gen)); - } + paxs::JapanProvinces* japan_provinces; + KanakumaLifeSpan() = default; + + ///// @brief 英語未翻訳 + ///// @brief 寿命を決定する + //AgeType setAdultLifeSpan(const bool is_male_, std::mt19937& gen) { + // // もし大人だったら + // if (!is_male_) { // 女性の場合 + // const AgeType adult_type = static_cast(life_male_adult_num(gen)); + + // if (adult_type <= 14) { // 成年 + // return static_cast(life_adult_exp_dist(gen)); + // } + // else if (adult_type <= (14 + 26)) { // 熟年 + // return static_cast(life_mature_exp_dist(gen)); + // } + // // 老年 + // return static_cast(life_older_exp_dist(gen)); + // } + // else { // 男性の場合 + // const AgeType adult_type = static_cast(life_female_adult_num(gen)); + + // if (adult_type <= 19) { // 成年 + // return static_cast(life_adult_exp_dist(gen)); + // } + // else if (adult_type <= (19 + 19)) { // 熟年 + // return static_cast(life_mature_exp_dist(gen)); + // } + // } + // // 老年 + // return static_cast(life_older_exp_dist(gen)); + //} /// @brief 英語未翻訳 /// @brief 寿命を決定する - AgeType setLifeSpan(const bool is_male_, std::mt19937& gen) { - - if (life_person_num(gen) <= 37) { // もし子供だったら - const AgeType child_type = static_cast(life_child_num(gen)); - - if (child_type <= 6) { // 乳児 - return static_cast(life_infant_exp_dist(gen)); - } - else if (child_type <= (6 + 22)) { // 幼児 - return static_cast(life_toddler_exp_dist(gen)); - } - else if (child_type <= (6 + 22 + 5)) { // 小児 - return static_cast(life_child_exp_dist(gen)); - } - // 若年 - return static_cast(life_young_exp_dist(gen)); - } - // もし大人だったら - return setAdultLifeSpan(is_male_, gen); + AgeType setLifeSpan(const bool is_farming_, const bool is_male_, std::mt19937& gen) { + + return static_cast(japan_provinces->getLifeSpan(is_farming_, !is_male_, gen) * SimulationConstants::getInstance()->steps_per_year + + SimulationConstants::getInstance()->step_per_year_dist(gen)); + + //if (life_person_num(gen) <= 37) { // もし子供だったら + // const AgeType child_type = static_cast(life_child_num(gen)); + + // if (child_type <= 6) { // 乳児 + // return static_cast(life_infant_exp_dist(gen)); + // } + // else if (child_type <= (6 + 22)) { // 幼児 + // return static_cast(life_toddler_exp_dist(gen)); + // } + // else if (child_type <= (6 + 22 + 5)) { // 小児 + // return static_cast(life_child_exp_dist(gen)); + // } + // // 若年 + // return static_cast(life_young_exp_dist(gen)); + //} + //// もし大人だったら + //return setAdultLifeSpan(is_male_, gen); } }; diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index 20e925108..c807c5476 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -32,18 +32,10 @@ #include #include -// M_PI が定義されていない場合 -#ifndef M_PI -#define M_PI 3.141592653589 -#endif - namespace paxs { namespace settlement { - // std::sqrt(2 * M_PI) - constexpr double sqrt_2_x_pi = static_cast(2.506628275); - // 結婚・出産の定数 constexpr double sigma = 0.25; constexpr double sigma_p_2 = sigma * sigma; @@ -495,17 +487,18 @@ namespace paxs { } // 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 + )); Genome genome = Genome::generateFromParents(*gen, agent.cgetGenome(), agent.cgetPartnerGenome()); children.emplace_back(Agent( UniqueIdentification::generate(), //0, // TODO: 名前ID 0, - kanakuma_life_span.setLifeSpan(genome.isMale(), *gen), + kanakuma_life_span.setLifeSpan(farming > 0, genome.isMale(), *gen), genome, - (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 - )), + farming, //(((*gen)() % 2) == 0) ? agent.cgetFarming() : agent.cgetPartnerFarming(), (((*gen)() % 2) == 0) ? agent.cgetHunterGatherer() : agent.cgetPartnerHunterGatherer() )); @@ -528,7 +521,7 @@ namespace paxs { if (agents.size() >= 60) { Genome genome = Genome::generateRandom(*gen); - const AgeType set_lifespan = kanakuma_life_span.setLifeSpan(genome.isMale(), *gen); + const AgeType set_lifespan = kanakuma_life_span.setLifeSpan(true, genome.isMale(), *gen); std::uniform_int_distribution<> lifespan_dist{ (std::min)(18 * SimulationConstants::getInstance()->steps_per_year + 1, static_cast(set_lifespan - 1)), @@ -587,12 +580,14 @@ namespace paxs { /// @brief Is the agent married? /// @brief 確率で結婚するかどうかを返す bool isMarried(const double age) noexcept { - auto x = [](double age) { return (age - 13) / 8.5; }; + // 婚姻可能年齢の上限値以上だったら結婚しない + 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 weight = [=](double age) { - return std::exp(-std::pow(std::log(x(age)), 2) / settlement::sigma_p_2_x_2) / (x(age) * settlement::sigma_x_sqrt_2_x_pi); + 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.98f / 101.8f); + const double threshold = static_cast(weight(age)) * (0.98 / 101.8); return SimulationConstants::getInstance()->random_dist(*gen) < threshold; } @@ -602,10 +597,10 @@ namespace paxs { bool isAbleToGiveBirth(const double age) noexcept { auto x = [](double age) { return (age - 14) / 8.5; }; auto weight = [=](double age) { - return std::exp(-std::pow(std::log(x(age)), 2) / settlement::sigma_p_2_x_2) / (x(age) * settlement::sigma_x_sqrt_2_x_pi); + 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.0f / 101.8f); + const double threshold = static_cast(weight(age)) * (16.0 / 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 628bb59dd..7337d77c4 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp @@ -46,6 +46,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); + 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 }; @@ -60,6 +61,7 @@ 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 }; @@ -79,8 +81,8 @@ namespace paxs { std::vector life_num1(SimulationConstants::getInstance()->steps_per_year * 100, 0); std::vector life_num2(SimulationConstants::getInstance()->steps_per_year * 100, 0); for (int i = 0; i < loop_num_; ++i) { - life_num1[kanakuma_life_span.setLifeSpan(0, gen)] += 1; - life_num2[kanakuma_life_span.setLifeSpan(1, gen)] += 1; + life_num1[kanakuma_life_span.setLifeSpan(true, 0, gen)] += 1; + life_num2[kanakuma_life_span.setLifeSpan(true, 1, gen)] += 1; } life_ofs << "step\tyear\tfemale\tmale\n"; for (int i = 0; i < SimulationConstants::getInstance()->steps_per_year * 100; ++i) { @@ -95,7 +97,7 @@ namespace paxs { void init() { settlement_grids.clear(); initRandomizeSettlements(); - randomizeSettlements(0, 0, 255, 0/*縄文人は SNP:0*/); + randomizeSettlements(true, 0, 255, 0/*縄文人は SNP:0*/); } /// @brief Run the simulation for the specified number of steps. @@ -141,7 +143,7 @@ namespace paxs { ++sat_num; // 集落数を増加させる pop_num += settlement.getPopulation(); // 人口数を増加させる - const std::uint_least8_t ryo_id = environment->template getData(MurMur3::calcHash("district"), settlement.getPosition()); + const std::uint_least8_t ryo_id = environment->template getData(SimulationConstants::getInstance()->district_key, settlement.getPosition()); if (ryo_id < max_number_of_districts) { ryopop[ryo_id]+= settlement.getPopulation(); // 地区ごとに人口数を増加させる ryosnp[ryo_id]+= settlement.getSNP(); // 地区ごとに SNP を増加させる @@ -201,7 +203,7 @@ namespace paxs { } // 前901年から稲作文化開始 if (step_count >= SimulationConstants::getInstance()->immigration_start_steps) { - randomizeSettlements(1, 255, 0, 255/*渡来人は SNP:255*/); + randomizeSettlements(false, 255, 0, 255/*渡来人は SNP:255*/); } m_start_time = std::chrono::system_clock::now(); // 婚姻計測開始 @@ -280,6 +282,12 @@ namespace paxs { } } + // 前901年から処理開始 + if (step_count >= SimulationConstants::getInstance()->immigration_start_steps) { + // 渡来数を増やす + japan_provinces->update(); + } + ++step_count; end_time = std::chrono::system_clock::now(); // 計測終了 processing_time = static_cast(std::chrono::duration_cast(end_time - start_time).count() / 1000.0); @@ -386,7 +394,7 @@ namespace paxs { } // 地区ごとに人口が決められているので、人口に空きがあるかどうかを判定 - std::uint_least8_t district_id = environment->template getData(MurMur3::calcHash("district"), position); + std::uint_least8_t district_id = environment->template getData(SimulationConstants::getInstance()->district_key, position); if (district_id < max_number_of_districts) { (*live_list)[district_id].emplaceBack(live_probability, land_position); } @@ -397,7 +405,7 @@ namespace paxs { /// @brief Randomly place settlements. /// @brief 集落をランダムに配置する void randomizeSettlements( - std::size_t ad200, + bool is_ad200, std::uint_least8_t farming, std::uint_least8_t hunter_gatherer, std::uint_least8_t snp_ @@ -408,10 +416,10 @@ namespace paxs { // 地区と人口のマップ std::unordered_map district_population_map; for (auto& district : japan_provinces->cgetDistrictList()) { - if (district.population[ad200/*ad200*/] == 0) { + if (((is_ad200)? district.init_pop : district.immigrant) == 0) { continue; } - district_population_map[district.id] = district.population[ad200/*ad200*/]; + district_population_map[district.id] = ((is_ad200) ? district.init_pop : district.immigrant); // より地区 ID が大きい値を見つけたら上書き if (district.id > district_id_max) { district_id_max = district.id; @@ -448,7 +456,7 @@ namespace paxs { const Vector2 live_position = Vector2::from(live.habitable_land_positions[live_probability_index]); // 地区ごとに人口が決められているので、人口に空きがあるかどうかを判定 - // std::uint_least8_t district_id = environment->template getData(MurMur3::calcHash("district"), live_position); + // std::uint_least8_t district_id = environment->template getData(SimulationConstants::getInstance()->district_key, live_position); auto district_population_it = district_population_map.find(district_id); if (district_population_it == district_population_map.end()) { @@ -482,7 +490,7 @@ namespace paxs { settlement.resizeAgents(settlement_population); for (int i = 0; i < settlement_population; ++i) { Genome genome = Genome::generateRandomSetMtDNA(gen, japan_provinces->getMtDNA((farming>0)? SimulationConstants::getInstance()->immigration_district_id/*toraijin*/ : district_id, gen), snp_); - const AgeType set_lifespan = kanakuma_life_span.setLifeSpan(genome.isMale(), gen); + const AgeType set_lifespan = kanakuma_life_span.setLifeSpan((farming > 0), genome.isMale(), gen); AgeType age_value = 0; if (set_lifespan > SimulationConstants::getInstance()->init_lifespan_min) { @@ -541,7 +549,7 @@ namespace paxs { std::vector agents(add_population); for (int i = 0; i < add_population; ++i) { Genome genome = Genome::generateRandomSetMtDNA(gen, japan_provinces->getMtDNA((farming > 0) ? SimulationConstants::getInstance()->immigration_district_id/*toraijin*/ : district_id, gen), snp_); - const AgeType set_lifespan = kanakuma_life_span.setLifeSpan(genome.isMale(), gen); + const AgeType set_lifespan = kanakuma_life_span.setLifeSpan((farming > 0), genome.isMale(), gen); AgeType age_value = 0; if (set_lifespan > SimulationConstants::getInstance()->init_lifespan_min) { diff --git a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp index ffea35a9f..d3d19893e 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp @@ -24,6 +24,11 @@ #include #include +// M_PI が定義されていない場合 +#ifndef M_PI +#define M_PI 3.141592653589 +#endif + namespace paxs { constexpr int pixel_size = 256; // 1画像あたりの縦横のピクセル数 @@ -33,6 +38,9 @@ namespace paxs { constexpr std::uint_least8_t female_value = 0; // 女性 constexpr std::uint_least8_t male_value = 1; // 男性 + // std::sqrt(2 * M_PI) + constexpr double sqrt_2_x_pi = static_cast(2.506628275); + using GridType = int; using HumanIndexType = std::uint_least32_t; using AgeType = std::uint_least16_t; @@ -58,6 +66,8 @@ namespace paxs { int start_julian_day = 1728746; // シミュレーション開始日(ユリウス日) std::uint_least32_t area = MurMur3::calcHash("japan"); // シミュレーションの対象範囲 + std::uint_least32_t land_key = MurMur3::calcHash("district"); // 陸地データの Key + std::uint_least32_t district_key = MurMur3::calcHash("district"); // 地区データの Key SimulationRange sr; int steps_per_year = 12; // 1年あたりのステップ数 @@ -66,6 +76,7 @@ namespace paxs { // 女性の結婚可能年齢:13歳以上60歳未満, 男性の結婚可能年齢:17歳以上60歳未満 std::uint_least32_t female_marriageable_age_min = 13; + double female_marriageable_age_min_f64 = 13.0; std::uint_least32_t male_marriageable_age_min = 17; std::uint_least32_t female_marriageable_age_max = 60; std::uint_least32_t male_marriageable_age_max = 70; @@ -119,6 +130,7 @@ namespace paxs { std::uniform_real_distribution random_dist_f32 = std::uniform_real_distribution( 0.0f, 1.0f ); // 乱数分布 std::uniform_real_distribution random_dist = std::uniform_real_distribution( 0.0, 1.0 ); // 乱数分布 + std::uniform_int_distribution step_per_year_dist = std::uniform_int_distribution( 0, 11 ); // 乱数分布 private: template @@ -151,23 +163,31 @@ namespace paxs { stoiFunc(kvt, MurMur3::calcHash("start_julian_day"), [&](const std::string& str_) {start_julian_day = std::stoi(str_); }); stoiFunc(kvt, MurMur3::calcHash("area"), [&](const std::string& str_) {area = MurMur3::calcHash(str_.size(), str_.c_str()); }); + stoiFunc(kvt, MurMur3::calcHash("land_key"), [&](const std::string& str_) {land_key = MurMur3::calcHash(str_.size(), str_.c_str()); }); + stoiFunc(kvt, MurMur3::calcHash("district_key"), [&](const std::string& str_) {district_key = MurMur3::calcHash(str_.size(), str_.c_str()); }); // シミュレーションの範囲を設定 AppConfig::getInstance()->calcDataSettings(MurMur3::calcHash("SimulationRange"), [&](const std::string& path_) {sr.input(path_); }); stoiFunc(kvt, MurMur3::calcHash("steps_per_year"), [&](const std::string& str_) {steps_per_year = std::stoi(str_); }); + step_per_year_dist = std::uniform_int_distribution(0, steps_per_year - 1); stoiFunc(kvt, MurMur3::calcHash("output_step_frequency"), [&](const std::string& str_) {output_step_frequency = std::stoi(str_); }); stoiFunc(kvt, MurMur3::calcHash("female_marriageable_age_min"), [&](const std::string& str_) {female_marriageable_age_min = static_cast(std::stoul(str_)); }); + female_marriageable_age_min_f64 = static_cast(female_marriageable_age_min); + stoiFunc(kvt, MurMur3::calcHash("male_marriageable_age_min"), [&](const std::string& str_) {male_marriageable_age_min = static_cast(std::stoul(str_)); }); 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_)); }); 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("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("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_district_id"), [&](const std::string& str_) {immigration_district_id = static_cast(std::stoul(str_)); }); diff --git a/Library/PAX_SAPIENTICA/Simulation/Simulator.hpp b/Library/PAX_SAPIENTICA/Simulation/Simulator.hpp index dcfcccb89..43abc4f05 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Simulator.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Simulator.hpp @@ -88,7 +88,7 @@ namespace paxs { std::mt19937 gen; // 乱数生成器 std::uniform_int_distribution<> gender_dist{0, 1}; // 性別の乱数分布 - KanakumaLifeSpan kanakuma_life_span; + KanakumaLifeSpan kanakuma_life_span{}; /// @brief Clear the agents. /// @brief エージェントをクリアする @@ -115,7 +115,7 @@ namespace paxs { agents.emplace_back(Agent( id, "", position, set_gender, age_dist(gen), - kanakuma_life_span.setLifeSpan(set_gender, gen), + kanakuma_life_span.setLifeSpan(true, set_gender, gen), environment)); } StatusDisplayer::displayProgressBar(agent_count, agent_count);