hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
アルゴリズム/迷路/Dev-Hole - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

ここのアルゴリズムを考える

ここの穴掘り法について考えていきましょう。


  • 速い!でも102行ここには敵いません;; -- Charlotte 2005-05-28 11:36:15 (土) New!
    • 早すぎorz何故早いのかここのを解読中です。--kz3 2005-05-28 12:08:25 (土) New!
    • 現在管理人にソースの一部を掲載して議論してよいかどうか確認中。--kz3 2005-05-28 13:52:06 (土)
    • だったらその場で管理人に聞いちゃえばよい、とか思ったり思わなかったり・・・
    • 新企画だw -- Charlotte 2005-05-28 14:08:49 (土)
  • 現在回答待ち。そしてソースにフルコメント化。@@; -- kz3 2005-05-28 14:14:45 (土)
  • おお! で、この雑談リンクがないです;; -- Charlotte 2005-05-28 14:17:30 (土)
  • あ、迷路のコメントからリンク貼ってますよ^^; -- kz3 2005-05-28 14:18:36 (土)
  • あっ。貼ってました。。。解決後に雑談に移動します。 -- Charlotte 2005-05-28 14:20:42 (土)
    • 雑談はpukiwiki公式のようにしたいと考えております。 -- Charlotte 2005-05-28 14:24:11 (土)
    • ページ構成の事と思ってよろしいですか?どのようになさってもOKです^^--kz3 2005-05-28 14:30:34 (土)
    • どうもです。 -- Charlotte 2005-05-28 14:31:26 (土)
  • 回答は夜になると、おもわれ。 -- Charlotte 2005-05-28 14:35:50 (土)
  • 全てを完全に理解するのは、いつになるか分かりませぬ・・・;; -- kz3 2005-05-28 14:38:08 (土)
    • だいたいならわかるような・・・。う〜m -- Charlotte 2005-05-28 14:40:07 (土)
  • ようするに、ただログとって戻るからすごい速いわけですよね。 -- Charlotte 2005-05-28 14:46:25 (土)
  • そうなんですよ、僕だって一応ログは取ってるんですが、ログ取りの方法が違うのかな・・・ -- kz3 2005-05-28 14:49:54 (土)
  • あと僕はソース見やすくするために2次元配列使ってるから遅いのかも・・・ -- kz3 2005-05-28 14:54:49 (土)
  • ふ、分かってきた^^; -- kz3 2005-05-28 14:57:19 (土)
  • 進むたびにログをとってる模様 -- Charlotte 2005-05-28 15:04:46 (土)
  • b,bb,hantメンバ(構造体じゃないけど)の意味完全理解b -- kz3 2005-05-28 15:06:56 (土)
    • hantは4方向に進むためかな? -- Charlotte 2005-05-28 15:19:43 (土)
  • その通り! -- kz3 2005-05-28 15:21:10 (土)
  • backはスタックですね。progがスタックポインタで進むとどんどん上書き。 -- kz3 2005-05-28 15:26:54 (土)
  • うむうm、これ思いつくのはすごいですねw -- Charlotte 2005-05-28 15:28:18 (土)
    • って変数メンバ=ソース ∴ソース無断公開かな・・・;; -- kz3 2005-05-28 15:28:27 (土)
  • 僕のログ取りはマップに直に記録していますよね。 -- kz3 2005-05-28 15:29:35 (土)
  • 概要はつかめた。ひとまず、僕のソースも2次元配列→1次元配列に直してみます -- kz3 2005-05-28 15:33:02 (土)
  • 変数メンバ=ソース う〜んそこら辺微妙ですよね。 -- Charlotte 2005-05-28 15:43:35 (土)
  • データ構造変更完了。正常動作確認。早くなったかは・・・疑問;; -- kz3 2005-05-28 16:13:48 (土)
  • 変更版はどこにUPしたらいいでしょう? -- kz3 2005-05-28 16:17:49 (土)
  • ver.1とかつけてさいUPまたは上書き(消さないといけない)でお願いします。 -- Charlotte 2005-05-28 16:21:47 (土)
    • 迷路に追加しておきます。見やすい編集をお願いしますm_ _m -- kz3 2005-05-28 16:25:52 (土)
      • 了解ですw -- Charlotte 2005-05-28 16:28:14 (土)
  • 棒倒し法の要領でやってみると速いかもしれない -- Charlotte 2005-05-28 16:50:41 (土)
  • 戻りすぎのせいで完成に満たないようです;; -- Charlotte 2005-05-28 16:52:53 (土)
  • 戻りすぎ!?バグですか!?デバッグだ・・・orz -- kz3 2005-05-28 16:56:01 (土)
  • デバッグ完了しました!!ver2.1にします。バグとりなのでね^^ -- kz3 2005-05-28 18:25:50 (土)
  • 偶数座標はぜったいに掘らないといけないから・・・。 -- Charlotte 2005-05-28 16:55:22 (土)
  • 迷路如きがこんなに難しいとは。こうなったら最短ソースを目指すw -- Charlotte 2005-05-28 17:00:30 (土)
  • ここの管理人さんから許可が出たので、「解読」の方にレスをつけていきます^^ -- kz3 2005-05-29 08:44:00 (日)
  • メンバの名前が微妙に変わってる;;--kz3 &now

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

