2次元ランダムウォーク
Posted feedbacks - Nested
Flatten Hidden1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php
//移動回数
define('LOOP', 10);
//初期位置
$pos[0] = array('x' => 0, 'y' => 0);
for($time = 1; $time <= LOOP; $time++){
$rad = deg2rad(mt_rand()%360);
$x = $pos[$time-1]['x'] + cos($rad);
$y = $pos[$time-1]['y'] + sin($rad);
$pos[$time] = array('x' => $x, 'y' => $y);
}
foreach($pos as $key => $val){
echo $key . " " . $val['x'] . " " . $val['y'] . " " . "\n";
}
|
2次元ランダムウォークを描け というお題だと解釈しました。 というわけで、Image::Magickで描いてみました。
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 | use strict;
use warnings;
use List::Util qw/min max/;
use Image::Magick;
# 歩く回数
my $count = 10000;
sub _walk { int(rand(3))-1; }
# 歩いて範囲を測定
my @current = (0,0);
my @area = (@current, @current);
my @footmarks;
for my $fm (map { [_walk, _walk] } 1 .. $count) {
$current[0] += $fm->[0];
$current[1] += $fm->[1];
$area[0] = min $area[0], $current[0];
$area[1] = min $area[1], $current[1];
$area[2] = max $area[2], $current[0];
$area[3] = max $area[3], $current[1];
push @footmarks, [@current];
}
# 軌跡を書く
my $grid = 8;
my $lsize = 2;
my $img = Image::Magick->new;
$img->Set(
size=>join(q/x/, map { ($_+1) * $grid } $area[2]-$area[0], $area[3]-$area[1])
);
$img->Read(q/xc:white/);
$img->Draw(primitive => q/polyline/, stroke => q/black/, strokewidth => $lsize,
points => join(q/ /, map { join q/,/, map { $_ * $grid + $grid/2 } @$_ }
map { [$_->[0]-$area[0],$_->[1]-$area[1]] }
@footmarks)
);
# start地点にバッテン
$img->Draw(primitive => q/line/, stroke => q/red/, strokewidth => $lsize/2,
points => join(q/ /, map { join q/,/, map { $_ * $grid } @$_ }
map { [$_-$area[0], $_-$area[1]] }
0, 1)
);
$img->Draw(primitive => q/line/, stroke => q/red/, strokewidth => $lsize/2,
points => join(q/ /, map { join q/,/, map { $_ * $grid } @$_ }
map { [$_->[0]-$area[0], $_->[1]-$area[1]] }
[1,0], [0,1])
);
$img->Write(q/rwalk.png/);
|
特に指定はないようなので、単位時間に上下左右の四方向に一歩ずつ 進む一番簡単そうなものにしました。 random_walk 10 1 0 _1 2 0 0 3 _1 0 4 _1 1 5 _2 1 6 _3 1 7 _2 1 8 _2 2 9 _2 3 10 _1 3
1 | random_walk=:3 :'(>:i.y),.+/\>(<:?y#4){0 _1;0 1;_1 0;1 0'
|
BASICで。グラフィック機能が組み込まれた言語の見せ所だと思って、アニメーション。同時にファイルにも書きます。
N88互換BASICで動作を確認。Microsoft BASIC系依存なので(仮称)十進BASICでは動きません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 100 cls 3
110 x=320 : y=200 : t=0
120 open "c:\RandomWalk.dat" for output as #1
130 print #1, t; x; y
140 *loop
150 circle(x,y),2,0
160 if rnd(1)<0.5 then x=x+1 else x=x-1
170 if rnd(1)<0.5 then y=y+1 else y=y-1
180 t=t+1
190 circle(x,y),2,7
200 print #1, t; x; y
210 if inkey$<>"" then goto *quit
220 goto *loop
230 *quit
240 close #1
|
まずはシンプルなところで。 1 0 -1 2 0 0 3 0 1 4 -1 1 5 -2 1 6 -1 1 7 0 1 8 -1 1 9 -1 0 10 -1 1
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 | #include <cstdlib>
#include <complex>
#include <iostream>
#include <iomanip>
int main(int args, char* argv[])
{
std::complex<int> d[] =
{
std::complex<int>( 1, 0),
std::complex<int>( 0, 1),
std::complex<int>(-1, 0),
std::complex<int>( 0, -1)
};
std::complex<int> p(0, 0);
for(int i = 1; i <= 10; ++i)
{
p += d[std::rand() % 4];
std::cout << std::setw(4) << i
<< std::setw(4) << p.real()
<< std::setw(4) << p.imag()
<< std::endl;
}
return 0;
}
|
uwsc はマウスとキーボード入力を記録して再生するソフトですが スクリプト言語を備えています。 これを使ってランダムウォークをやってみました。出力にはwindows 付属の paint を使いましたが、マウスのドラッグで線が描けるソフトならなんでも いいと思います。 paint などでマウスのドラッグで線が描ける状態にして、uwsc を起動して このスクリプトを読み込みます。マウスを開始したい位置に移動して ALT+F1 で再生、ALT+F2で停止します。
see: uwsc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | dim dx[4]=-1,1,0,0
dim dy[4]=0,0,-1,1
t=input("歩数(dot)=",500)
w=input("歩幅(dot)=",5)
x=G_MOUSE_X
y=G_MOUSE_Y
btn(left,down,x,y)
for i=1 to t
r=random(4)
x=x+w*dx[r]
y=y+w*dy[r]
mmv(x,y,10)
next
btn(left,up)
|
動作には直接影響しませんが、いくつか訂正します。
パラメータ入力の文字列の部分が変でした。
t=input("歩数(dot)=",500)
歩数の単位は歩幅なので (dot) は間違いでした。
パラメータの入力の順番は歩幅を先にした方が良いのかな。
配列に初期値を設定する場合は、要素数は省略可能でした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | dim dx[]=-1,1,0,0
dim dy[]=0,0,-1,1
w=input("歩幅(dot)",5)
t=input("歩数",500)
x=G_MOUSE_X
y=G_MOUSE_Y
btn(left,down,x,y)
for i=1 to t
r=random(4)
x=x+w*dx[r]
y=y+w*dy[r]
mmv(x,y,10)
next
btn(left,up)
|
きっともっと綺麗な書き方があると思うのですが、挑戦の意味を込めて投稿です。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import System.Random
import Text.Printf
direction = [(1, 0), (0, 1), (-1, 0), (0, -1)]
printPoint :: (Int, (Int, Int)) -> IO ()
printPoint (n, (x, y)) = printf "%4d%4d%4d¥n" n x y
addPair (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
main = do
gen <- getStdGen
mapM_ printPoint $ take 10 $ zip [1..] $ scanl addPair (0, 0) $ map (\x -> direction !! (mod x 4)) $ randoms gen
|
僕もhaskellの練習で作ってみました。長くなってしまった。乱数の使い方が難しくって強引な事(unsafeを利用している)をしたけど、mattanさんがやってるようなすっきりとした利用方法があるんですね。
>writeRW2D "file.name" 100
時刻0-99までのxy位置が書かれる。
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 | import System.IO.Unsafe
import System.Random
type XYPlot a = (a,a)
random4:: IO Int
random4 = getStdRandom (randomR (0,3))
nextStep:: XYPlot Int -> IO Int -> XYPlot Int
nextStep (x,y) iorand
| rand == 0 = (x+1,y)
| rand == 1 = (x,y+1)
| rand == 2 = (x-1,y)
| rand == 3 = (x,y-1)
where rand = unsafePerformIO $ iorand
randomWalk2D:: XYPlot Int -> [XYPlot Int]
randomWalk2D (x,y) = [(x,y)]++randomWalk2D (nextStep (x,y) random4)
formatRW2D:: XYPlot Int -> String
formatRW2D (x,y) = (show x) ++ " " ++ (show y) ++ "\n"
rw2DtoStr:: Int -> [XYPlot Int]->String
rw2DtoStr count (x:xs) = show count ++ " " ++
formatRW2D x ++ (rw2DtoStr (1+ count) xs)
rw2DtoStr count [] = ""
writeRW2D::FilePath -> Int ->IO()
writeRW2D fname terminal =
writeFile fname $rw2DtoStr 0 $take terminal $randomWalk2D (0,0)
|
座標の表現に複素数を使ってみました。描画はこの出力を gnuplot なり何なりに食わせてやればよいでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | (use srfi-27)
(define wvec '#(+1 -1 +i -i))
(define (main args)
(let ((n (string->number (cadr args)))
(l (vector-length wvec)))
(random-source-randomize! default-random-source)
(let random-walk ((m 0)
(pos 0))
(when (< m n)
(format #t "~A ~A ~A~%" m (real-part pos) (imag-part pos))
(random-walk (+ m 1) (+ pos (ref wvec (random-integer l))))))
0))
|
適当に。
1 2 3 4 5 6 7 8 9 10 11 12 13 | from random import uniform
from itertools import islice
from math import sin,cos,pi
def randomwalk(x = 0,y = 0):
while True:
rad = uniform(0,2*pi)
x, y = x + cos(rad), y + sin(rad)
yield (x,y)
def main():
for i,(x,y) in enumerate(islice(randomwalk(),10)):
print i,x,y
|
Processing は可視化が容易です。とりあえずシンプル版。
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 | int x, y, t;
int d = 1;
void setup() {
x = width / 2;
y = height / 2;
t = 0;
// randomSeed(0);
}
void draw() {
t += 1;
float r = random(1);
if (r < 0.25) {
x += d;
} else if (r < 0.5) {
x -= d;
} else if (r < 0.75) {
y += d;
} else {
y -= d;
}
point(x, y);
println(t + " " + x + " " + y);
}
|
複数の点を扱いアニメーションにした版。 点を増やしていくとランダムウォークと拡散が関係していそう、というのが分かりますね。
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 | int n = 1000;
int t;
Particle[] particles = new Particle[n];
int hsb = 16;
void setup() {
colorMode(HSB, hsb);
size(200,200);
smooth();
for (int i=0; i < n; i++) {
Particle p = new Particle(width/2, height/2, 1);
particles[i] = p;
}
}
void draw() {
t += 1;
float xm = 0;
float ym = 0;
for (int i=0; i < n; i++) {
Particle p = particles[i];
p.move();
xm += p.x;
ym += p.y;
p.render();
}
println(t + " " + xm/n + " " + ym/n);
rectMode(CORNER);
fill(hsb, hsb * 0.25);
rect(0, 0, width, height);
}
class Particle {
int x;
int y;
int d;
Particle(int x_, int y_, int d_) {
x = x_;
y = y_;
d = d_;
}
void move() {
float r = random(1);
if (r < 0.25) {
x += d;
} else if (r < 0.5) {
x -= d;
} else if (r < 0.75) {
y += d;
} else {
y -= d;
}
}
void render() {
point(x, y);
}
}
|
大変おもしろいと思いました。:-)
Squeak Smalltalk で。
1 2 3 4 5 6 7 8 | | pen origin out time |
pen := Pen new defaultNib: 1; color: Color red; place: (origin := Display center).
out := FileStream fileNamed: 'out.txt'.
time := 0.
[(time := time + 1) < 1e3] whileTrue: [
out nextPutAll: time printString; tab; nextPutAll: (pen location - origin) printString; cr.
pen turn: 360 atRandom; go: 5].
out edit
|
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 | using System;
using System.Collections.Generic;
using System.IO;
class Program {
static void Main(string[] args) {
RandomWalk rndwalk = new RandomWalk(int.Parse(args[0]));
while(true) {
if(Console.ReadLine() != "end") {
foreach(int i in rndwalk.Tic()) {
Console.Write(i.ToString() + " ");
}
Console.WriteLine();
} else {
break;
}
}
rndwalk.WriteLog(Environment.CurrentDirectory + "\\" + args[1]);
using(StreamReader sr = new StreamReader(Environment.CurrentDirectory + "\\" + args[1])) {
while(!sr.EndOfStream) {
Console.WriteLine(sr.ReadLine());
}
}
Console.ReadLine();
}
}
class RandomWalk {
int rank;
List<int[]> log = new List<int[]>();
Random rnd = new Random();
int[] direction = new int[] { -1, 1 };
public RandomWalk(int rank) {
this.rank = rank;
log.Add(new int[rank]);
}
public int[] Tic() {
int changeRank = rnd.Next(0, rank);
int[] pre = log[log.Count - 1];
int[] ticedPoint = new int[rank];
for(int i = 0; i < rank; i++) {
if(i == changeRank) {
ticedPoint[i] = pre[i] + direction[rnd.Next(0, 2)];
} else {
ticedPoint[i] = pre[i];
}
}
log.Add(ticedPoint);
return log[log.Count - 1];
}
public void WriteLog(string fileName) {
using(StreamWriter sw = new StreamWriter(fileName)) {
for(int time = 0; time < log.Count; time++) {
int[] point = log[time];
sw.Write(time + " ");
foreach(int i in point) {
sw.Write(i.ToString() + " ");
}
sw.WriteLine();
}
sw.Close();
}
}
}
|
貧相ですが,画面上に表示する様にしてみました。
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
|
出力はSVGにしてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | private import std.stdio, std.math, std.random;
void main() {
write(`<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="600" height="600">
<title>ランダムウォーク</title>
<g transform="translate(300,300)">
<circle style="fill:blue" cx="0" cy="0" r="5"/>
<path style="fill:none; stroke:black; stroke-width:1" d="M 0 0`);
auto rgen = Random(unpredictableSeed);
auto uniform = UniformDistribution!(real)(0, PI * 2);
foreach(_; 0 .. 10000) {
auto angle = uniform.next(rgen);
auto move = expi(angle) * 10;
writef(` l %.2f %.2f`, move.re, move.im);
}
write(`"/>
</g>
</svg>`);
}
|
なぜかRで 1-1と2-1は解いてません 本職の人はどう書くんでしょう?
see: R-Tips
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | t <- 1000
#1次元
plot(cumsum(c(0,2*floor(2*runif(t-1))-1)),type="l")
#2次元
x <- 0
y <- 0
f.x <- function(t){switch(t,1,-1,0,0)}
f.y <- function(t){switch(t,0,0,1,-1)}
w <- floor(4*runif(t)+1)
move.x <- unlist(lapply(as.list(w),f.x))
move.y <- unlist(lapply(as.list(w),f.y))
x <- x + cumsum(move.x)
y <- y + cumsum(move.y)
plot(x,y,type="b")
#3次元
library(scatterplot3d)
z <- 1:t
scatterplot3d(x,y,z,pch=20)
|
本職ではありませんが・・・
simecolというライブラリーに、ランダムウォークを実装するためのフレームワークが用意されています。
もちろんアニメーションもします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | library(simecol)
size <- 50
obj <- rwalkModel(
parms = list(size=size, area=c(0, size, 0, size)),
init = data.frame(time=0, x=size/2, y=size/2),
times = c(from=0, to=100, by=1),
main = function(time, init, parms) {
r <- 2 * pi * runif(1)
data.frame(time=time, x=((init$x + cos(r)) %% parms$size),
y=((init$y + sin(r)) %% parms$size))
}
)
sim(obj, animate=T)
|
2次元も1次元と同じような書き方でいいと思いますが。
1 2 | w <- floor(4*runif(t)+1)
plot(cumsum(c(1,-1,0,0)[w]),cumsum(c(0,0,1,-1)[w]),type="b")
|
もっといえば、1~4の乱数が欲しいようなときはrunif()ではなくsample()を使った方がRっぽいかもです。
1 | plot(cumsum(data.frame(x=c(1,-1,0,0), y=c(0,0,1,-1))[sample(4, t, replace=T),]), type="b")
|
画像が置けないので、画面イメージはBLOGに貼っています。
"Run"ボタンを押すたび100回ずつ動きます。
"Groovy in Action"を参考にしました。
実行結果
-------------------------
以下のURLに画面イメージ貼り付け。
http://d.hatena.ne.jp/nemo_kaz/20080730
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 | import groovy.swing.SwingBuilder
import java.awt.Color
import java.awt.BorderLayout as BL
import javax.swing.WindowConstants as WC
import javax.swing.BorderFactory as BF
import javax.swing.JOptionPane
swing = new SwingBuilder()
paint = swing.action(
name: 'Run',
closure: this.&paintGraph,
mnemonic: 'R',
accelerator: 'ctrl R'
)
about = swing.action(
name: 'About',
closure: this.&showAbout,
mnemonic: 'A',
accelerator: 'F1'
)
frame = swing.frame(title:'2次元ランダムウォーク',
location:[100,100], size:[300,300],
defaultCloseOperation:WC.EXIT_ON_CLOSE) {
menuBar (){
menu(mnemonic:'A','Action'){
menuItem(action:paint)
}
glue()
menu(mnemonic:'H','Help'){
menuItem(action:about)
}
}
panel (border:BF.createEmptyBorder(6,6,6,6)) {
borderLayout()
vbox(constraints: BL.CENTER,border:BF.createTitledBorder('Runボタンを押すたびに100回動きます')) {
panel(id:'canvas')
}
hbox (constraints: BL.SOUTH){
hstrut(width:10)
button(action:paint)
}
}
}
frame.show()
def labeledSpinner(label, value){
swing.label(label)
swing.hstrut()
swing.spinner(id:label, stateChanged:this.&paintGraph,
model:swing.spinnerNumberModel(value:value))
}
gfx = swing.canvas.graphics
gfx.color = new Color(255, 255, 150)
gfx.color = Color.red
xpos = 100
ypos = 100
def paintGraph(event) {
int width = swing.canvas.size.width
int height = swing.canvas.size.height
1.upto(100) {
xdir = Math.random()
ydir = Math.random()
if (xdir <0.3333 && xpos >5) { xpos-=5 }
if (xdir >0.6666 && (xpos < width-5)) { xpos+=5 }
if (ydir <0.3333 && ypos >5) { ypos-=5 }
if (ydir >0.6666 && (ypos <height-5)) { ypos+=5 }
gfx.fillRect(xpos,ypos,4,4)
}
}
void showAbout(event) {
JOptionPane.showMessageDialog(frame,
'''2次元ランダムウォーク
赤い四角がランダムに歩きます。''')
}
|
Java がまだ投稿されていなかったので、Swingで表示するものを作ってみました。
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class RandomWalk extends JFrame {
private static final int WIDTH = 640;
private static final int HEIGHT = 480;
private static final Dimension PLOT_SIZE = new Dimension(WIDTH, HEIGHT);
private final JTextField countField_ = new JTextField(8);
private final JButton startButton_ = new JButton(new AbstractAction("開始") {
public void actionPerformed(ActionEvent e) { start(); }
});
private final JButton stopButton_ = new JButton(new AbstractAction("停止") {
public void actionPerformed(ActionEvent e) { stop(); }
});
private final JButton endButton_ = new JButton(new AbstractAction("終了") {
public void actionPerformed(ActionEvent e) { dispose(); }
});
private final Random random_ = new Random();
private volatile boolean walking_ = false;
private final List<Point> points_ = new ArrayList<Point>();
public RandomWalk() {
super("2次元ランダムウォーク");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
configure();
Box main = Box.createVerticalBox();
main.add(createOperationArea());
main.add(createPlotArea());
|





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 ]