首页 > 解决方案 > 如何弥补一些任意数字之间的差距?

问题描述

我正在尝试设计一种算法来找到一些半随机数的最佳舍入数。就我而言,输入就像音乐理论中的音符持续时间。例如,如果输入是这样的:

109 102 212 196 99 802

那么输出将是这样的:

100 100 200 200 100 800

PS:实际上我想编写一个代码来将歌曲转换为乐谱。

标签: algorithmrounding

解决方案


实际上,我想编写一个代码来将歌唱曲目转换为乐谱。为此,我找到了相邻音符之间的间隔,然后我需要算法来四舍五入这些间隔。我已经做到了,我认为它运作良好。首先,我在“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 并尝试接近间隙值,然后它返回粗音符。

这是我提出的方案,如果您有更好的方案,请告诉我。


推荐阅读