(仮)解読

  • ログ取りの仕方は違えど、戻って行ける方向を選択して行ければ進む、全く行けなければ戻るの繰り返しですね。 -- kz3 2005-05-28 16:35:24 (土)
  • どこで差が出てくるのかという事も分かりました。 -- kz3 2005-05-28 16:35:45 (土)
  • 自分がいうのもどうかと思いますが、戻りすぎている所があるような。。 -- Charlotte 2005-05-28 16:42:25 (土)
    • えぇ!!?ではver3では戻った時に赤く塗ってみようかな!--kz3 2005-05-28 16:48:56 (土)
      • ver3(婆さん)だって、プッ--kz3 2005-05-28 16:48:56 (土)
      • がは!!!--Charlotte
    • ver2.11としました。--kz3 2005-05-28 19:16:55 (土)
  • 計算量(仮)
    進路方向を決定するのに、あちらは固定テーブルを参照するだけなので、多くてもループは4回。
    これが全ルートだと、ループ回数は2304×4=9216回。
    対して僕は一旦進むと方向テーブルを再構築します。
    再構築の際に4回ループします。
    よって僕の場合、多くてループ2601回×4×4=41616回。
  • 4倍違うんですね^^;
  • ルートのかずが2304と2601で違うのは実はあちらはSize99で外周部分もメモリに含まれているので実質迷路を構成するのは48*48マップ。
  • 対する僕はSize51で51*51マップ。外周部分は画面描画で表現しています。
  • Size48でやってみようかな。^^;
  • 結局、方向テーブルを固定か、再構築の為に4回ループするかで、完成までの時間に影響してきますね? -- kz3 2005-05-28 18:43:54 (土)
  • 解読した結果私のアルゴリズムと、revyさん( ここの管理人さんでありソースの作者です)のアルゴリズムでどうしてここまで速度に差が出るのか、それは2つあることが分かりました。
  1. 進路決定の方法
    1. kz3   :毎回乱数で進路を決める
    2. revyさん:固定テーブル
  2. 足跡の記録の仕方
    1. kz3   :マップ(迷路を表現するデータ構造)に直接記録
    2. revyさん:足跡はスタックで管理
  • えっと・・・この後どしよっか;;

進路決定アルゴリズム

  • まずはrevyさんから。最新版meiro2_.asについて書いていきます。
    revyさんの進路決定方法はhantという変数がポイントです。
    (本来ならhantは"4!*4"の全96の要素をもっていなければならないのですが、めんどいので省略しました。)
    meiro2_.asからの抜粋でした。ここで"96の要素"が本来必要という部分ですが・・・
    これは私は64の間違えじゃないかなぁと思ったりしています^^;
    撤回。96でした;;ごめんなさい、revyさん。 「何故96なのか、何が96なのか」はい。
    4方向について進める方向をランダムで探しますがこれは1624通りあります。
    これをrevyさんは固定テーブルとして4パターン作っています。
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
    
     
     
     
     
    
        hant.0 = -SIZE, -1, 1, SIZE    ;方向テーブルの初期化
        hant.4 = SIZE, -SIZE, -1, 1
        hant.8 = 1, SIZE, -SIZE, -1
        hant.12= -1, 1, SIZE, -SIZE
    1つのパターンの0〜3の4要素が移動量を表しています。ので・・・
    24パターン×4要素=96要素
    要素は配列のサイズということです。
    これを手で書いていくのは大変ということで、4パターンにしたと言う訳ですね。
    さてこのテーブルをどうやって使うのか。
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
      5
      6
    
     
     
     
     
     
     
    
        rnd dir, 4             ;”だいたいの”方向決定
        go = 0                 ;二マス先が壁かどうかの判定(後の行で使用)
        repeat 4
            tdir = dir*4+cnt   ;真の方向決定
            hori2 = hant.tdir*2+hito  ;2マス先
            hori1 = hant.tdir+hito    ;1マス先
    
    の部分で方向を決定していますが、進める方向が決まるのに、平均2回方向テーブルを参照するだけで決まります。
  • そしてkz3の方向決定アルゴリズムは・・・ 私のはまるっきりランダムです。
    ですが、まるっきりランダムでは一旦進めないと判断したルートを何度も選択してしまう可能性があります。
    そこで私は重複しない乱数を使っています。
    重複しない乱数はこちら?
    私はwayという配列を方向決定テーブルとして使っています。
    revyさん同様repeat 4で進めるルートが見つかればループを抜けるので平均2回方向テーブルを参照しますが、revyさんと違うのは進む度に方向テーブルを更新します。(=固定ではない)
    この方向テーブル更新にテーブル内をrevyさんより4回余計にループしています。
    仮に迷路本体の大きさが50の時を考えると・・・
    Everything is expanded.Everything is shortened.
      1
      2
      3
    
     
     
     
    
        ;kz3付加コメント:SIZE-3/2が迷路本体なので50*50=2500
        rest = (SIZE-3/2)*(SIZE-3/2) ;残りのマス
        dim back, rest               ;ログ
    
    revyさん方向テーブル平均参照回数:2500*2=5000回
    kz3方向テーブル平均参照回数:2500*6=15000回
    3倍遅いんですね・・・。

