2010年2月26日金曜日

簡単そうに見えて、とても難しい

今日は、簡単そうに見えて、とても難しい問題に突き当たった。

「頂点数 n, 枝の本数 m のグラフで、multi edge があるかどうかを判断するのが O(m+n) でできるのか」

という問題である。multi edge とは、枝の両端が同じ頂点、つまり、並行している枝のことである。
たとえば、(a,b) で枝が a と b にあるとしたときに、
(1,4), (2,5), (3,4), (2,4), (2,5), (1,3), (1,5)
などとあったときには、(2,5) が2本あるので、 multi edge である。

最初は、頂点の番号でソートすれば簡単だと思ったのだが、それでは O(m+n) にならない。
O(m+n) なので、以下の2つは使えない。
1. ソート( O(m log m) か O(n log n) となり、O(m+n) を超えてしまう。)
2. 頂点同士のペアで調べることができない (2重の for になって O(n^2) になるため。)

ソートできないと、配列中に同じ値が存在するかどうかを調べるのが線形時間でできるのかどうか解からない。(これが最大のネックになっていると思う)

論文には、multi edge の探索を内部的につかって、全体としてO(m+n) になる、と書いてあるので、これはO(m+n)になるはずなのであるが、さっぱり解からない。



今日は6時間ぐらいかけて、論文の2ページぐらい読み進んだ。
この論文、はたして読み終えることができるんだろうか?

読むのが遅くなっている理由として、必要な事項が足りないことが多すぎる、などがある。
たとえば、「頂点 v について成り立つ」とあるのに、「特定の条件を満たす v について成り立つ」という「特定の条件」が暗黙のうちにかかれていて、これを推測しないといけない。
あと、文章の内容とexampleの図があっていないので、それもどちらが正しいのかを推測しないといけない。

とりあえず、こつこつと読み進めよう。

今日の作業内容: 論文読み 6h
今日のBGM: マクロスF OST [1-2], FF12 OST [1-2]
今日のランチ: いろは 豚汁定食
明日の予測作業時間: 2h

7 件のコメント:

  1. グラフの点数/枝数は整数なので O(m) (bucket-sort) でソート可能です。僕の最短路ソルバでも bucket-sort を使っています。

    返信削除
  2. Yes, that's right!!

    帰りの電車と夕飯の準備と夕飯を食べているときに考えていたところ、かぼちゃを食べているときに

    バケツソートの2段掛けか!!

    と気がつきました。
    で、記事を修正しようと思ってたら、すでに先を越されてみました。
    やはり、「もちはもち屋」ですね。

    返信削除
  3. グラフ表現に forward-star を使うと始点順に並びますので、都合が良さそうですね。「もちはもち屋」のもち屋になりたいです。

    返信削除
  4. 訂正です。点数で sort するので、O(n) でしたね。
    (終点 sort) + (始点 sort) + (multi edge の check) で、O(n) + O(n) + O(m) = O(n+m) かと。

    返信削除
  5. えっと、たぶん終点ソートは O(m) かかるんじゃないかと。(全ての枝をチェックしないといけないので。)

    たぶん、O(n) は、バケツソートのバケツの初期化にかかる時間じゃないかと、推測しました。

    返信削除
  6. あ、間違っているかもしれないので、もし間違いに気がついたら、


    そっと


    訂正しておいてください。

    返信削除
  7. O(n+m) 中、multi edge の check は O(m) なので、よく考えずに bucket-sort は O(n) かと早合点してしまいました。おっしゃる通り O(m) ですね。O(n) は必要なバケット数です。となると、O(m) + O(m) + O(m) = O(m) で済むのではないでしょうか。。

    返信削除