algorithm - 如何弥补一些任意数字之间的差距?
问题描述
我正在尝试设计一种算法来找到一些半随机数的最佳舍入数。就我而言,输入就像音乐理论中的音符持续时间。例如,如果输入是这样的:
109 102 212 196 99 802
那么输出将是这样的:
100 100 200 200 100 800
PS:实际上我想编写一个代码来将歌曲转换为乐谱。
解决方案
实际上,我想编写一个代码来将歌唱曲目转换为乐谱。为此,我找到了相邻音符之间的间隔,然后我需要算法来四舍五入这些间隔。我已经做到了,我认为它运作良好。首先,我在“102 103 402 409 390 398 100 200 408”中找到了主要差距的值,主要差距接近400(平均值为402 409 390 398 408),然后我将其持续时间设为1并进行比较另一个与它。对于 102 持续时间将是 0.25 等等。
编辑:首先我使用了一些python库来处理.mp3文件并找到频率变化的时刻及其相应的持续时间(以毫秒为单位)。由于这些时间不准确,我需要四舍五入,以便为它们分配一个注释符号。
def roundOff(diffs):
global major_element, ref_offset, divide_flag, measured_time, measured_note
major_element = findMajor(diffs)
for element in diffs:
divide_flag = False
measured_time = 0
measured_note = 0
note_duration.append(noteFinder(element, ref_offset))
return note_duration
上述函数将间隙作为输入并返回其相应的音符时长。我发现主要差距如下:
def findMajor(diffs):
diffs_copy = diffs.copy()
diffs_copy.sort()
this = 0
for element in diffs_copy:
if isNear(element, this):
temp_this = (this*elements_in_gap[this] + element)/(elements_in_gap[this] + 1)
elements_in_gap[this] += 1
elements_in_gap[temp_this] = elements_in_gap.pop(this)
this = temp_this
else:
this = element
elements_in_gap[this] = 1
return max(elements_in_gap, key = element_in_gap.get)
首先,它对间隙列表进行排序,并将'this'作为我们要检查其他间隙的代表值(初始为0),在每一步中,它检查新间隙是否靠近'this'然后修改' this' 并增加 'this' 集合中的间隙数,但如果它不在附近,请将 'this' 更改为新元素,并将新 'this' (: |) 的初始数量更改为 1 并执行相同操作。最后,返回具有最大价值的键作为主要差距。
isNear 函数是这样的:
def isNear(a, b):
if a < b+b*tolerance and a > b-b*tolerance:
return True
return False
在这种情况下,将容差设置为 0.1 是合适的。noteFinder 查找关于主要间隙的每个间隙的注释为 1 (ref_offset)。
def noteFinder(diff_time, offset):
global measured_time, measured_note, divide_flag, major_element
if isNear(diff_time, measured_time):
return measured_note
else:
if not divide_flag:
if diff_time > measured_time:
measured_time += offset*major_element
measured_note += offset
return noteFinder(diff_time, offset)
else:
offset /= 2
measured_time -= offset*major_element
measured_note -= offset
divide_flag = True
return noteFinder(diff_time, offset)
else:
offset /= 2
if diff_time > measured_time:
measured_time += offset*major_element
measured_note += offset
return noteFinder(diff_time, offset)
else:
measured_time -= offset*major_element
measured_note -= offset
return noteFinder(diff_time, offset)
它在每一步中将偏移量添加到测量音符并将偏移量*主要间隙值添加到测量时间(首先,如上所述,偏移量为 1)直到其间隙值低于测量时间,然后它将打开 divid_flag 进行除法在每一步中偏移 2 并尝试接近间隙值,然后它返回粗音符。
这是我提出的方案,如果您有更好的方案,请告诉我。
推荐阅读
- android - 升级到 Android SDK 28 时出错
- botframework - 如何区分 MS Bot Framework V3 中 Adaptive Card Submit Action 和 User type Text 发送的 Activity?
- python - 熊猫数据框替换特定位置的字符,而不更改其他位置的相似字符
- c# - Xamarin 表单“尝试 JIT 编译方法”“_Decimal_object_object_Nullable`1
" EntityFramework SQL Lite 出错 - wordpress - 获取活动日历中活动的开始日期
- ionic-framework - 使用 Ionic3 调用函数时出现运行时错误
- javascript - 向 Google Maps API 发出 GET 请求返回错误请求 400 错误 - javascript
- python - 分配 mx 时显示错误的代码。要排队的数据包数
- reactjs - 如何在 CRA v2 中将代理值从 package.json 移动到 setupProxy.js?
- java - Unable to decode Custom object at Avro Consumer end in Kafka