メールの場合
次のルールに従う.
- 人は優先順位付きのリストを持っている
- 優先順位が高い順に処理していく.
- リストには「返信しなければならないメール」が溜まっているとする
- メールが1通届く.この時の優先順位はランダムに振られる(どんなメールが届くかわからない)
- 人はメールを優先順位が一番高いメールに返信する
このルールに従ってシミュレーションし,メールが返信されるまでの時間とその件数を図にしたものが以下のものである.
べき分布になってるのだろうかこれ.
手紙の場合
次のルールに従う.本文中ではアインシュタインが送った手紙のログで実験されていた.
- 人は優先順位付きのリストを持っている
- 優先順位が高い順に処理していく.
- リストには「返信しなければならない手紙」が溜まっているとする
- 手紙がn通届く.この時,それぞれの手紙の優先順位はランダムに振られる(どんな手紙が届くかわからない)
- 人は優先順位が高いm通について手紙を返信する
このルールに従ってシミュレーションし,手紙が返信されるまでの時間とその件数を図にしたものが以下のものである.
まずは届く数より送る数の方が多い場合(n = 10, m = 11)
そりゃこっちはすぐに返信される.
次に届く数より送る数の方が少ない場合(n = 10, m = 5)
こっちだとどんどんメールが溜まっていくので返信までの時間がべき分布になる.
話として非常にシンプルで良かった.
とここまでやって元論文([cond-mat/0505371] The origin of bursts and heavy tails in human dynamics)をざっと開いたら優先順位リストの優先順位割り当てはに従う云々とか書いてあったので今度真面目に読むことにする.
コード
barabasi_email_model.rb
class Array def push_at(elem, pos = 0) raise StandardError if self.size < pos new_self = self[0...pos] new_self.push elem (pos + 1 .. self.size).each do |i| new_self.push self[i - 1] end self.replace(new_self) return self end end if __FILE__ == $0 iter = ARGV[0] || 100; iter = iter.to_i # e-mail's queue # index: priority # value: waiting time queue = [ ] # initialize 100.times{ queue.push 0} hist = Hash.new{|h, k|h[k] = 0} 10000.times do # send e-mail hist[queue.shift] += 1 # receive e-mail queue.push_at(0, rand(queue.size)) # update waiting time queue.map!{|e| e+= 1} end puts "time,counts" hist.sort_by{|e|e.first}.each do |e| puts e.join(",") end end
barabasi_mail_model.rb
require "./barabasi_email_model" if __FILE__ == $0 receive_rate = ARGV[0] || 3; receive_rate = receive_rate.to_i send_rate = ARGV[1] || 5; send_rate = send_rate.to_i iter = ARGV[2] || 100; iter = iter.to_i queue = [ ]; 100.times{ queue.push 0} hist = Hash.new{|h, k|h[k] = 0} iter.times do # receive receive_rate.times do pos = queue.size == 0 ? 0 : rand(queue.size) queue.push_at(0, pos) end # send send_rate.times do next if queue.size == 0 hist[queue.shift] += 1 end # update queue.map!{|e|e += 1} end puts "time,counts" hist.sort_by{|e|e.first}.each do |e| puts e.join(",") end end