ここが大事だよ迷路表現データ構造

revyさんの穴掘り法が早いのはまさにこれです。
これがあるからプログラム=アルゴリズム+データ構造と言われるのです。
revyさんも私も(2次元マップから1次元マップに変更しました)迷路を表現するデータ構造はそれぞれ

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
 
 
 
 
 
 
 
 
    ;revyさん
    #define SIZE 99  ;迷路の大きさ、必ず奇数
    #const HSIZE SIZE*SIZE
    dim meiro, HSIZE ;迷路データ(0-道 1-壁)
 
    ;kz3
    #const _mclass     51        ;迷路の大きさ
    dim maze,_mclass*_mclass ;迷路データ 

やっている事は同じです。が、足跡の記録方法が大きく違います。
まずはrevyさんの足跡の記録方法から。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
-
|
|
|
|
|
-
|
|
|
!
    if go {                ;掘り進む
        back.plog = hito
        meiro.hori2 = 0
        meiro.hori1 = 0
        hito = hori2       ;人移動
        plog++
    }else {                ;戻る
        plog--
        hito = back.plog   ;人バック
        hori2 = -1 : hori1 = -1
    }

進むたびに1つ前の位置(の値)をスタックに積みます。
戻る時はスタックから1つ前の位置(の値)を取り出します。
上の9行目の人バックで人が元の位置に戻るのですが、スタック参照で一発で戻っていますね。 対するkz3はというと・・・

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    ;足跡記録
    repeat 4
        ;いろいろチェック
            if way.cnt=_ftop{    maze.mdig=_bbottom }
            if way.cnt=_fright{  maze.mdig=_bleft }
            if way.cnt=_fbottom{ maze.mdig=_btop }
            if way.cnt=_fleft{   maze.mdig=_bright }
            digno=_digok : break
        ;描画処理は省略で 進んだら
    loop
    if digno=_digok:continue
    if maze.mdig=_start     :break
    if maze.mdig=_btop      :mdig-=_mclass  :continue
    if maze.mdig=_bright    :mdig++         :continue
    if maze.mdig=_bbottom   :mdig+=_mclass  :continue
    if maze.mdig=_bleft     :mdig--

進んだ場合、どの方向から来たのかをその場所に記録します。
戻る時はその場所に記録された来た方向をたどっていきます。
ここで、左に戻るためには4回比較しなければなりません・・・。


  • 書きすぎました・・・;;すみません。ページ構成よろしくお願いしますm_ _m
  • これだから簡潔にまとめる技術が必要なんですよね;; -- kz3 2005-05-29 12:28:47 (日)
    • すごくいいと思いますけどね・・・うん -- Charlotte 2005-05-29 12:30:23 (日)
  • こうなるともう雑談ではないので、迷路のほうに移動したいと思います。 -- Charlotte 2005-05-29 12:57:26 (日)
  • ありがとうございますm_ _m -- kz3 2005-05-29 13:08:10 (日)
  • これより速いのは無理なんですかね。 -- Charlotte 2005-05-29 13:10:43 (日)
  • 早くする方法を思いつきました(ぇ -- kz3 2005-05-29 13:15:04 (日)
  • ログをスタックにしてより早いものに書き換えてみます^^; -- kz3 2005-05-29 13:17:18 (日)
    • おお! -- Charlotte 2005-05-29 13:20:38 (日)
    • データ構造は、ログ取りにスタック(revyさん)、迷路本体に配列(共通)、方向テーブル(kz3)でいきますq -- kz3 2005-05-29 13:30:12 (日)
  • 高速化は前途多難でした;; 簡単に可能なのは、=1と比較するところを&1とすることでしょうか・・・ -- kz3 2005-06-01 10:48:28 (水)


トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-04-08 (日) 02:38:46 (2436d)