Skip to content

Commit

Permalink
Merge pull request #103 from AsPJT/feature-simulation-all-input-data
Browse files Browse the repository at this point in the history
シミュレーションの全定数の入力データ化
  • Loading branch information
AsPJT authored Jul 14, 2024
2 parents d2ad4d7 + 430bc53 commit bf07d6a
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 51 deletions.
14 changes: 7 additions & 7 deletions Data/Simulations/Sample/District.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 12 additions & 7 deletions Data/Simulations/Settings.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -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 狩猟採集死産率
Expand All @@ -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 移動確率
39 changes: 33 additions & 6 deletions Library/PAX_MAHOROBA/LocationPoint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -619,7 +621,15 @@ namespace paxs {
void draw(const double jdn,
std::unordered_map<SettlementGridsType, paxs::SettlementGrid>& 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()) {
Expand Down Expand Up @@ -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<double>(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<std::uint_least8_t>(pop_original);
paxg::Circle(draw_pos,
1.0f + (settlement.getPopulation() / 40.0f)//2.0f
Expand Down
13 changes: 6 additions & 7 deletions Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,12 @@ namespace paxs {
/// @brief Move.
/// @brief 移動
/// @return 集落グリッドを移動したかどうか
std::tuple<std::uint_least32_t, Vector2, Vector2> move(std::mt19937& engine, int move_probability) noexcept {
std::tuple<std::uint_least32_t, Vector2, Vector2> 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
Expand Down Expand Up @@ -582,25 +581,25 @@ 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<double>(weight(age)) * (0.98 / 101.8);
const double threshold = static_cast<double>(weight(age)) * (SimulationConstants::getInstance()->marriageable_age_threshold / SimulationConstants::getInstance()->marriageable_age_all_weight); // (0.98 / 101.8);

return SimulationConstants::getInstance()->random_dist(*gen) < threshold;
}

/// @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<double>(weight(age)) * (16.0 / 101.8);
const double threshold = static_cast<double>(weight(age)) * (SimulationConstants::getInstance()->birthable_age_threshold / SimulationConstants::getInstance()->birthable_age_all_weight); // (16 / 101.8);

return SimulationConstants::getInstance()->random_dist(*gen) < threshold;
}
Expand Down
17 changes: 5 additions & 12 deletions Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ namespace paxs {
environment(std::make_unique<Environment>(map_list_path)), gen(seed) {
japan_provinces = std::make_unique<paxs::JapanProvinces>(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 {
Expand All @@ -62,10 +58,6 @@ namespace paxs {
japan_provinces.reset();
japan_provinces = std::make_unique<paxs::JapanProvinces>(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
Expand Down Expand Up @@ -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);
Expand All @@ -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*/);
}

Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -327,7 +321,6 @@ namespace paxs {
std::shared_ptr<Environment> environment;

std::unique_ptr<paxs::JapanProvinces> japan_provinces;
int move_probability = 0; // 移動確率

std::mt19937 gen; // 乱数生成器

Expand Down
Loading

0 comments on commit bf07d6a

Please sign in to comment.