スマートフォンアプリエンジニアを募集しています | Technology-Gym
最近、自分のTwitterのTLでこの問題ってどうやって解くんだろう?って話題になってた。いわゆる普通のパス探索アルゴリズムの話なんだけど、ゲーム業界とかなら普通にA*アルゴリズムダイクストラ法とかで解くんだろうな~と思ってたけど、普通の?プログラマはどうもA*とか知らないと総当りで(といっても、ループ排除やら計算済みコストからの分岐の刈りこみをしつつ)計算したコスト一覧をソートしてっていう力技が最初に思いつくみたいだ。
自分もA*アルゴリズムっぽい(どうやらA*とダイクストラ法がごっちゃになってたみたい 指摘されてちと直しました)ので解いてみたんだが、今日ふとあるブログのエントリーを思い出して「コレはいけるんじゃないか?」って思って実践したアルゴリズムがある。
常識を覆すソートアルゴリズム!その名も"sleep sort"! - Islands in the byte stream
思い出したブログのエントリーはこちら、そう、複数プロセスを走らせて数値の秒数だけSleepすることでソートをしてしまおうというスリープアルゴリズム!
これを応用して、スリープ探索アルゴリズムを組んでみた。
class node { //ノードに付いてるアルファベット public string c; //パス一覧<次のノードのID, ノードへのコスト> public Dictionary<int, int> path = new Dictionary<int, int>(); } static List<node> data = new List<node>();まずは、この形のデータを用意する。いわゆる普通のノードデータ一覧だね
class NemurinoKogoro { int Index; //ノードのインデックス int SumCost; //今までのトータルコスト int Cost; //このノードに着くためのコスト string Answer; //問題の答えとなるために経路でたされてきた文字列 //スレッドに引数を渡すためにオブジェクトに値をコピー public NemurinoKogoro(int index, int sum_cost, int cost, string ans) { Index = index; SumCost = sum_cost; Cost = cost; Answer = ans; } //スレッドで実行 public void Exec() { //答え文字列を追加 Answer += data[Index].c; //トータルコスト計算 SumCost += Cost; //コストの分お休み Thread.Sleep(100 * Cost); //ゴールのIndexなら出力して終了 if (Index == 15) { Console.WriteLine("ゴール!:{0}:{1}", Answer, SumCost); return; } //自分のノードから伸びているパスの分だけ //眠りの小五郎クラスを複製してマルチスレッドで実行 foreach (var item in data[Index].path) { var t = new NemurinoKogoro(item.Key, SumCost, item.Value, Answer); new Thread(new ThreadStart(t.Exec)).Start(); } } }
引数付きでスレッド呼び出しをするためのクラスを作る。
そして、メインスレッドからは・・・
//小五郎のおっちゃん頼む! new NemurinoKogoro(0, 0, 0, "").Exec(); //あとは寝て待て Thread.Sleep(100 * 1000);
以下実行結果
ゴール!:XXXXXXXXX:XX //一応答えなので隠しておきます ゴール!:SealthG:27 ゴール!:SheaeothG:27 ゴール!:SeaeothG:28 ゴール!:SjlthG:28 ゴール!:SheeothG:28 ゴール!:SeeothG:29 ゴール!:SjalthG:29 ゴール!:SjealthG:30 ゴール!:SjaeothG:30 ゴール!:ShealthhG:30 ゴール!:SjeaeothG:31 ゴール!:SheaeothhG:31 ゴール!:SealthhG:31 ゴール!:SjeeothG:32 ゴール!:ShunhG:32
おぉ、なんかちゃんとソレっぽい答えが出ましたw
このアルゴリズムだと、ノードが循環して無限ループするのとか気にすることも、ソートのためにデータを保持しておくことも、探索の刈りこみをすることもなーんもしないでも一応答えが出る。簡単だ
しかも、同一コストの別ルートも同時に表示できるね、面白い!
0 件のコメント:
コメントを投稿