2次元ランダムウォーク
Posted feedbacks - Ruby
貧相ですが,画面上に表示する様にしてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | require 'vr/vruby'
require 'vr/vrcontrol'
class RandomWalk
attr_accessor :x, :y, :trace
def self.next(current)
rand(2) == 0 ? (current - 1) : (current + 1)
end
def initialize
self.trace = []
self.x = 0
self.y = 0
end
def walk(step=10000)
self.trace = (1..step).map { |_| move }
end
private
def move
[:x,:y].map { |p| send("#{p.to_s}=".intern, self.class.next(send(p))) }
end
end
class RandomWalkPlotter <VRForm
include VRDrawable
WIDTH = 300
STEP = 10000
attr_accessor :scale
def construct
random_walk
addControl VRButton, "btn_walk", "walk", 10, 310, 40, 30
addControl VRButton, "btn_save", "save", 60, 310, 40, 30
addControl VRButton, "btn_quit", "quit", 240, 310, 40, 30
move 100, 100, 300, 385
end
def btn_walk_clicked
random_walk
refresh
end
def btn_save_clicked
if (file = SWin::CommonDialog::saveFilename(self))
File.open(file,"w") { |f| (1..trace.size).zip(trace).each { |d| f.puts(d.flatten.join(",")) } }
end
end
def btn_quit_clicked
close
end
def self_paint
setPen RGB(0, 0, 0)
x, y = WIDTH / 2, WIDTH / 2
trace.each do |p|
l = [(p[0] * scale).to_i + WIDTH / 2,WIDTH / 2 - (p[1] * scale).to_i]
drawLine x , y , *l
x, y = *l
end
end
def random_walk
random_walk = RandomWalk.new
random_walk.walk STEP
self.trace = random_walk.trace
end
def trace=(trace)
@trace = trace
self.scale = WIDTH.to_f / (trace.flatten.inject(0) { |m,p| (m < p.abs) ? p.abs : m } * 2)
end
def trace
@trace
end
end
VRLocalScreen.start RandomWalkPlotter
|
n次元ランダムウォーカー。 とりあえず値のみの変化で、画像出力はまたこんど。
自己回避を入れてみようとしたけど汚くなったので止めた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | class RandomWalker
WALK = [-1, +1]
def initialize dimension = 1
@dimension = dimension
@history = []
@position = Array.new(dimension, 0)
@history << @position.dup
end
def walk
@position[rand(@dimension)] += WALK[rand(2)]
@history << @position.dup
end
def to_s
result = ""
@history.each_with_index do |position, time|
result << "#{time} #{position.join " "}\n"
end
result
end
def save filename
File.open(filename, "w") do |file|
file.write to_s
end
end
end
rw = RandomWalker.new(2) # 2次元ランダムウォーカーを作成
100.times do
rw.walk
end
rw.save "rw.txt"
|

ytakenaka
#6806()
Rating2/2=1.00
2次元ランダムウォークをつくってみてください。
******
元は3本建てにしようかと思ったけど、上の一本に絞りました。おまけとして、3本とも下に補足しておきます。作れるようでしたら作ってみてください。
1.一次元のランダムウォークを作ってください。
1.1 データファイルに残してください。 フォーマット:時間 位置
おまけ)
可視化が簡単な処理系・プログラミング言語でしたら実際に可視化してみてください。フォーマットしたファイルをスプレッドシートやplotutilitiesなどの可視化ソフトを使って、実際に動きをかくにんしてみましょう。:-)
2.同じように2次元のランダムウォークを作ってください。
2.1 1.1と同じようにしてください。
フォーマット:時間 x位置 y位置
3.凝りたければ、アニメーションにするもよし、3次元の動きをとるもよし、自分の想像力がいかせるところまでやってみてください。
http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%82%A6%E3%82%A9%E3%83%BC%E3%82%AF
分からないというヒトへの分かりにくいヒント:
今の位置から次の時間の位置が決まるのですが、決まりかたが、乱数で一歩後退するか一歩先にいくか?ということをやればよいです。
[ reply ]