You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DSA图论:如何编程将n个点划分为N组使组内点尽可能接近?

一维点最优分组的展示方案

首先明确核心前提:因为所有点都在x轴上,最优分组必然是连续的区间(非连续分组的误差一定大于调整为连续后的误差),所以先对所有点按从小到大排序是关键步骤。

步骤1:基于动态规划的最优分组回溯

假设你已经实现了计算区间[start, end](点的索引,0/1起始均可)组内误差的函数calculate_error(start, end),接下来通过动态规划找到最优分组后,回溯出具体的分组边界:

动态规划定义

  • 设sorted_points为排序后的点列表,长度为n
  • 定义dp[i][k]:前i个点分成k组的最小总误差
  • 初始化:dp[i][1] = calculate_error(0, i-1)(前i个点分成1组的误差)
  • 状态转移:
    dp[i][k] = min(dp[j][k-1] + calculate_error(j, i-1)) ,其中 j 从 k-1 到 i-1
    
    (分成k组的话,前j个点至少要分成k-1组,所以j≥k-1)

回溯分组边界

从dp[n][N]倒推:

  1. 初始化current = n,groups = []
  2. 从k = N downto 1:
    • 遍历j从k-1到current-1,找到使得dp[current][k] == dp[j][k-1] + calculate_error(j, current-1)的j值
    • 将sorted_points[j:current]加入groups
    • 令current = j
  3. 反转groups得到从左到右的分组顺序

步骤2:分组展示方案

文本展示(直接明了)

把每个组的点、组内均值、组内误差一起输出,示例代码:

# 假设回溯得到的groups是[[1.1, 2.2, 3.1], [5.3, 6.2, 7.0], [9.5, 10.1]]
for idx, group in enumerate(groups, 1):
    group_mean = sum(group) / len(group)
    # 用你实现的函数计算当前组误差,这里假设函数接受起始/结束索引
    start_idx = sum(len(g) for g in groups[:idx-1])
    end_idx = start_idx + len(group) - 1
    group_err = calculate_error(start_idx, end_idx)
    print(f"Group {idx}:")
    print(f"  Points: {group}")
    print(f"  Mean: {group_mean:.2f}, Error: {group_err:.2f}")

输出效果:

Group 1:
  Points: [1.1, 2.2, 3.1]
  Mean: 2.13, Error: 0.85
Group 2:
  Points: [5.3, 6.2, 7.0]
  Mean: 6.17, Error: 0.61
Group 3:
  Points: [9.5, 10.1]
  Mean: 9.80, Error: 0.18

可视化展示(ASCII版,快速直观)

利用x轴刻度标记点和分组,示例代码:

sorted_points = sorted(your_point_list)
max_val = max(sorted_points)
min_val = min(sorted_points)
# 生成21个刻度点,覆盖所有数据范围
scale = [round(min_val + i*(max_val - min_val)/20, 1) for i in range(21)]

print("X-axis scale: " + " ".join([f"{s:>4}" for s in scale]))
print("              " + "----"*20)

for idx, group in enumerate(groups, 1):
    line = ["    "] * 21
    for point in group:
        # 找到点对应的刻度位置
        pos = min(range(21), key=lambda x: abs(scale[x] - point))
        line[pos] = f"G{idx} "
    print("              " + "".join(line))

输出效果:

X-axis scale:  1.1  1.5  1.9  2.3  2.7  3.1  3.5  3.9  4.3  4.7  5.1  5.5  5.9  6.3  6.7  7.1  7.5  7.9  8.3  8.7  9.1
              ----------------------------------------------------------------------------------------
              G1  G1        G1                                                                        
                                      G2        G2        G2                                        
                                                                                  G3        G3        

关键注意事项

  • 必须先对所有点排序,否则回溯得到的分组会混乱,不符合“接近程度”的分组逻辑
  • 如果n < N,直接每个点单独成组即可,无需计算
  • 动态规划的索引要和你的calculate_error函数的索引规则保持一致(0-based还是1-based)

内容的提问来源于stack exchange,提问作者Algoriphobia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:13:14