0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CUDDの簡単な利用例: BDD構造の幅優先探索

Posted at

TL; DR

  • ランダムな論理関数を作成できるようになった
  • BDD/ZDD/ADDのノードを表しているC言語側の構造体__DdNode(のポインタ)__を利用して、BDD構造を走査したい
  • とりあえずqueueとstackを利用すれば幅優先・深さ優先探索ができる
  • 優先探索からやってみる。

前提

  • 実装済みのランダムな論理関数がBDDで返ってくる関数を__random_function__という名前で再利用
  • DdNode*からBDDを作る場合は以下の形で可能(効率が良い/悪いまでは気にしない)
Cudd mgr;
DdNode* n = (何らかの内部構造へのポインタ)
BDD b = BDD(mgr, n);
  • あるノードから0枝(点線)と1枝(実践)を辿った先のノードはそれぞれC言語側の関数__Cudd_E__と__Cudd_T__で取得できる

  • あるBDDの節点bについて、その深さは関数__NodeReadIndex__で、子供に存在する節点数を__nodeCount__で取得できる

幅優先探索の実装

  • 前提とqueueを利用して実装する
#include <iostream>
#include <random>
#include <vector>
#include <queue>
#include <stack>
#include "cuddObj.hh"
#include "myutil.hpp" // random_functionが入っている

using namespace std;

int main() {
  Cudd mgr;
  const int N = 4;
  vector<int> pos;
  BDD f = random_function(N, &pos, mgr);

  // dot dump
  const vector<ADD> vec = {f.Add()};
  const char* iname[4] = {"x1", "x2", "x3", "x4"};
  const char* oname[1] = {"F"};
  auto fp = fopen("dot/random.dot", "w");
  mgr.DumpDot(vec, iname, oname, fp);

  // BFS
  queue<DdNode*> q;
  q.push(f.getNode());
  while (!q.empty()) {
    DdNode* n = q.front(); q.pop();
    BDD b = BDD(mgr, n);
    std::string name = b.IsZero() ? "F" : (b.IsOne() ? "T" : iname[b.NodeReadIndex()]);
    cout << name << ":" << b.nodeCount() << "," << b.NodeReadIndex() << endl;

    // put left & right child only when n is an nternal nodes
    if (!b.IsZero() && !b.IsOne()) {
      DdNode* l = Cudd_E(n);
      DdNode* r = Cudd_T(n);
      q.push(l);
      q.push(r);
    }
  }
  return 0;
}

ランダム関数の例

random.png

出力の例

  • おそらく合っている気持ちになる
x1:6,0             # 0x3a:root(x1)は自分以下に節点を6つ持つ
x2:4,1             # 0x3aの0枝側: x2は自分以下に節点を4つ持つ(0x36)
x2:3,1             # 0x3aの1枝側: x2は自分以下に節点を3つ持つ(0x39)
x3:3,2             # 0x36の0枝側: x3は自分以下に節点を3つ持つ(0x35)
T:1,2147483647     # 0x36の1枝側: T(=1)
x4:2,3             # 0x39の0枝側: x4は自分以下に節点を2つ持つ(0x31)
T:1,2147483647     # 0x39の1枝側: T(=1)
x4:2,3             # 0x35の0枝側: x4(0x31)
F:1,2147483647     # 0x35の1枝側: F(=0)
F:1,2147483647     # 0x31の0枝側: F(=0)
T:1,2147483647     # 0x31の1枝側: T(=1)
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?