糞糞糞ネット弁慶

読んだ論文についてメモを書きます.趣味の話は http://repose.hatenablog.com

バラバシの「バースト!」に出てくるeメール/手紙の優先順位モデルを試す

バースト! 人間行動を支配するパターン

バースト! 人間行動を支配するパターン

奇数章だけ読み始めた.その中に出てくるメールと手紙の送信モデルが面白かったので試した.

メールの場合

次のルールに従う.

  • 人は優先順位付きのリストを持っている
  • 優先順位が高い順に処理していく.
  • リストには「返信しなければならないメール」が溜まっているとする
  • メールが1通届く.この時の優先順位はランダムに振られる(どんなメールが届くかわからない)
  • 人はメールを優先順位が一番高いメールに返信する

このルールに従ってシミュレーションし,メールが返信されるまでの時間とその件数を図にしたものが以下のものである.
https://img.skitch.com/20120825-kfj4fph8mr1ps9p35h7qy2c4x5.jpg
べき分布になってるのだろうかこれ.

手紙の場合

次のルールに従う.本文中ではアインシュタインが送った手紙のログで実験されていた.

  • 人は優先順位付きのリストを持っている
  • 優先順位が高い順に処理していく.
  • リストには「返信しなければならない手紙」が溜まっているとする
  • 手紙がn通届く.この時,それぞれの手紙の優先順位はランダムに振られる(どんな手紙が届くかわからない)
  • 人は優先順位が高いm通について手紙を返信する

このルールに従ってシミュレーションし,手紙が返信されるまでの時間とその件数を図にしたものが以下のものである.
まずは届く数より送る数の方が多い場合(n = 10, m = 11)
https://img.skitch.com/20120825-xhukrtjkbna37yxa3t1dqgbe3q.jpg
そりゃこっちはすぐに返信される.
次に届く数より送る数の方が少ない場合(n = 10, m = 5)
https://img.skitch.com/20120825-ewb3s4ur7cexi8296ywd77cj93.jpg
こっちだとどんどんメールが溜まっていくので返信までの時間がべき分布になる.

話として非常にシンプルで良かった.

とここまでやって元論文([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