Archiverse Internet Archive
投稿のみ 投稿と返信
前のページ(最近)
1111 112 113 114 115 116 117 118 119 120 121 122 123
次のページ(過去)
返信[6]
親投稿
れい rei-nntnd
これは乱数を最大値でそろえるときにMODULOを使っているからですね。 よくあるダメな手法。 回避方法は2の累乗など2^32を割り切れる数値しかつかわないこと。RND(256)とかRND(1024)とか。 X=RND(400):Y=RND(200) みたいな乱数発生は厳密にはちょっとまずい
2そうだね
プレイ済み
返信[5]
親投稿
れい rei-nntnd
報告。 乱数そのもののチェックはまだおわってないけどRND(x)の実装は問題ありですね 例えばこんなの M=1879048192:C1=0:C2=0 FOR I=1 TO 10000 R=RND(M) IF A<M/2 THEN INC C1 ELSE INC C2 NEXT PRINT STR$(C1)+" "+STR$(C2) 大きい乱数を作って半分より大きいものと小さいものの個数を数えるだけ。 半分だから当然同じくらいの数になるはずだけど…
0そうだね
プレイ済み
返信[1]
親投稿
れい rei-nntnd
見るからに自分には抜けられなそうな弾幕なんですが…
0そうだね
プレイ済み
返信[26]
親投稿
れい rei-nntnd
4096周期のLCGより悪くなってしまってますので、 周期を伸ばすために2つをつなげるのであれば独立させるべきだと思いますよ。
0そうだね
プレイ済み
返信[4]
親投稿
れい rei-nntnd
でもですね スライムを倒すよりドラゴン倒した方が経験値いっぱいもらえるんですよ! それに最近はパワーレベリングという言葉もありまして せっかく場所があるんだから何でも聞いたらいいじゃん お礼だって言えないシャイな子もいるだろうし 答えてる人だってお礼が聞きたくて答えてるわけじゃないでしょ 道徳おしつけてメンドクさい場所になるより 質問も会話も適当に書けるほうがらくでいいと思うけどなー
1そうだね
プレイ済み
返信[24]
親投稿
れい rei-nntnd
あ、説明たりないかな どういうことをやってるかというと、連続で2つ乱数作ったとき、それぞれの下位2ビットがどんな頻度で出現するかを見ているんです。 本当の乱数なら、C(0)~C(15)まで同じような値が入らないといけない。 でも、1000以上現れるパターンと一回も現れないパターンの2種しかない。 これは連続でとった2回の乱数が非常に強く相関していることと、 周波数分布が偏ってることを意味します。 実際によくあるのが画面にランダムに敵を配置するとき。 XYの2回連続で乱数を呼んで敵を配置するのに、何個敵を配置しても「重なっちゃう」ことになる。 なので乱数としてはダメってことなんです。
0そうだね
プレイ済み
返信[23]
親投稿
れい rei-nntnd
結果はコレ。 1476/0/0/1023/0/0/1024/1477/0/1023/1477/0/1024/1477/0/0/ 2つのLCGの周期が近すぎて、2回連続で乱数を作ると明確な関連が出てきてしまうんです。 もうそれは乱数じゃありません。 2つのLCGを使って周期を伸ばしたければ、 2つのLCGを独立に動かしたうえで、最後に合成しなければダメなんです。
0そうだね
プレイ済み
返信[22]
親投稿
れい rei-nntnd
それでもダメなんです… 確かに4096と1しか離れていない4095を使えば「互に素」ですから周期は伸びるんですが… 今度は近すぎて乱数じゃなくなっちゃう。 こちらを動かしてみてください。(たぶんmkIIで動く) X=0:Y=0:DIM C[16] FOR I=0 TO 10000 GOSUB @RND:X1=(X AND 3):GOSUB @RND:X1=(X AND 3) J=X1+X2*4:C(J)=C(J)+1 NEXT FOR I=0 TO 15 PRINT STR$(C(I))+"/"; NEXT END @RND Y=(Y+1)%4095:X=(X*117+Y)%4096 RETURN
0そうだね
プレイ済み
返信[19]
親投稿
れい rei-nntnd
たぶん大丈夫ですよ。 409を4096で割ると0.099853515625 410は0.10009765625 なので0.1をmkIIの固定小数点で表すと409 同様に1.1は4505 なのでおちゃめさんのアルゴリズムは整数化すると Yn+1=(Yn+409) mod 4505 Xn+1=(Xn*117 + Yn) mod 4096 で、あってますよね。 この変形LCGの周期が問題で、 恐らくLCG二つだからそれぞれの周期4505と4096をかけて18452480の周期があるはずという主張なんだと思うけど、 実際に計算すると4613120。 YをXのmoduloのなかに入れちゃってるから周期が消えちゃう。 今回は1/4になっちゃってる。
0そうだね
プレイ済み
返信[17]
親投稿
れい rei-nntnd
いやだから… そのアルゴリズム、数値だと460万回の周期になってますよと。 1800万回の保証はありません。 ぜひ実際に試してみてくださいな。
0そうだね
プレイ済み
返信[3]
親投稿
れい rei-nntnd
本当に大丈夫なのか、もうちょっと検証してみたいんですが… プチコンのアルゴリズムがわからないので プチコン上で検定しないといけなくて… 重くてやってられない!
0そうだね
プレイ済み
返信[15]
親投稿
れい rei-nntnd
プチコンmkIIは持ってないので 固定小数点やmoduloの仕様がわかりませんが、 @RND Y=(Y+0.1)%1.1 X=(X*117+0.2)%1 R=(X-Y+0.9998)%0.9998 IF R==0 THEN R=0.9998 RETURN こんな感じのを代わりにいれてみてください。 きちんと4096*4505≒1800万回の周期が出ます。
0そうだね
プレイ済み
返信[14]
親投稿
れい rei-nntnd
うーん… 何処で見つけたのか、どう計算したのかわかりませんが、残念ながらそれだとアルゴリズムがダメなので最大周期が保証されてないんですよ 証明は…余白が足りないから省略。 X=0:Y=0 FOR I=0 TO 2000:FOR J=0 TO 9999 GOSUB @RND IF X==0 AND Y==0 THEN GOTO @AAA NEXT:NEXT @AAA PRINT STR$(I)+RIGHT$("000"+STR$(J),4) こんな感じで試してみてくださいな 初期値が0,0なら4613119回で抜けてしまいます
0そうだね
プレイ済み
返信[3]
親投稿
れい rei-nntnd
できれば超絶テクニックを持つ人のリプレイが。 眺めてて感動できるようなやつを… うまい人のプレイは眺めるだけでワクワクです。
0そうだね
プレイ済み
返信[9]
親投稿
れい rei-nntnd
あー… その乱数生成器は残念ながらダメなんです… 線形合同法(以下LCG)で周期を伸ばすのには、縦につなげてしまうと周期は二つの掛け算にはならず、もっともっと小さくなってしまいます。 やってみればわかりますが、それだとよくて200~400万、種によっては数万になってしまうかと。 また、あまりよくないモアレ的なものが出てしまいます。 LCGを組み合わせて周期を伸ばすには、並列でつなぐ方法を用います。 Y=(Y+0.1)%1 X=(X+0.2)%0.99 R=(X-Y)%(0.9997) if R=0 then R=0.9997 こんな感じで。(固定小数点の計算は適当w これをCombined Linear Congruential Generator(CLCG)と言います。 ほぼ同じ計算量で周期はきちんと二つのLCGの掛け算になり、怪しいモアレも出にくくなります。
0そうだね
プレイ済み
返信[17]
親投稿
れい rei-nntnd
さっき作った有名な高速乱数生成アルゴリズムXorShift(G.Marsaglia,2003) 残念ながらプチコンではあまり意味ないみたい。 便利な関数まとめたライブラリ誰かつくってくれないかなぁ(ひとまかせ
0そうだね
プレイ済み
返信[1]
親投稿
れい rei-nntnd
めちゃたのしみだけど多分避けられなくてイライラしてコードいじってしまうと思う 無敵モードかお手本モードください
0そうだね
プレイ済み
投稿
れい rei-nntnd
XorShiftによる乱数生成関数と速度の比較。 DEE3D4 XorShiftは32ビットと128ビット。 どちらも100000回で数百フレーム。 標準の乱数生成関数RNDは50程度。 標準の早い! 乱数の優劣は調べてないが、XorShiftで速度が叶わないなら自前で作るメリットはかなり少ないっぽい。
7そうだね
プレイ済み
返信[6]
親投稿
れい rei-nntnd
同じ乱数列を生成したいときでしょ シミュレーションとかだと必須 そういやプチコンの乱数生成の速度はかってないや 遅かったらXorShiftでも組んでみるかな
0そうだね
プレイ済み
返信[4]
親投稿
れい rei-nntnd
そういやプチコンの乱数はなにつかってんだろうなぁ メルセンヌツイスタってことはないだろうし
1そうだね
プレイ済み