Skip to content

Commit 1a9eec3

Browse files
committed
Merge branch 'develop' of https://github.com/AsPJT/PAX_SAPIENTICA into develop
2 parents fad120c + cc3ecd5 commit 1a9eec3

File tree

5 files changed

+400
-29
lines changed

5 files changed

+400
-29
lines changed

Library/PAX_MAHOROBA/StringViewer.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,29 @@ namespace paxs {
122122
}
123123
// シミュレーションが初期化されている場合
124124
else {
125+
126+
const auto* constants = SimulationConstants::getInstance(model_name);
127+
const int total_steps = constants->total_steps;
128+
129+
// 規定ステップ数に達したかチェック
130+
if (total_steps > 0 && koyomi_siv.steps.cgetDay() >= total_steps) {
131+
// 残り実行回数を減らす
132+
m_remaining_iterations--;
133+
134+
if (m_remaining_iterations > 0) {
135+
// まだ実行回数が残っている場合、シミュレーションを初期化して自動で再開
136+
simulationInit(simulator, koyomi_siv);
137+
koyomi_siv.is_agent_update = true;
138+
koyomi_siv.move_forward_in_time = true;
139+
}
140+
else {
141+
// 全ての実行が終了した場合、シミュレーションを停止
142+
koyomi_siv.is_agent_update = false;
143+
koyomi_siv.move_forward_in_time = false;
144+
m_remaining_iterations = 0; //念のため0にリセット
145+
}
146+
}
147+
125148
// シミュレーションが再生されている場合
126149
if (koyomi_siv.is_agent_update) {
127150
// シミュレーションを停止
@@ -169,6 +192,9 @@ namespace paxs {
169192
// if (s3d::SimpleGUI::Button(U"Sim Start", s3d::Vec2{ 190, 60 })) {
170193
koyomi_siv.is_agent_update = true;
171194

195+
// 実行回数をセット
196+
m_remaining_iterations = SimulationConstants::getInstance(model_name)->num_iterations;
197+
172198
koyomi_siv.move_forward_in_time = true; // 再生
173199
koyomi_siv.go_back_in_time = false;
174200
}
@@ -275,6 +301,8 @@ MurMur3::calcHash("ain")
275301

276302
// シミュレーションのモデル番号
277303
std::size_t simulation_model_index = 0;
304+
// シミュレーションの繰り返し回数
305+
int m_remaining_iterations = 0;
278306
#ifdef PAXS_USING_SIV3D
279307
// UI の影
280308
s3d::RenderTexture shadow_texture{};

Library/PAX_SAPIENTICA/Simulation/Genome.hpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ namespace paxs {
7777
SNP = value;
7878
}
7979

80+
std::uint_least8_t getLanguage() const noexcept {
81+
return language;
82+
}
83+
84+
void setLanguage(const std::uint_least8_t value) noexcept {
85+
language = value;
86+
}
87+
8088
constexpr bool isFemale() const noexcept {
8189
return (yDNA == 0);
8290
}
@@ -95,9 +103,10 @@ namespace paxs {
95103
genome.setMtDNA(static_cast<std::uint_least8_t>(dist(engine)));
96104
genome.setYDNA((is_female) ? 0 : static_cast<std::uint_least8_t>(dist(engine)));
97105
genome.setSNP(static_cast<std::uint_least8_t>(dist(engine)));
106+
genome.setLanguage(static_cast<std::uint_least8_t>(dist(engine)));
98107
return genome;
99108
}
100-
static Genome generateRandomSetMtDNA(std::mt19937& engine, const std::uint_least8_t mtdna_, const std::uint_least8_t snp_) noexcept {
109+
static Genome generateRandomSetMtDNA(std::mt19937& engine, const std::uint_least8_t mtdna_, const std::uint_least8_t snp_, const std::uint_least8_t language_) noexcept {
101110
Genome genome;
102111
#ifdef USING_CHROMOSOME
103112
genome.setChromosome(Chromosome::generateRandom(engine));
@@ -106,6 +115,7 @@ namespace paxs {
106115
genome.setSNP(snp_);
107116
genome.setMtDNA(mtdna_);
108117
genome.setYDNA((is_female) ? 0 : 1/*static_cast<std::uint_least8_t>(dist(engine))*/);
118+
genome.setLanguage(language_);
109119
return genome;
110120
}
111121

@@ -114,7 +124,8 @@ namespace paxs {
114124
#ifdef USING_CHROMOSOME
115125
genome.setChromosome(Chromosome::generateFromParents(engine, mother.cgetChromosome(), father.cgetChromosome()));
116126
#endif // USING_CHROMOSOME
117-
const bool is_female = ((engine() % 2) == 0);
127+
const auto& engine_value = engine();
128+
const bool is_female = ((engine_value % 2) == 0);
118129

119130
genome.setMtDNA(mother.getMtDNA());
120131
if (is_female) {
@@ -123,6 +134,7 @@ namespace paxs {
123134
else {
124135
genome.setYDNA(father.getYDNA());
125136
}
137+
genome.setLanguage((((engine_value >> 1) % 2) == 0) ? mother.language : father.language);
126138
genome.setSNP(static_cast<std::uint_least8_t>((int(mother.getSNP()) + int(father.getSNP())) / 2));
127139
return genome;
128140
}
@@ -134,6 +146,7 @@ namespace paxs {
134146
#endif // USING_CHROMOSOME
135147
mtDNA == rhs.mtDNA &&
136148
yDNA == rhs.yDNA;
149+
language == rhs.language;
137150
}
138151

139152
private:
@@ -144,6 +157,7 @@ namespace paxs {
144157
std::uint_least8_t SNP = 0;
145158
std::uint_least8_t mtDNA = 0;
146159
std::uint_least8_t yDNA = 0;
160+
std::uint_least8_t language = 0;
147161
};
148162
}
149163

Library/PAX_SAPIENTICA/Simulation/JapanProvinces.hpp

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ namespace paxs {
6161
double immigrant_f64 = 0;
6262
double increased_immigration = 0;
6363
std::uint_least32_t mtdna_region_hash = 0;
64+
std::uint_least32_t language_region_hash = 0;
6465

6566
std::uint_least32_t direction_min_distance = 100;
6667
// std::array<double, 8> direction_weight{};
@@ -78,6 +79,41 @@ namespace paxs {
7879
return (menu.find(str_) != menu.end()) ? menu.at(str_) : SIZE_MAX;
7980
}
8081

82+
void inputLanguage_List(const std::string& japan_provinces_path) noexcept {
83+
84+
const std::string path = japan_provinces_path + "/Language_List.tsv";
85+
86+
paxs::InputFile language_tsv(AppConfig::getInstance()->getRootPath() + path);
87+
if (language_tsv.fail()) {
88+
PAXS_WARNING("Failed to read Language_List TSV file: " + path);
89+
return;
90+
}
91+
// 1 行目を読み込む
92+
if (!(language_tsv.getLine())) {
93+
return; // 何もない場合
94+
}
95+
// BOM を削除
96+
language_tsv.deleteBOM();
97+
// 1 行目を分割する
98+
std::unordered_map<std::uint_least32_t, std::size_t> menu = language_tsv.splitHashMapMurMur3('\t');
99+
std::size_t i = 1;
100+
101+
// 1 行ずつ読み込み(区切りはタブ)
102+
while (language_tsv.getLine()) {
103+
std::vector<std::string> sub_menu_v = language_tsv.split('\t');
104+
if (
105+
sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("language"))
106+
) {
107+
PAXS_WARNING("Failed to read Japan Language_List TSV file: " + path + " at line " + std::to_string(i));
108+
++i;
109+
continue;
110+
}
111+
language_list.emplace_back(sub_menu_v[menu[MurMur3::calcHash("language")]]);
112+
++i;
113+
}
114+
115+
}
116+
81117
void inputMtDNA_List(const std::string& japan_provinces_path) noexcept {
82118

83119
const std::string path = japan_provinces_path + "/mtDNA_List.tsv";
@@ -113,6 +149,72 @@ namespace paxs {
113149

114150
}
115151

152+
void inputLanguage_Region(const std::string& japan_provinces_path) noexcept {
153+
154+
const std::string path = japan_provinces_path + "/Language.tsv";
155+
156+
paxs::InputFile language_tsv(AppConfig::getInstance()->getRootPath() + path);
157+
if (language_tsv.fail()) {
158+
PAXS_WARNING("Failed to read Language TSV file: " + path);
159+
return;
160+
}
161+
// 1 行目を読み込む
162+
if (!(language_tsv.getLine())) {
163+
return; // 何もない場合
164+
}
165+
// BOM を削除
166+
language_tsv.deleteBOM();
167+
// 1 行目を分割する
168+
std::unordered_map<std::uint_least32_t, std::size_t> menu = language_tsv.splitHashMapMurMur3('\t');
169+
#ifdef PAXS_DEVELOPMENT
170+
std::size_t i = 1;
171+
#endif
172+
173+
// 1 行ずつ読み込み(区切りはタブ)
174+
while (language_tsv.getLine()) {
175+
std::vector<std::string> sub_menu_v = language_tsv.split('\t');
176+
if (
177+
sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("language_region")) ||
178+
sub_menu_v.size() <= getMenuIndex(menu, MurMur3::calcHash("language_dist"))
179+
) {
180+
#ifdef PAXS_DEVELOPMENT
181+
PAXS_WARNING("Failed to read Japan Language TSV file: " + path + " at line " + std::to_string(i));
182+
#endif
183+
continue;
184+
}
185+
186+
mtDNA_Region language_region;
187+
std::vector<std::string> dist = paxs::StringExtensions::split(sub_menu_v[menu[MurMur3::calcHash("language_dist")]], '/');
188+
189+
if (dist.size() % 2 == 1) {
190+
continue;
191+
}
192+
if (dist.size() <= 1) {
193+
continue;
194+
}
195+
for (int j = 0; j < dist.size(); j += 2) {
196+
for (int k = 0; k < language_list.size(); ++k) {
197+
// 言語 の名称の index を取得し、確率分布と一緒に管理
198+
if (language_list[k] == dist[j]) {
199+
language_region.id.emplace_back(k);
200+
language_region.weight.emplace_back(std::stod(dist[j + 1]));
201+
break;
202+
}
203+
}
204+
}
205+
// 確率分布を生成
206+
language_region.dist = std::discrete_distribution<>(language_region.weight.begin(), language_region.weight.end());
207+
208+
// mtDNA 地方区分のハッシュ
209+
const std::string& mtdna_region_str = sub_menu_v[menu[MurMur3::calcHash("haplo_group_region")]];
210+
language_region_list.emplace(MurMur3::calcHash(mtdna_region_str.size(), mtdna_region_str.c_str()), language_region);
211+
212+
#ifdef PAXS_DEVELOPMENT
213+
++i;
214+
#endif
215+
}
216+
}
217+
116218
void inputMtDNA_Region(const std::string& japan_provinces_path) noexcept {
117219

118220
const std::string path = japan_provinces_path + "/mtDNA.tsv";
@@ -244,6 +346,9 @@ namespace paxs {
244346

245347
const std::string& mtdna_region_str = sub_menu_v[menu[MurMur3::calcHash("mtdna_region")]];
246348
district.mtdna_region_hash = MurMur3::calcHash(mtdna_region_str.size(), mtdna_region_str.c_str());
349+
350+
const std::string& language_region_str = sub_menu_v[menu[MurMur3::calcHash("language_region")]];
351+
district.language_region_hash = MurMur3::calcHash(language_region_str.size(), language_region_str.c_str());
247352
district_list.emplace_back(district);
248353
++i;
249354
}
@@ -257,6 +362,8 @@ namespace paxs {
257362

258363
inputMtDNA_List(japan_provinces_path);
259364
inputMtDNA_Region(japan_provinces_path);
365+
inputLanguage_List(japan_provinces_path);
366+
inputLanguage_Region(japan_provinces_path);
260367
inputDistrict(japan_provinces_path);
261368
}
262369

@@ -357,6 +464,25 @@ namespace paxs {
357464

358465
return district_list[0];
359466
}
467+
std::uint_least8_t getLanguage(const std::uint_least8_t id, std::mt19937& gen) noexcept {
468+
for (const auto& district : district_list) {
469+
if (district.id == id) {
470+
auto& weight_list = language_region_list.at(district.language_region_hash);
471+
return weight_list.id[weight_list.dist(gen)];
472+
}
473+
}
474+
PAXS_WARNING("Failed to get District: " + std::to_string(id));
475+
476+
auto& weight_list = language_region_list.at(district_list[0].language_region_hash);
477+
return weight_list.id[weight_list.dist(gen)];
478+
}
479+
const std::string& getLanguage_Name(const std::uint_least8_t id) const noexcept {
480+
return language_list[id];
481+
}
482+
std::size_t getSizeLanguage() const noexcept {
483+
return language_list.size();
484+
}
485+
360486
std::uint_least8_t getMtDNA(const std::uint_least8_t id, std::mt19937& gen) noexcept {
361487
for (const auto& district : district_list) {
362488
if (district.id == id) {
@@ -418,8 +544,10 @@ namespace paxs {
418544
std::vector<JapanRegion> japan_regions; // 日本の地方区分
419545
std::vector<District> district_list; // 日本の地区
420546
std::unordered_map<std::uint_least32_t, mtDNA_Region> mtdna_region_list; // mtDNA 地方区分
547+
std::unordered_map<std::uint_least32_t, mtDNA_Region> language_region_list; // 言語 地方区分
421548
//std::vector<std::uint_least32_t> mtdna_region_hash_list; // mtDNA ハッシュ計算用
422549
std::vector<std::string> mtdna_list; // mtDNA
550+
std::vector<std::string> language_list; // 言語
423551
};
424552

425553
}

0 commit comments

Comments
 (0)