优化问题:矩形域内六边形拟合,求解最优Ls与整数n/m以最小化边界误差
正六边形排布参数优化解决方案
核心思路
你的问题属于混合整数优化问题,优化变量包含连续值Ls(正六边形边长,限定在[ls_min, ls_max]区间)以及正整数n(直行方向单元数)、m(锯齿方向单元数),约束是所有六边形完全落在L×B的域内,优化目标是最小化两个方向的边界误差总和。
因为n和m的取值范围非常小,优先推荐暴力遍历法,实现简单、无局部最优问题,运行效率完全满足需求:
- 先确定
n和m的最大可能取值:以Ls的下限ls_min计算,最多能放的单元数就是遍历的上限 - 对每一组
(n,m)组合,推导Ls的可行区间,在可行区间内直接取Ls的最大值即可得到该组(n,m)下的最小总误差(误差本质是域的剩余间隙,Ls越大剩余间隙越小) - 遍历所有可行的
(n,m)组合,保留总误差最小的一组参数即可
实现代码
import numpy as np # 固定参数定义 L = 500 B = 200 # Ls的限定区间,可按需修改 ls_min = 8 ls_max = 12 # 计算n和m的最大遍历上限,避免无效循环 max_n = int(np.floor(L / (1.5 * ls_min))) max_m = int(np.floor(B / ( (np.sqrt(3)/2) * (4/3) * ls_min ))) # 初始化最优参数 best_total_error = np.inf best_Ls = 0 best_n = 0 best_m = 0 best_errorL = 0 best_errorB = 0 # 遍历所有可能的n、m组合 for n in range(1, max_n + 1): for m in range(1, max_m + 1): # 计算当前n、m下Ls的上限约束 ls_upper_length = L / (n + 0.5) ls_upper_width = B / ( (np.sqrt(3)/2) * (m + 1/3) ) ls_upper = min(ls_max, ls_upper_length, ls_upper_width) # 无可行Ls,跳过当前组合 if ls_upper < ls_min: continue # 当前组合下最优Ls取可行区间上限 current_Ls = ls_upper current_errorL = L - current_Ls * (n + 0.5) current_errorB = B - current_Ls * (np.sqrt(3)/2) * (m + 1/3) # 可根据需求调整误差计算逻辑,比如加权、平方和等 current_total_error = current_errorL + current_errorB # 更新最优参数 if current_total_error < best_total_error: best_total_error = current_total_error best_Ls = current_Ls best_n = n best_m = m best_errorL = current_errorL best_errorB = current_errorB # 打印结果 print(f"最优Ls: {best_Ls:.2f}") print(f"直行方向单元数n: {best_n}") print(f"锯齿方向单元数m: {best_m}") print(f"长度方向误差errorL: {best_errorL:.2f}") print(f"宽度方向误差errorB: {best_errorB:.2f}") print(f"总误差: {best_total_error:.2f}")
可选优化方案
如果后续你需要扩展到更大的参数范围,不想用暴力遍历,可以使用scipy.optimize.differential_evolution差分进化算法,直接指定变量类型(Ls为连续变量,n、m为整数变量),传入约束即可求解,不需要手动推导遍历范围。
内容的提问来源于stack exchange,提问作者dan
相关产品推荐
相关产品推荐

