用于存储和弦进行规则的数据结构?

时间:2011-09-30 16:39:23

标签: language-agnostic data-structures

在数据结构中表示各种和弦进程(音乐)规则的最合适(自然适合)的方式是什么,这样每个和弦都有一组可以进展的加权选项?

此数据结构将在程序音乐生成程序中以您可以编码的方式实现:(与语言无关的伪代码)

Chord[7] songArray;

Chord first = new Chord(I); //set the first chord's value

songArray[0] = first;

for (i=0; i<7; i++){
    Chord temp = songArray[i].next();   //select the following chord
    songArray[i+1] = temp;
}

注意:在古典型音乐中,给定键中的每个和弦可以按照以下规则自然地进入另一个和弦:

 ----------------------
| Chord | Leads to     |
|=======================
| I     | any          |
| ii    | V, vii       |
| iii   | IV, vi       |
| IV    | ii, V, vii   |
| V     | vi           |
| vi    | ii, ii, IV, V|
| vii   | I            |
 ----------------------

数据结构将各种进度存储为加权选项。例如,考虑任何给定主键中的IV和弦:IV可以自然地进展到ii,V或vii,但也可以打破进入任何其他和弦的规则。违反规则的情况很少发生。

enter image description here

我已经考虑了某种链表/树数据结构,但它几乎不像我曾经使用的任何类型的树或列表 - 另外,我无法弄清楚如何实现加权:

enter image description here

另一个想法是使用JSON或类似的东西,但它似乎很快就会变得多余:

{
    "I":{
        "100%":{
            "I",
            "ii",
            "iii",
            "IV",
            "V",
            "vi",
            "vii"
        }
    },
    "ii":{
        "80%":{
            "V",
            "vii"
        },
        "20%":{
            "i",
            "ii",
            "iii",
            "IV",
            "vi"
        }
    },
    // ...
}

注意:我很乐意用少数几种语言实现它,此时我并不关心特定的语言实现,而是与语言无关的数据结构体系结构。

3 个答案:

答案 0 :(得分:3)

Markov Chain可能非常适合此问题。

马尔可夫链是一个随机过程,其中向下一个状态的进展由当前状态决定。因此,对于表格中的给定间隔,您可以将权重应用于“Leads to”值,然后随机确定要进展的状态。

答案 1 :(得分:3)

我希望你的和弦少于100个,因此如果你使用32位表示概率系列(可能是极端矫枉过正)你最终得到一个100x100x4(40000)字节数组对于平面马尔可夫矩阵表示。根据矩阵的稀疏性(例如,如果你有50个和弦,但每个通常映射到2或3个和弦)的速度和不太重要的空间原因,你可能需要一个数组,其中每个最终的数组元素是(和弦ID,概率)。

在任何一种情况下,这里的关键点之一是你应该使用概率序列,而不是概率序列。也就是说,不是说“这个和弦有10%的几率,而且这个有10%的几率,而且这个有80%的几率”说“第一个和弦有10%的几率,前两个和弦有一个20%的几率,前三个和弦有100%的几率。“

原因如下:当您选择随机但加权的值时,您可以生成固定范围内的数字(对于无符号整数,0到0xFFFFFFFF),然后通过和弦而不是线性搜索执行二进制搜索。 (搜索具有最小概率系列值的元素,该值仍然大于或等于您生成的数字。)

另一方面,如果你的每个和弦只有几个和弦,由于环路更紧密,线性搜索可能比二分搜索更快,然后所有概率系列都可以让你计算出一个简单的运行概率值的总和。

如果你不需要最令人惊讶的惊人表现(我怀疑你没有 - 对于一台计算机而言,音乐中没有那么多的和弦)这部分代码,我老实说只需坚持马尔可夫矩阵的平面表示 - 易于理解,易于实现,合理的执行速度。

除了有趣之外,这种事情很适合考虑预测编码 - 数据压缩中的常用方法。您可以考虑使用基于n-gram的算法(例如PPM)来实现音乐生成中的高阶结构,而无需太多示例材料。多年来,它一直致力于数据压缩。

答案 2 :(得分:2)

听起来你想要某种形式的directed, weighted graph,其中节点是和弦,边缘是渐进选项,边缘权重是进展的可能性。