【问题标题】:optimising intervals in a histogram优化直方图中的间隔
【发布时间】:2017-09-22 17:33:09
【问题描述】:

我是一个完全的新手(甚至不是计算机科学家),但自从我开始学习 Python 和一般编程以来,我想解决这个问题,看看用编程解决这类事情有多难。 从数学的角度来看,我也不知道这有多难回答,是几行代码简单还是需要完成一些优化工作?

假设我有一组从 1 到 200 的 35 个“值”。

我想将它们分成 5 组(“箱”),但我希望每个组(箱)相同数量的“值”。所以图表将像 5 个相同高度的条形。所以不确定它是否仍然被称为直方图。无论如何,唯一的问题是如何计算(优化?)那些间隔/过渡点。 / bin 宽度。很难编码还是根本不编码?

我只想说,如果只有 2 个组(箱),“过渡点”就是中位数。 如果有 4 个组,则为两组中的每一个计算另外两个中位数。 但我不知道是否有 5 个组(箱)以及是否有比计算中位数更好的编码方法。

提前感谢您的回复。

【问题讨论】:

    标签: optimization histogram


    【解决方案1】:

    我确信对于这个问题可能有比我即将提出的算法更有效的算法,但我觉得对于从 1 到 200 的一组 35 个值,这个问题不需要最多高效和优化的算法。一个简单易懂的方法就足够了。

    首先,在您的列表中均匀放置 4 个分隔符(这可以由单独列表中的 4 个值表示,以指示它们的索引)。然后,设置一个变量,altered 为 true,然后进入你的主循环:当改变时,做逻辑。立即设置更改为 false(这将允许我们在达到最佳解决方案后终止)。现在,仍然在 while 循环中,有一个从 0 迭代到 3(包括)的 for 循环,比较每个分隔线两侧的高度。向任一方向移动分隔线会减小它们的差异,继续向该方向移动它,并将 altered 设置为 true。现在让 for 循环对所有分隔符重复,最外面的 while 循环冲洗并重复循环,直到找不到更好的解决方案。

    编辑:这是一些尝试执行我上面解释的python代码。您可能需要调整 compare_bins 函数以满足您对最平衡直方图的标准(我将其定义为所有相邻邻居之间差异的最小总和)。

    list_values = [10, 27, 59, 177, 185, 195, 54, 151, 15, 26, 105, 22, 32, 179, 92, 1, 115, 129, 152, 124, 100, 134, 175, 1, 149, 178, 28, 51, 90, 69, 128, 96, 8, 18, 38]
    edges = [0, 7, 14, 21, 28, len(list_values)] # 0 and 34 are the ends of the list, and we do not change
    
    def compare_bins():  # scores the difference in the histogram heights
        global list_values, edges
        score = 0
        for bin_id in range(4):
            idx = bin_id + 1
            prev_bin = sum(list_values[edges[idx-1]:edges[idx]])
            next_bin = sum(list_values[edges[idx]:edges[idx+1]])
            score += abs(prev_bin - next_bin)
            print(abs(prev_bin - next_bin))
        return score
    
    altered = True
    while altered:
        altered = False
        for i in range(4):
            old_diff = compare_bins()
            idx = i + 1
            edges[idx] -= 1
            while compare_bins() < old_diff:  # try moving the dividers left
                edges[idx] -= 1
                altered = True
            edges[idx] += 2
            while compare_bins() < old_diff:  # try moving the dividers right
                edges[idx] += 1
                altered = True
            edges[idx] -= 1
    

    【讨论】:

    • 谢谢你,我会保留你的帖子,当我知道如何编码时使用它;-) 我正处于学习基础(理论)并研究代码和操作的阶段它有不同的结果。我自己还不能写,但我会试着弄清楚你在说什么。如果那是几行,也许有人可以写?干杯!
    • 您打算使用什么语言?如果需要,如果它是我熟悉的语言,或者如果您不介意伪代码,我可以尝试编写代码的快速模型。
    • 我已将代码添加到我的答案中。请注意,您可能需要根据需要调整 compare_bins() 评分函数。我自己对其进行了简短的测试,它似乎可以工作,但我可能忽略了一些局部最大值的情况。无论哪种方式,我希望这可以解决您的问题。
    • 太棒了...非常感谢...我会研究它并尝试运行它:-)
    • 我以为你说你想要 5 个条形,而不是依赖于值的“n”个条形?我可能只是误解了你原来的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 2015-06-23
    • 2015-11-09
    • 1970-01-01
    • 2015-11-09
    相关资源
    最近更新 更多