ほぼ雑記的メモ
最近すっかりJava屋なワタシ。
今日悩んでいた問題は単純なプログラムなのに異常に処理が遅いということです。
いろいろと調査をしたところ次のようにindexを指定して要素を取り出すプログラムは Vectorのサイズが大きくなると異様に遅いということをハッケンしました。
Vector v; .... for(int i=0 ; i<v.size() ; ++i){ Object hoge = v.elementAt(i); ... }
これを機会にVectorのドキュメントマニュアル読み直しましたところ、こういう場合は黙って iteratorを使うのがよいようです。劇的に早くなりました。
また、サイズの概算があらかじめわかっているのなら、Vectorのコンストラクタであらかじめサイズを指定してやるとよいような気もします。(未確認)
Vectorのリスト管理がどのようなデータ構造でなされているのが知りませんが、こういうTIPSは知っててソンはないでしょう。なんでもVMのせいにすればいいってもんじゃないという見本?
穴の位置にも16のタイルがあると仮定してください。 2つのタイルを入れ替える操作を繰り返し、完成形になるまでの繰り返します。 この入れ替えは隣同士でなく、タイルを盤面から取り、物理的に入れ替えることを意味します。 完成系になるように入れ替えて行くやり方はいろいろあるのですが、ある盤面からある盤面に変換する入れ替えの回数が偶数であるか奇数であるかは最初の盤面の配置で決まります。 すなわち、どのように入れ替えて言っても、完成形になるまでの手数の数は偶数であるか奇数であるかが決まっているのです。これは偶置換と奇置換といって代数学では有名な定理です。 タイルをスライドさせるというのは16とその隣のタイルを入れ替えるということと考えられます。 ところで、最初に16が右下にあると仮定すると奇数回の移動では16のタイルは右下にはやってくることがありません。必ず偶数回の移動をしなければなりません。 したがって、ある盤面から完成形に移動する入れ替えの回数が奇数ならば、どうやっても完成形に持っていくことはできません。 これは例えば1と2が入れ替わっただけの16パズルを解こうと努力をしてみるとわかります。どんなに頑張っても解くことができません。 では、逆に入れ替え回数が偶数ならば解けるのかと言えば、これは真です。(証明は実際にアルゴリズムを提示しないとだめですが) したがって、よりスマートな解法としては 「解けないと判定できたら任意の2つのタイルを入れ替える」 これで必ず解ける16パズルが完成します。
Powered by Red Leaf ( Rev. c78c769f2 ), © Issei Numata, 2007-2021