コンピュータサイエンスにおいて、二分決定図(BDD)または分岐プログラムは、ブール関数を表すために使用されるデータ構造です。より抽象的なレベルでは、BDDは集合または関係の圧縮表現と考えることができます。他の圧縮表現とは異なり、操作は圧縮表現に対して直接実行されます。つまり、解凍は不要です。
類似のデータ構造としては、否定標準形(NNF)、ジェガルキン多項式、命題有向非巡回グラフ(PDAG)などがある。
ブール関数は、複数の(決定)ノードと2つの終端ノードからなる、ルート付き有向非巡回グラフとして表現できます。2つの終端ノードには、0(偽)と1(真)のラベルが付けられています。各(決定)ノードは、ブール変数によってラベル付けされていますそして、low child と high child という 2 つの子ノードを持ちます。ノードからのエッジは、低い(または高い)子に、変数にそれぞれ FALSE(または TRUE)の値を割り当てることを表します。このようなBDDは、ルートからのすべてのパスで異なる変数が同じ順序で現れる場合、「順序付き」と呼ばれます。BDDは、次の2つのルールがグラフに適用されている場合、「縮小」されていると言われます。
一般的に、BDDという用語は、ほぼ常に縮小順序付き二分決定図(文献ではROBDDと呼ばれ、順序付けと縮小の側面を強調する必要がある場合に使用されます) を指します。ROBDD の利点は、特定の関数と変数の順序に対して正準 (同型を除いて一意) であることです。 [ 1 ]この特性により、関数の等価性チェックや、関数テクノロジーマッピングなどの他の操作に役立ちます。
ルートノードから1端子へのパスは、(部分的な場合もある)変数割り当てを表し、その割り当てに対応するブール関数は真となります。パスがノードから下位(または上位)の子ノードに降りていくと、そのノードの変数には0(または1)が割り当てられます。
下の左図は、関数を表す二分決定木(縮約ルールは適用されていない)と真理値表を示しています。左側のツリーでは、関数の値は、グラフを下って終端までパスをたどることで、特定の変数割り当てに対して決定できます。下の図では、点線は下位の子へのエッジを表し、実線は上位の子へのエッジを表します。したがって、を見つけるにはx 1から始め、点線に沿って x 2まで進み(x 1には0 が割り当てられているため)、次に実線を 2 つ下ります (x 2と x 3にはそれぞれ 1 が割り当てられているため)。これにより、ターミナル 1 に到達します。これは、次の値です。。
左図の二分決定木は、 2つの削減ルールに従って最大限に削減することで、二分決定図に変換できます。結果として得られる二分決定図を右図に示します。
このブール関数を記述する別の表記法は次のとおりです。。

