diff --git a/Library/PAX_MAHOROBA/LocationPoint.hpp b/Library/PAX_MAHOROBA/LocationPoint.hpp index 091921744..311961854 100644 --- a/Library/PAX_MAHOROBA/LocationPoint.hpp +++ b/Library/PAX_MAHOROBA/LocationPoint.hpp @@ -678,8 +678,9 @@ 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 float pop_original = settlement.getSNP() * 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 b50ac02a7..33aeb5c92 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Genome.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Genome.hpp @@ -54,6 +54,14 @@ namespace paxs { yDNA = value; } + std::uint_least8_t getSNP() const noexcept { + return SNP; + } + + void setSNP(const std::uint_least8_t value) noexcept { + SNP = value; + } + constexpr std::uint_least8_t getGender() const noexcept { return chromosome.getGender(); } @@ -65,13 +73,15 @@ namespace paxs { std::uniform_int_distribution<> dist((std::numeric_limits::min)(), (std::numeric_limits::max)()); genome.setMtDNA(static_cast(dist(engine))); genome.setYDNA(static_cast(dist(engine))); + genome.setSNP(static_cast(dist(engine))); return genome; } - static Genome generateRandomSetMtDNA(std::mt19937& engine, const std::uint_least8_t mtdna_) noexcept { + static Genome generateRandomSetMtDNA(std::mt19937& engine, const std::uint_least8_t mtdna_, const std::uint_least8_t snp_) noexcept { Genome genome; genome.setChromosome(Chromosome::generateRandom(engine)); std::uniform_int_distribution<> dist((std::numeric_limits::min)(), (std::numeric_limits::max)()); + genome.setSNP(snp_); genome.setMtDNA(mtdna_); genome.setYDNA(static_cast(dist(engine))); return genome; @@ -88,6 +98,7 @@ namespace paxs { else { genome.setYDNA(father.getYDNA()); } + genome.setSNP(static_cast((int(mother.getSNP()) + int(father.getSNP())) / 2)); return genome; } @@ -96,9 +107,10 @@ namespace paxs { } private: - Chromosome chromosome; - std::uint_least8_t mtDNA; - std::uint_least8_t yDNA; + Chromosome chromosome{}; + std::uint_least8_t SNP = 0; + std::uint_least8_t mtDNA = 0; + std::uint_least8_t yDNA = 0; }; } diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index d856d01f3..704d0a81d 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -396,6 +396,17 @@ namespace paxs { return farming_population; } + /// @brief Get the SNP. + /// @brief SNP を取得 + double getSNP() const noexcept { + std::uint_least64_t snp = 0; + + for (std::size_t i = 0; i < agents.size(); ++i) { + snp += static_cast(agents[i].cgetGenome().getSNP()); + } + return static_cast(snp) / static_cast(agents.size()) / 255.0; + } + /// @brief Get the most mtDNA. /// @brief 最多 mtDNA を取得 std::size_t getMostMtDNA() const noexcept { diff --git a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp index c5a76726f..4d429328b 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp @@ -95,7 +95,7 @@ namespace paxs { void init() { settlement_grids.clear(); initRandomizeSettlements(); - randomizeSettlements(0, 0, 255); + randomizeSettlements(0, 0, 255, 0/*縄文人は SNP:0*/); } /// @brief Run the simulation for the specified number of steps. @@ -131,6 +131,8 @@ namespace paxs { std::size_t sat_num = 0; // 集落数 std::vector < std::vector> mtdna_num(90, std::vector(256, 0)); // mtDNA 数 std::size_t ryopop[90]{}; + std::size_t ryoset[90]{}; + double ryosnp[90]{}; // 地名を描画 for (const auto& agent : getSettlementGrids()) { @@ -141,6 +143,8 @@ namespace paxs { const std::uint_least8_t ryo_id = environment->template getData(MurMur3::calcHash("gbank"), settlement.getPosition()); if (ryo_id < 90) { ryopop[ryo_id]+= settlement.getPopulation(); // 地区ごとに人口数を増加させる + ryosnp[ryo_id]+= settlement.getSNP(); // 地区ごとに SNP を増加させる + ++(ryoset[ryo_id]); // mtDNA ごとにカウント for (int popi = 0; popi < settlement.cgetAgents().size(); ++popi) { @@ -151,8 +155,11 @@ namespace paxs { } pop_ofs << step_count << '\t' << sat_num << '\t' << pop_num << '\t'; pop_mtdna_ofs << step_count << '\t' << sat_num << '\t' << pop_num << '\t'; + pop_snp_ofs << step_count << '\t' << sat_num << '\t' << pop_num << '\t'; for (int i = 0; i < 90; ++i) { + ryosnp[i] /= static_cast(ryoset[i]); pop_ofs << ryopop[i] << '\t'; + pop_snp_ofs << ryosnp[i] << '\t'; for (int j = 0; j < 27; ++j) { if (int(mtdna_num[i][j]) == 0) continue; pop_mtdna_ofs << japan_provinces->getMtDNA_Name(j) << ':' << int(mtdna_num[i][j]) << '/'; @@ -161,6 +168,7 @@ namespace paxs { } pop_ofs << step_count << '\n'; pop_mtdna_ofs << step_count << '\n'; + pop_snp_ofs << step_count << '\n'; } std::vector> move_list; @@ -192,7 +200,7 @@ namespace paxs { } // 前901年から稲作文化開始 if (step_count > SimulationConstants::getInstance()->steps_per_year * 200) { - randomizeSettlements(1, 255, 0); + randomizeSettlements(1, 255, 0, 255/*渡来人は SNP:255*/); } m_start_time = std::chrono::system_clock::now(); // 婚姻計測開始 @@ -320,6 +328,7 @@ namespace paxs { std::ofstream pop_ofs = std::ofstream("pop.txt"); std::ofstream pop_mtdna_ofs = std::ofstream("pop_mtdna.txt"); + std::ofstream pop_snp_ofs = std::ofstream("pop_snp.txt"); /// @brief () /// @brief 集落をランダムに配置する前の初期化処理 @@ -372,7 +381,8 @@ namespace paxs { void randomizeSettlements( std::size_t ad200, std::uint_least8_t farming, - std::uint_least8_t hunter_gatherer + std::uint_least8_t hunter_gatherer, + std::uint_least8_t snp_ ) noexcept { // 地区と人口のマップ @@ -439,7 +449,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)? 73/*toraijin*/ : district_id, gen)); + Genome genome = Genome::generateRandomSetMtDNA(gen, japan_provinces->getMtDNA((farming>0)? 73/*toraijin*/ : district_id, gen), snp_); 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) }; // 性別の乱数分布 @@ -492,7 +502,7 @@ namespace paxs { for (auto& settlement : settlements) { std::vector agents(add_population); for (int i = 0; i < add_population; ++i) { - Genome genome = Genome::generateRandomSetMtDNA(gen, japan_provinces->getMtDNA((farming > 0) ? 73/*toraijin*/ : district_id, gen)); + Genome genome = Genome::generateRandomSetMtDNA(gen, japan_provinces->getMtDNA((farming > 0) ? 73/*toraijin*/ : district_id, gen), snp_); 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) }; // 性別の乱数分布