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

如何实现针对不同线径的线束直径计算算法?

线束直径计算的数值解决方案与可视化实现

核心思路

这类问题本质是**圆排列(Circle Packing)**问题:将多个给定半径的圆放入最小的外接圆中,对应线束的最小直径。以下是可落地的数值实现方案,附带可视化代码。

数值解决方案

算法步骤

  1. 预处理:将导线外径转换为半径,按半径从大到小排序——优先放置大圆能显著缩小最终外接圆的尺寸。
  2. 迭代放置:从最大的圆开始(放在原点),依次为剩余每个圆寻找合适的放置位置:
    • 尝试在已放置圆的外部相切位置生成候选点
    • 筛选出不与任何已放置圆重叠的候选点
    • 选择能让当前整体外接圆最小的位置作为最终放置点
  3. 结果计算:遍历所有已放置圆,找到圆心到原点的距离加上半径的最大值,乘以2即为线束的最小直径。

实现代码

import math
import random

def calculate_min_harness_diameter(outer_diameters):
    # 转换为半径并降序排序
    radii = [d / 2 for d in outer_diameters]
    radii.sort(reverse=True)
    
    # 初始化:最大圆放在原点
    placed = [(0.0, 0.0, radii[0])]
    remaining = radii[1:]
    
    for r in remaining:
        best_pos = None
        best_enclosing_r = float('inf')
        
        # 遍历已放置圆,生成相切候选位置
        for (x_exist, y_exist, r_exist) in placed:
            # 随机角度生成相切点,避免陷入局部最优
            angle = random.uniform(0, 2 * math.pi)
            offset_x = (r_exist + r) * math.cos(angle)
            offset_y = (r_exist + r) * math.sin(angle)
            candidate_x = x_exist + offset_x
            candidate_y = y_exist + offset_y
            
            # 检查是否与其他圆重叠
            overlap = False
            for (x2, y2, r2) in placed:
                dist = math.hypot(candidate_x - x2, candidate_y - y2)
                if dist < r2 + r - 1e-6:  # 允许微小计算误差
                    overlap = True
                    break
            if not overlap:
                # 计算当前候选位置对应的外接圆半径
                current_enclosing = max(
                    math.hypot(x, y) + r_placed 
                    for (x, y, r_placed) in placed + [(candidate_x, candidate_y, r)]
                )
                if current_enclosing < best_enclosing_r:
                    best_enclosing_r = current_enclosing
                    best_pos = (candidate_x, candidate_y, r)
        
        # 若未找到合适位置,放在当前外接圆的外围
        if best_pos is None:
            current_max_r = max(math.hypot(x, y) + r_placed for (x, y, r_placed) in placed)
            angle = random.uniform(0, 2 * math.pi)
            best_pos = (current_max_r * math.cos(angle), current_max_r * math.sin(angle), r)
        
        placed.append(best_pos)
    
    # 计算最终线束直径
    max_enclosing_r = max(math.hypot(x, y) + r for (x, y, r) in placed)
    return max_enclosing_r * 2

可视化方案

基于Matplotlib实现线束布局的可视化,直观展示导线位置与外接圆范围:

import matplotlib.pyplot as plt

def visualize_harness(outer_diameters):
    radii = [d / 2 for d in outer_diameters]
    radii.sort(reverse=True)
    
    # 复用放置逻辑生成导线位置
    placed = [(0.0, 0.0, radii[0])]
    remaining = radii[1:]
    
    for r in remaining:
        best_pos = None
        best_enclosing_r = float('inf')
        for (x_exist, y_exist, r_exist) in placed:
            angle = random.uniform(0, 2 * math.pi)
            offset_x = (r_exist + r) * math.cos(angle)
            offset_y = (r_exist + r) * math.sin(angle)
            candidate_x = x_exist + offset_x
            candidate_y = y_exist + offset_y
            
            overlap = False
            for (x2, y2, r2) in placed:
                dist = math.hypot(candidate_x - x2, candidate_y - y2)
                if dist < r2 + r - 1e-6:
                    overlap = True
                    break
            if not overlap:
                current_enclosing = max(
                    math.hypot(x, y) + r_placed 
                    for (x, y, r_placed) in placed + [(candidate_x, candidate_y, r)]
                )
                if current_enclosing < best_enclosing_r:
                    best_enclosing_r = current_enclosing
                    best_pos = (candidate_x, candidate_y, r)
        if best_pos is None:
            current_max_r = max(math.hypot(x, y) + r_placed for (x, y, r_placed) in placed)
            angle = random.uniform(0, 2 * math.pi)
            best_pos = (current_max_r * math.cos(angle), current_max_r * math.sin(angle), r)
        placed.append(best_pos)
    
    # 绘制可视化图
    fig, ax = plt.subplots(figsize=(8, 8))
    # 绘制所有导线
    for (x, y, r) in placed:
        wire_circle = plt.Circle((x, y), r, fill=False, edgecolor='#1f77b4', linewidth=1.5)
        ax.add_patch(wire_circle)
    # 绘制线束外接圆
    max_enclosing_r = max(math.hypot(x, y) + r for (x, y, r) in placed)
    harness_circle = plt.Circle((0, 0), max_enclosing_r, fill=False, edgecolor='#ff4b5c', linestyle='--', linewidth=2)
    ax.add_patch(harness_circle)
    
    # 调整坐标轴
    ax.set_aspect('equal')
    ax.set_xlim(-max_enclosing_r * 1.1, max_enclosing_r * 1.1)
    ax.set_ylim(-max_enclosing_r * 1.1, max_enclosing_r * 1.1)
    plt.title('线束布局可视化', fontsize=14)
    plt.show()
    
    return max_enclosing_r * 2

# 示例调用
sample_diameters = [5, 3, 3, 2, 2, 2]
print(f"计算得到的最小线束直径: {calculate_min_harness_diameter(sample_diameters):.2f}")
visualize_harness(sample_diameters)

优化说明

  • 上述实现是启发式算法,能快速得到工程可用的结果;若需要全局最优解,可引入模拟退火、遗传算法等优化方法调整圆的位置。
  • 对于大规模导线列表,建议使用专业的圆排列库(如circle-packer)提升效率与精度。

内容的提问来源于stack exchange,提问作者N.TW12

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:47:40