Skip to content

Instantly share code, notes, and snippets.

@takehiko
Last active October 16, 2015 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takehiko/74a64980b4f38fa88910 to your computer and use it in GitHub Desktop.
Save takehiko/74a64980b4f38fa88910 to your computer and use it in GitHub Desktop.
Load Estimation of Trigonal Human Pyramids
#!/usr/bin/env ruby
# gfload+.rb : Load Estimation of Trigonal Human Pyramids
# by takehikom
# see also:
# https://gist.github.com/takehiko/a32f51e2eabba4f821d8
# http://d.hatena.ne.jp/takehikom/20151016/1444941800
# http://d.hatena.ne.jp/takehikom/20151018/1445094000
require_relative "gfload.rb"
def generate_random_bm(avg, sd, size, seed = 12345)
# ボックス=ミュラー法を用いて,平均avg, 分散sd**2の正規分布から
# size個の乱数を生成し配列にして返す.seedは乱数生成の種
sds = 2 # z値の絶対値がこの値を超えるものは使用しない
srand(seed)
(1..size).to_a.map do
v = sds * 2
begin
begin
r1, r2 = rand, rand
end while r1 == 0.0 || r2 == 0.0
v = Math.sqrt(-2 * Math.log(r1)) * Math.cos(2 * Math::PI * r2)
puts "debug: v=#{v}, #{v.abs <= sds ? 'ok' : 'ng'}" if $DEBUG
end while v.abs > sds
sd * v + avg
end
end
gf = GFLoad::Formation.new
gf.build_pyramid_trigonal((ARGV.shift || 5).to_i)
size = gf.mem.size
# 分布は,政府統計の総合窓口
# http://www.e-stat.go.jp/SG1/estat/eStatTopPortal.do
# の体力・運動能力調査 > 平成26年度 > 学校段階別体格測定の結果より,
# 小学校11男子と中学校12男子の体重の平均値・標準偏差をもとにした.
avg = (37.82 + 43.86) / 2
sd = Math.sqrt((7.40 ** 2 + 8.31 ** 2) / 2)
# 小学校11男子のみであれば,以下のコメントを外す
# avg = 37.82; sd = 7.40
w_a = generate_random_bm(avg, sd, size)
if true
# 土台と2段目以上に分け,負荷の高いところを体重の重い者に割り当てる
p_a = gf.mem.values
p_a1 = p_a.dup
p_a1.delete_if {|p| p.name[0, 2] != "1."} # 土台の人(誰にも負荷をかけない)
p_a2 = p_a - p_a1 # 2段目以上の人(誰かに負荷をかける)
p_a1.sort_by! {|p| p.load_weight}
p_a2.sort_by! {|p| p.load_weight}
w_a.sort!
if $DEBUG
puts "p_a1: #{p_a1.map{|p| p.name}.inspect}"
puts "p_a2: #{p_a2.map{|p| p.name}.inspect}"
puts "w_a: #{w_a.inspect}"
end
[p_a2, p_a1].each do |p_aa|
p_aa.each do |p|
w = w_a.shift
p.weight = w
puts "%s : %5.2f kg" % [p.name, w]
end
end
else
# 土台と2段目以上に分けず,負荷の高いところを体重の重い者に割り当てる
p_a = gf.mem.values.sort_by {|p| p.load_weight}
w_a.sort!
p_a.each_with_index do |p, i|
w = w_a[i]
p.weight = w
puts "%s : %5.2f kg" % [p.name, w]
end
end
puts gf
puts gf.to_s_member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment