LoginSignup
2
0

More than 5 years have passed since last update.

CUDDの簡単な利用例: ランダムな論理関数の作成

Posted at

環境をインストールしてGraphviz経由の作図ができるようになったので、ランダムな論理関数を作ってみる。

考えた方法

  • 変数の数(BDDの高さ) $N$は固定
  • $2^N$ 通りの組み合わせを考える(= 0から1<<Nまで)
  • 個別の組み合わせ $i$ について、乱数を使って0/1を決定
  • 1の場合、組み合わせ $i$ を論理式 $f_i$ で表現
  • 全ての1の場合を足し合わせる

実装

#include <iostream>
#include <random>
#include <vector>
#include "cuddObj.hh"

using namespace std;

int main() {
  Cudd mgr;

  // 乱数生成機
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_int_distribution<int> bin(0, 1);

  // 桁数4 (= 変数の個数)
  const int N = 4;
  vector<BDD> X(N);
  for (int i = 0; i < N; i++)
    X[i] = mgr.bddVar(); // 変数Xiの作成

  BDD f = mgr.bddZero();
  for (int i = 0; i < (1 << N); i++) {
    int bj = bin(mt);
    if (bj == 1) {
      BDD termi = mgr.bddOne();
      for (int k = 0; k < N; k++)
        termi &= (i & (1 << k)) ? X[k] : !X[k];
      f |= termi; // fiを足し合わせる
    }
  }

  // dot dump
  const vector<ADD> vec = {f.Add()};
  auto fp = fopen("dot/random.dot", "w");
  const char* iname[4] = {"x1", "x2", "x3", "x4"};
  const char* oname[1] = {"F"};
  mgr.DumpDot(vec, iname, oname, fp);
  return 0;
}
  • 出力結果
    • 図から逆算すると、$x_1 \bar{x_2} \bar{x_3} \vee \bar{x_1} \bar{x_2} x_3 \vee \bar{x_1} \bar{x_2} \bar{x_3} \bar{x_4} $ なのかな

random.png

2
0
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
2
0