してみましょう DAGなります。一部のノードは「不良」であり、その他は「良好」であることがわかっています。悪いノードの子孫は悪いが、良いノードの祖先は良い。また、不良ノードには一意の最小要素があり、タイプ「Are you good or bad?」のクエリでクエリするノードをできるだけ少なくしたいと考えています。
この問題は、一般的なバージョン管理システムであるGitでコマンドによって解決されます。git-bisect
これは、プログラマーがバグが導入された最初のコミットを見つけるのに役立ちます。
最初に、Gitによって実装されたアルゴリズムは、1つの不良コミットと1つ以上の良好なコミットを知っていると想定しています。実行の各ステップで、アルゴリズムは次のステップ(ここから取得)を使用してコミットを見つけます。
次のコミットのみを保持します。
a)不良コミットの祖先である(不良コミット自体を含む)、および
b)グッドコミットの祖先ではない(グッドコミットを除く)。
結果のグラフの適切な端から始めて、各コミットに、その祖先の数にプラス1を関連付けます。
各コミットに関連付ける、ここではステップ2でのコミットに関連付けられた値、はグラフ内のコミットの総数(ステップ1で削減された後)。
最良の二分ポイントは、関連付けられた数が最大のコミットです。
このアルゴリズムは基本的に、「最悪の場合」を実現するコミットを見つけています。実際、は、最良の場合の次の反復でのDAG内のノードの数なので、が最悪のケースです。
不思議なんだけど:
- 「最悪のケース」、つまりを達成するノードを選択した場合、違いはありますか?
- このアルゴリズムは最悪の場合最適ですか?
編集:私はこの問題に限界があることに気づきました。と呼ばれる親を持つ単一のノードによって形成されるDAGを考えます。が不良であることがわかっている場合は、各親をチェックして、それらが最小の不良ノードであるかどうかを確認します。
編集2:以前は実際には境界です。ここで、はposetの幅です。この問題の代替アルゴリズムは、クエリを使用するcstheory.stackexchangeのこの回答に記載されています。