ページ 68

クイックソート(入門編)について

Posted: 2005年11月24日(木) 21:41
by omasu
お世話になります。

 ついにクイックソートを真似できました。


しかし、最悪のデータの並びの存在、スタックオーバーフロー対策等、
 何も考えていないため、今後の課題としたいと思います。

Posted: 2005年11月24日(木) 22:11
by マティ
ネットで検索するとomasuさんが投稿したようなコードが上位でヒットします。
このコードを使用した結果クイックソートって、動作が不安定だなって思っていました。
(だから不安定ソートって勘違いしたくらいです。)
このアルゴリズムでは、件数が多くなるとスタックオーバーを引き起こします。
また、元データが逆順の場合に性能が最悪になります。

初心者向けにも河川屋さんが投稿したロジックを元に移植する事を推奨します。
http://www.discoversoft.net/forum/viewt ... c&start=16

omasuさん、これからも頑張って下さい。

PS.ActiveBasicは、SubFunctionを使用しない方が早いようです。

アニバーサリー

Posted: 2005年11月24日(木) 22:56
by omasu
マティさんへ
 ありがとうございます。

 ごさっしのとおり(m!m)
ネットで探しまわり、直感で一番解りやすいロジックを参考にABに模倣移植しました。
 参考文献はC言語が圧倒的に多く、VBが続き、ABでは皆無です。
 クイック=難しい、ABで私のような初心者には理解しやすいと感じ投稿しました。

追伸:arさんのマージソートは実行比較環境に何とか移植できました、
   arさんのクイックソートは、私の手には負えません。
   どなたか!・・・
追伸:今、ヒープを登頂中です。難しすぎます。

Posted: 2005年11月24日(木) 23:18
by イグトランス
河川屋さんのコードのコメントを読み返してみましたが,結局辿り着くところは同じようで,
私が読んでいる本に書いてあることと同じことを実践されています。(改3まで)

それでもやる気をなくしたわけではありませんから,やるだけやりますよ。
(最近プログラミングに割ける時間が少なくて←言い訳)

Posted: 2005年11月24日(木) 23:22
by マティ
omasuさん以下のロジックで動作するでしょうか?
初心者向けに、分かりやすくしたつもりです。

アニバーサリーⅡ

Posted: 2005年11月24日(木) 23:54
by omasu
お世話になります。

 イグトランスさんへ
  ありがとうございます。
   今、大変心強さを感じております。

 マティさんへ
  たったこれだけの時間でこのようなロジックを組める???
   不思議としか言いようがないです。
両方から攻める方法は少し難しいです。

クイックソート

Posted: 2005年11月26日(土) 17:59
by イグトランス
 とりあえず形になったので投稿します。
単に数値化するだけでも随分と早くなるだろうと企んだわけですが,
思惑は外れ大して早くなりませんでした。

クイックソート5、挿入ソート3について

Posted: 2005年11月26日(土) 18:27
by omasu
イグトランスさんへ(皆さんへ)
 ありがとうございます。

 クイックソート5 !!!!!m(_ _)m!!!!!

 挿入ソート3 !!!m(_ _)m!!!

覚悟を決め、実行してみます。
 非常に高度なため、とりあえずでは動かせそうもないですが、
 コピー、ペースト、実行 ※とりあえずではいきなり終了します。
 (ところどころで設定すべき箇所があると思われます。)

自己流クイック(中級編?)

Posted: 2005年11月26日(土) 21:00
by omasu
お世話になります。

 自己流のクイックソート(中級編?)を作成しました。

皆様のクイック速度安定施策を参考に作成しました。

 ご指導のほどよろしくお願いします。
①最悪のデータ配列に対応
 先頭と中央と最後のデータの3件の内、中央値を基準値とする
②スタックオーバーフローに対応
 再帰処理は件数の小さい方から実行する
③速度向上に対応
 ある程度細かくなったら単純挿入ソートに移行する
 ※10(9)件は3件~30件までのテストにより最高値を採用
追伸:投稿後にバグに気づきバグつぶしをしてしまいました。
   冷や汗が出ました。

Posted: 2005年11月26日(土) 23:57
by イグトランス
すみませんでした。
以下の部分を消して,infileXXX.csvのあるフォルダへのパスを変数Pathへ代入してください。

コード: 全て選択

#define MAINPC

#ifdef MAINPC
Path = "h:\"
#else
Path = "c:\temp\"
#endif
ところで今回のはデータを全て数値(DWord)へ変換しています。
なので数字しか扱えないので「5桁のランダム数字」に分類してください。
しかし申し訳ありません,2列目だけをキーとして扱っていました。
1列目と2列目をキーとしなければならないのですよね。
今度修正してきます。

Posted: 2005年11月27日(日) 08:29
by マティ
omasuさん先頭と中央と最後をソートし中央値を基準値とする処理ですが、Sが最大となる場合に、Sが基準値となっています。確認してください。

omasuさんのコード

コード: 全て選択


       P=(S+E)\2
       If lstrcmp(KeyTable[Index[P]],KeyTable[Index[E]])>0 Then ' 最悪のパターンを減らすため
          Swap(Index[P],Index[E])                               ' 先頭と中央と最後をソート
       EndIf
       If lstrcmp(KeyTable[Index[S]],KeyTable[Index[P]])>0 Then
          Swap(Index[S],Index[P])
       EndIf
       Swap(Index[S],Index[P])                                  ' ソートした中央値を基準値とする
       P=S
これだとちゃんと基準を取れると思います。置き換えてみて下さい。

コード: 全て選択


    P=(S+E)\2
    ' 最悪のパターンを減らすため、先頭と中央と最後をソート
    If lstrcmp(KeyTable[Index[S]],KeyTable[Index[P]])>0 Then
        Swap(Index[S],Index[P])
    EndIf
    If lstrcmp(KeyTable[Index[P]],KeyTable[Index[E]])>0 Then
        Swap(Index[P],Index[E])
        If lstrcmp(KeyTable[Index[S]],KeyTable[Index[P]])>0 Then
            Swap(Index[S],Index[P])
        EndIf
    EndIf
    ' Pに中央値が入っています。

コーディングミスについて

Posted: 2005年11月27日(日) 09:11
by omasu
お世話になります。

 マティさんの言われるとおりでした。
  バグのほかにコーディングミスまでしてしまいました。
   [いろは]の[い]にまで、お気遣いありがとうございます。

 実行時間はネストが一段深くなったため、遅くなると思いきや
  速度が速くなりました。
追伸:皆様の上級編に近づけるようがんばります。

クイックソート5、挿入ソート3について

Posted: 2005年11月27日(日) 13:22
by omasu
お世話になります。

 イグトランスさんのクイックソートが動きました。

 しかし、私の動かし方が悪いのか、

 入力ファイル 千件の出力件数は 864件・・・ソートはされています。
 〃     一万件 〃    1794件・・・ソートはされています。
 〃     十万件 〃    4369件・・・ソートはされています。

また、例の私の環境のメモリ256MBの影響かもしれません。
   ちなみの 千件のソートは0秒
       十万件     6.578秒です?????

スタック数とかメモリ制限とか、いろいろ調べる必要があるやもしれません。

Posted: 2005年11月27日(日) 21:45
by イグトランス
それは単に私のバグに違いありません。
#クイックソート1つ書けないでどうするんだ,俺。

コーヒーブレイク

Posted: 2005年11月28日(月) 21:06
by omasu
お世話になります。

 ちょっと休憩します。

私の年はいくつだと思いますか?