我确信对于这个问题可能有比我即将提出的算法更有效的算法,但我觉得对于从 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