異をとなえん |

tennou.rbプログラム - 日本人は天皇の子孫か?(その5)

2008.07.14 Mon

14:46:42

日本人は天皇の子孫か?
で使ったrubyのプログラムを公開する。
ただし、表示方法とかは、わかりやすいように少し修正したので、
厳密には違っているが、基本的には同じである。

htmlになっているので、フォーマットがぐちゃぐちゃだが、動作することは確認した。

--------------------------------------------------------------------------------
#!/usr/bin/ruby

=begin
プログラムの使用法

プログラムの最後の部分を修正して使用する

inc = IncreasePopuration.new([[0.01, 2.0],
[0.2, 1.095],
[0.4, 1.075],
[0.6, 1.055],
[0.8, 1.035]],
1.055)

パラーメーターの意味は最初が、人口の割合ごとの人口の増加率の配列である。
次が、全体人口の増加率になる。

inc.calcurate(1, 1400000.0, 280, 1990)
パラメーターの意味は順番に初期対象人口, 初期男性人口, 開始年, 終了年である。

=end

=begin
日本の奈良時代(七百年)の人口は六百万人。
現在(千九百九十年)、一億二千万人。

三十年を一世代とすると、四十三世代で二十倍になっている。
平均寿命が二倍になっているとすると、実質十倍である。

四十三世代で十倍になるということは、一世代あたりの増加率は下記になる。

(x)を43乗すると10になる。

irb(main):066:0> 1.05501 ** 43
=> 10.0007546876559
irb(main):067:0> 1.055005 ** 43
=> 9.99871684130698

男一人が、一世代で約1.055人の男を作ればよい。

社会階層別に上層ほど家を存続させる意識が強いと仮定して、増加率を大体

最上層20%は、1.075
その下20%は、1.065
中間層20%は、1.055
その下20%は、1.045

と仮定する。

最下層20%は、帳尻合わせのために後で決定する。

さらに最上位層1%は特に2と仮定する。これは平均4人の子供を作る必要があるため女性には厳しい。だから、男性になっている。

上記の想定のもとに最終的な増加率が、1.055になるように下記の式を満たす最下層の増加率を決定する。
(0.01 * 2) + (0.2 * 1.075) + (0.2 * 1.065) + (0.2 * 1.055) + (0.2 * 1.045) + (0.19 * x)
= 1.055

xは0.96ぐらいになる。

上位層の子供は常に上位層から占めていき、単純に押し流されていくと仮定す
ると、最上位層の1%が100%占めるまでに何世代かかるかを計算してみる。
=end

class IncreasePopuration

def initialize(rate_array, ave_rate)
@rate_array = rate_array
@ave_rate = ave_rate

current_population_percent = 0
total = 0

@rate_array.each_index do |i|
total += (rate_array[i][0] - current_population_percent) * rate_array[i][1]
current_population_percent = @rate_array[i][0]
end
@lowest_class_increase_rate = (@ave_rate - total) / ( 1 - current_population_percent)

# パラメーター表示
start_rate = 0
@rate_array.each_index do |i|
printf("%2.4f 〜 %2.4f 人口増加率 = %2.4fn", start_rate, rate_array[i][0], rate_array[i][1])
start_rate = rate_array[i][0]
end
printf("%2.4f 〜 %2.4f 人口増加率 = %2.4fn", start_rate, 1.0, @lowest_class_increase_rate)
printf("n")

@w_array = []
@w_array.push([0, @rate_array[0][1]])
@rate_array.each_index do |i|
case i
when @rate_array.length - 1
@w_array.push([@rate_array[i][0], @lowest_class_increase_rate])
else
@w_array.push([@rate_array[i][0], @rate_array[i + 1][1]])
end
end
end

def increase(target_people, all_people)
x = target_people / all_people
y = 0

@w_array.reverse.each do |item|
if x > item[0]
y += all_people * (x - item[0]) * item[1]
x = item[0]
end
end
[y, all_people * @ave_rate]

end

def calcurate(target_people, all_people, start_year, end_year)
x, y = target_people, all_people
printf("%5s %11s %11s %7sn", "西暦", "対象人口", "男性人口", "割合")
start_year.step(end_year, 30) do |year|
# printf("year = %4d, target_people = %10d, all_people = %10d, rate = % 6.2fn", year, x, y, 100 * x / y)
printf("%4d| %10d| %10d| % 6.2fn", year, x, y, 100 * x / y)
x,y = increase(x, y)
end
end

end

# Korea Yannpann
# もっとも近いと思われる推定値
#inc = IncreasePopuration.new([[0.1, 2.0], [0.2, 1.5], [0.8, 1.066]], 1.066)
#inc.calcurate(240, 2000000.0, 1400, 1910)

# もっと妥当?
#inc = IncreasePopuration.new([[0.1, 2.0], [0.2, 1.5], [0.9, 0.9]], 1.066)
#inc.calcurate(500, 2000000.0, 1400, 1910)

# bug case
#inc = IncreasePopuration.new([[0.1, 2.0], [0.2, 2.0], [0.4, 1.5], [0.6, 1.0], [0.8, 1.035]], 1.055)
#inc.calcurate(240, 3000000.0, 1400, 1900)

# 神武天皇
inc = IncreasePopuration.new([[0.01, 2.0],
[0.2, 1.095],
[0.4, 1.075],
[0.6, 1.055],
[0.8, 1.035]],
1.055)
inc.calcurate(1, 1400000.0, 280, 1990)

このエントリーをはてなブックマークに追加
LINEで送る

コメント
コメントの投稿
管理者にだけ表示を許可する

トラックバック
トラックバックURLはこちら