ROBDD は、補数リンクとも呼ばれる補数エッジを使用して、さらにコンパクトに表現できます。[ 2 ] [ 3 ]結果として得られる BDD は、型付き BDD [ 4 ]または符号付き BDDと呼ばれることもあります。補数エッジは、下位エッジを補数であるか否かで注釈付けすることによって形成されます。エッジが補数である場合、それはエッジが指すノードに対応するブール関数の否定 (そのノードをルートとする BDD によって表されるブール関数) を参照します。結果として得られる BDD 表現が標準形式であることを保証するために、上位エッジは補数化されません。この表現では、以下で説明する理由により、BDD は単一のリーフノードを持ちます。
BDDを表現する際に補数エッジを使用する2つの利点は次のとおりです。
しかし、クヌース[ 5 ]はこれとは異なる主張をしている。
このようなリンクは主要なBDDパッケージすべてで使用されていますが、コンピュータプログラムが非常に複雑になるため、推奨は難しいです。メモリ節約効果は通常ごくわずかで、最大でも2倍程度にしかなりません。さらに、著者の実験では実行時間の改善もほとんど見られませんでした。
この表現における BDD への参照は、BDD のルートを指す (場合によっては補数化された)「エッジ」です。これは、補数化されたエッジを使用しない表現における BDD への参照 (BDD のルート ノード) とは対照的です。この表現における参照がエッジである必要がある理由は、各ブール関数について、関数とその否定が、BDD のルートへのエッジと、同じ BDD のルートへの補数化されたエッジによって表されるためです。これが、否定が定数時間で実行される理由です。また、単一のリーフ ノードで十分な理由も説明できます。FALSE はリーフ ノードを指す補数化されたエッジで表され、TRUE はリーフ ノードを指す通常のエッジ (つまり、補数化されていない) で表されます。
例えば、ブール関数が、補数エッジを使用して表現された BDD で表されているとします。変数に (ブール) 値が割り当てられたときのブール関数の値を求めるには、BDD のルートを指す参照エッジから始め、与えられた変数の値によって定義されるパス (ノードをラベル付けする変数が FALSE の場合は低いエッジをたどり、ノードをラベル付けする変数が TRUE の場合は高いエッジをたどります) をリーフノードに到達するまでたどります。このパスをたどる際に、通過した補数エッジの数を数えます。リーフノードに到達したときに奇数個の補数エッジを通過した場合、与えられた変数割り当てに対するブール関数の値は FALSE になります。そうでない場合 (補数エッジを通過した数が偶数の場合)、与えられた変数割り当てに対するブール関数の値は TRUE になります。
この表現における BDD の例図を右側に示します。これは、上の図に示されているのと同じブール式を表しています。低いエッジは破線、高いエッジは実線で表示され、補完エッジは始点に円で示されます。@記号が付いたノードはBDDへの参照を表し、つまり参照エッジはこのノードから始まるエッジです。
データ構造が作成された基本的なアイデアは、シャノン展開です。スイッチング関数は、1 つの変数を割り当てることによって 2 つのサブ関数 (コファクター) に分割されます ( if-then-else の標準形を参照)。このようなサブ関数をサブツリーとみなすと、バイナリ決定木で表現できます。バイナリ決定図 (BDD) は CY Lee [ 6 ]によって導入され、Sheldon B. Akers [ 7 ]と Raymond T. Boute [ 8 ] によってさらに研究され、知られるようになりました。これらの著者とは独立して、Yu. V. Mamrukov は、速度に依存しない回路の分析用の CAD で、「標準ブラケット形式」という名前の BDD を実現しました [ 9 ]。データ構造に基づく効率的なアルゴリズムの可能性は、カーネギーメロン大学のRandal Bryantによって調査されました。彼の主な拡張は、固定変数順序 (標準表現用) と共有サブグラフ (圧縮用) を使用することでした。これら 2 つの概念を適用すると、集合と関係を表現するための効率的なデータ構造とアルゴリズムが得られます。[ 10 ] [ 11 ]共有を複数の BDD に拡張することで、つまり 1 つのサブグラフが複数の BDD で使用されることで、共有縮小順序付き二分決定図というデータ構造が定義されます。[ 2 ]現在では、BDD という概念は、一般的にその特定のデータ構造を指すために使用されています。
ドナルド・クヌースは、ビデオ講義「二分決定図(BDD)で楽しむ」の中で、BDDを「過去25年間に登場した数少ない真に基本的なデータ構造の1つ」と呼び、ブライアントの1986年の論文がしばらくの間、コンピュータサイエンスで最も引用された論文の1つであったことに言及している。[ 12 ]
アドナン・ダーウィッシュとその共同研究者たちは、BDD(ブール演算データ)がブール関数の正規形の一つであり、それぞれ異なる要件の組み合わせによって生成されることを示した。ダーウィッシュが特定したもう一つの重要な正規形は、分解可能な否定正規形(DNNF)である。
BDDは、 CADソフトウェアで回路合成(論理合成)や形式検証、ネットワーク検証に広く使用されています。BDDには、フォールトツリー解析、ベイズ推論、製品構成、プライベート情報検索など、あまり知られていないアプリケーションがいくつかあります。[ 13 ] [ 14 ]
任意の BDD (縮小や順序付けされていない場合でも) は、各ノードを 2 対 1マルチプレクサに置き換えることでハードウェアに直接実装できます。各マルチプレクサは、 FPGA内の 4-LUT で直接実装できます。論理ゲートの任意のネットワークから BDD に変換するのは、( AND インバータグラフとは異なり)それほど簡単ではありません。
BDDは効率的なDatalogインタープリタに適用されている。[ 15 ]
BDDのサイズは、表現される関数と変数の順序によって決まります。ブール関数が存在します。変数の順序によっては、ノード数が最良の場合は線形( nに関して)、最悪の場合は指数関数的になるグラフが得られることになる(例:リップルキャリー加算器)。ブール関数を考えてみよう。 変数順序付けを使用するBDDには関数を表すノード。順序付けを使用するBDDは以下から構成される。ノード。
このデータ構造を実際に適用する際には、変数の順序に注意を払うことが極めて重要です。最適な変数の順序を見つける問題はNP困難です。[ 16 ]任意の定数c > 1に対して、最適なものより最大でc 倍大きいサイズのOBDDとなるような変数の順序を計算することは、NP困難です。[ 17 ]しかし、この問題に取り組むための効率的なヒューリスティックが存在します。[ 18 ]
変数の順序に関係なく、グラフのサイズが常に指数関数的になる関数が存在する。これは、例えば乗算関数に当てはまる。[ 1 ]実際、2つの積の中間ビットを計算する関数は、-ビット数には、より小さいOBDDがありません頂点。[ 19 ](乗算関数が多項式サイズのOBDDを持つ場合、整数因数分解がP/polyにあることを示すことになるが、これは真であるとは知られていない。[ 20 ])もう1つの悪名高い例は、指数サイズのBDDを持つ最も単純な関数と見なされている隠れ重みビット関数である。[ 21 ]
研究者たちは、BDDデータ構造の改良を提案しており、以下のような関連グラフがいくつか提案されている。
BDDに対する多くの論理演算は、多項式時間グラフ操作アルゴリズムによって実装できる。 [ 24 ]: 20
しかし、これらの操作を複数回繰り返すと、例えば一連の BDD の論理積や論理和を形成する場合、最悪の場合、指数関数的に大きな BDD が生成される可能性があります。これは、2 つの BDD に対する前述の操作のいずれかによって、BDD のサイズが BDD のサイズの積に比例する BDD が生成され、その結果、複数の BDD では操作回数に対してサイズが指数関数的に増加する可能性があるためです。変数の順序付けを改めて検討する必要があります。BDD の集合の一部に対して適切な順序付けであっても、操作の結果に対して適切な順序付けではない可能性があります。また、ブール関数の BDD を構築すると、NP 完全ブール充足可能性問題と co-NP 完全トートロジー問題が解決されるため、結果として得られる BDD が小さい場合でも、BDD の構築にはブール式のサイズに対して指数関数的な時間がかかる可能性があります。
縮小BDDの複数の変数に対する存在抽象化を計算することはNP完全である。[ 25 ]
ブール式の充足可能な割り当ての数を数えるモデルカウントは、BDD(ブール表示展開)の場合は多項式時間で実行できます。しかし、一般的な命題論理式の場合、この問題は♯P完全であり、既知の最良のアルゴリズムでも最悪の場合には指数時間が必要となります。