ならば

音とかで遊んでいたログ

BAモデルの可聴化

Barabási-Albertモデル(BAモデル)は、複雑ネットワークの主要な性質のひとつである「次数分布のスケールフリー性」を持つグラフを生成するアルゴリズム

BAモデルの可視化はwonderflでやった
    


ChucKを使って可聴化もやったのでここに書く。その前にBAモデルの手順について簡単に。最初に適当なノード数からなる完全グラフを用意して、次のことを所望のノード数になるまで繰り返す。

  • 成長:一個のノードをグラフに追加する
  • 優先的選択:追加するノードからM本のエッジを既存のノードに張る。既存のノードは、その次数に比例した確率でM個独立に選択する


可聴化のデザイン。

  • 一回の成長ごとにM本のエッジを既存のノードに張るとき、M個の音を同時に鳴らす
  • エッジを張る先のノードの次数が大きいほど音高と音量も大きくする
  • 大きいグラフの生成過程の全体を概観するために一回の成長で鳴らす音の長さは極端に短くする

ChucKのプログラム。ノード間の接続情報は今回の可聴化には不要なので保持しない。

.05::second => dur T;
2 => int N0;
1000 => int N;
4 => int M;
int degAt[N];
int addTo[M];
Event e;
Gain g => dac;
1./(2*M) => g.gain;

init();
evolve();

fun void tone(int i, Event e) {
    Wurley w => g;
    while (e => now) {
        220 + 8*degAt[addTo[i]] => w.freq;
        Math.log(degAt[addTo[i]])/10 => w.noteOn;
    }
}

fun void init() {
    for (int i; i < N0; i++) {
        N0 - 1 => degAt[i];
    }
    for (int i; i < M; i++) {
        spork ~ tone(i, e);
    }
}

fun void evolve() {
    (N0-1)*N0 => int degs;
    int addEnd;
    for (N0 => int i; i < N; i++) {
        for (int j; j < M; j++) {
            Std.rand2(1, degs) => addEnd;
            for (int k; k < i; k++) {
                degAt[k] -=> addEnd;
                if (addEnd <= 0) {
                    k => addTo[j];
                    break;
                }
            }
        }
        for (int j; j < M; j++) {
            1 +=> degAt[addTo[j]];
        }
        M => degAt[i];
        2*M +=> degs;
        e.broadcast();
        T => now;
    }
    second => now;
}

録音したもの。
Download


出力される音の特徴。

  • 低い音のクラウド*1の中で少数の高い音がすぐに目立ってくる
  • 少数の高い音も結構頻繁に鳴る
  • 低い音のクラウドはほぼそのままで少数の高い音はますます高くなっていく

可聴化のデザインは簡単だけどBAモデルの特徴は良く出ていると思う。

*1:書いておいてなんだが、こんな言葉の使い方は多分ない