Каков был бы наиболее подходящий (естественно подходящий) способ представления различных правил аккордовой прогрессии (музыкальной) в структуре данных, чтобы каждый аккорд имел взвешенный набор вариантов, к которым он может прогрессировать?
Эта структура данных была бы реализована в процедурной программе генерации музыки таким образом, чтобы вы могли написать код: (псевдокод, не требующий знания языка)
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, но может и нарушить правила, перейдя в любой другой аккорд. Нарушение правил будет происходить нечасто.
Я думал о какой-то структуре данных типа связанного списка/дерева, но это вряд ли будет похоже на любой тип дерева или списка, который я когда-либо использовал - кроме того, я не могу придумать, как реализовать взвешивание:
Другая мысль была использовать JSON или что-то подобное, но это, кажется, быстро становится избыточным:
{
"I":{
"100%":{
"I",
"ii",
"iii",
"IV",
"V",
"vi",
"vii"
}
},
"ii":{
"80%":{
"V",
"vii"
},
"20%":{
"i",
"ii",
"iii",
"IV",
"vi"
}
},
// ...
}
Примечание: мне удобно реализовать это на нескольких языках, и на данный момент меня не интересует реализация на конкретном языке, а интересует архитектура структуры данных, не зависящая от языка.