通过加权概率从列表中选择项目

时间:2018-12-12 13:33:58

标签: python jython

我有以下列表:

60, 62, 63, 65, 66, 68, 69, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 87, 88

在以下情况下,我需要从列表中选择音高:

  1. 需要选择100个音高

  2. 首先需要从列表中选择一个随机音高,然后通过加权概率确定从列表中选择的以下音高。

我要完成的是,从列表(71)中随机选择第一个音高后,下一个音高将根据其与71的接近度由加权概率确定(69和73的概率最大)被选中,然后是68和74等)

假设将68选为跟随71的音高,然后根据68与68的接近程度,通过加权概率确定68之后的下一个音高(66和69的选择概率最高,其次是65和71等)

我主要关心的是,尽管程序运行时没有错误(也就是说,至少一条错误消息不会中断其执行),但我仍然不确定该程序是否按照我的预期方式运行。我之所以这样说是因为,即使我希望程序选择100个音符,它也始终会准确选择5050个音符。为什么是5050?

这是我的代码:

from music import *
from random import *

solo = Phrase()
solo.setTempo(100)

durations = []
pitches = []
pitchIndex = ()
numberOfNotesInSolo = 0
listOfAvailablePitches = [60, 62, 63, 65, 66, 68, 69, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 87, 88]

pitch = choice(listOfAvailablePitches)
pitchIndex = listOfAvailablePitches.index(pitch)

while numberOfNotesInSolo < 100:

   weightedProbabilitiesForPitches = [pitchIndex + 1] * 20 + [pitchIndex - 1] * 20 + [pitchIndex + 2] * 15 + [pitchIndex - 2] * 15 + [pitchIndex + 3] * 12 + [pitchIndex - 3] * 12 + [pitchIndex + 4] * 8 + [pitchIndex - 4] * 8 + [pitchIndex + 5] * 5 + [pitchIndex - 5] * 5 + [pitchIndex + 6] * 3 + [pitchIndex - 6] * 3        

   pitchIndex = choice(weightedProbabilitiesForPitches)         

   while pitchIndex > 18 or pitchIndex < 0:

      pitchIndex = choice(weightedProbabilitiesForPitches)

   pitch = listOfAvailablePitches[pitchIndex]
   weightedProbabilitiesForDurations = [SN] * 1 + [EN] * 1 + [DEN] * 1 + [QN] * 1 + [DQN] * 1

   duration = choice(weightedProbabilitiesForDurations)
   pitches.append(pitch)
   durations.append(duration)
   solo.addNoteList(pitches, durations)
   numberOfNotesInSolo = numberOfNotesInSolo + 1     

print solo

1 个答案:

答案 0 :(得分:0)

我认为您面临的问题是如何为音高列表生成权重列表。这是我的代码:

pitches =  [60, 62, 63, 65, 66, 68, 69, 71, 73, 74, 76, 77, 79, 80, 82, 83, 85, 87, 88]
num = len(pitches)
choice = random.randint(0, num-1)
below = choice
above = num-choice-1
weightbelow = list(range(num-1, num-1-below, -1))[::-1]
weightabove = list(range(num-1, num-1-above, -1))
weight = weightbelow + [num] + weightabove

例如,如果音高的choice11(即pitches[11]=77),则权重将变为:

[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 18, 17, 16, 15, 14, 13, 12]

然后,您可以像A weighted version of random.choice中的选择一样进行加权随机选择

上面的代码是创建一个由len(pitches)-1组成的整数的升序列表,然后是一个降序列表,根据您的选择,它们的长度都合适,然后将它们合并在一起。如果您需要除线性分布以外的其他分布,请对其进行一些转换。