2024年华数杯全国大学生数学建模竞赛B题思路代码与可视化结果分析
2024年华数杯B题思路代码加模型建立与求解,爆肝力作,学习从速!!!!
针对VLSI电路单元的自动布局问题的研究
1 问题一模型建立与求解
1.1 数据预处理
由于本次题目给的是txt格式文件,不是很方便读取和处理,所以首先将txt文件转化为excel文件,转化结果导出为附件1.xlsx和附件2.xlsx,转化代码如下:
import pandas as pd
import re
# 读取txt文件内容
file_path = '附件1.txt'
data = []
with open(file_path, 'r', encoding='utf-8') as file:
lines = file.readlines()
for line in lines:
data.append(line.strip())
# 使用正则表达式定义数据行的模式
pattern = r'([^,]+),\(([^)]+)\),\(\((.*?)\)\),(\d+),(\d+)'
# 提取数据到DataFrame
rows = []
for line in data[1:]:
match = re.match(pattern, line)
if match:
group_name = match.group(1).strip()
circuit_units = match.group(2).strip()
coordinates = match.group(3).strip()
hpwl = int(match.group(4))
rsmt = int(match.group(5))
rows.append([group_name, circuit_units, coordinates, hpwl, rsmt])
# 构建DataFrame
df = pd.DataFrame(rows, columns=['组名称', '(电路单元名称:连线接口名称)', '(对应连线接口坐标)', 'HPWL', 'RSMT'])
# 保存为Excel文件
excel_file = 'output.xlsx'
df.to_excel(excel_file, index=False)
print(f"转换完成,结果保存在 {excel_file}")
1.2 问题一模型建立
在电路设计中,可以将各个接口或设备视为图中的节点。连接这些节点的电路线或导线可以看作是图中的边,每条边都有一个权重,通常是这条线的长度或者成本。
最小生成树是一个包含图中所有节点并且边的权重之和最小的树形连接。在电路设计中,如果将各个节点(接口或设备)用边连接起来,那么通过最小生成树算法可以得到一棵树,这棵树的所有边的权重之和是最小的。这个权重之和可以被视为布线的最短长度或者最低成本的估计。
布线优化:在电路板设计中,各个电子元件之间需要通过导线或电路板的布线连接。通过计算最小生成树,可以找到一种连接方式,使得总的导线长度最短,从而减少信号延迟、减小成本。
成本估算:每条电路线的布线成本可能与其长度成正比。通过最小生成树计算出的总长度可以估算整体的布线成本。
可靠性考虑:最小生成树也可以用于优化电路的可靠性,例如最小化单点故障对整体电路的影响。本次采用Prim算法来计算每组坐标点形成的最小生成树,坐标点间的长度采用欧几里得公式计算:
Prim算法是一种用于计算加权无向图的最小生成树的贪婪算法。它从一个单点出发,逐步扩展,每次选择与当前生成树相邻且权重最小的边,直到生成树覆盖了图中所有的节点。
选择任意一个节点作为起始点加入生成树(可以是任意节点,因为最终都会生成同一颗最小生成树)。
首先初始化一个空的生成树和一个集合,用于记录已经在生成树中的节点。算法步骤包括:
1. 选择最小边:从当前生成树连接到生成树外的节点中,选择一条权重最小的边加入生成树。
2. 更新集合:将这个新加入的节点加入到已经在生成树中的节点集合中。
3. 重复步骤:重复以上步骤,直到所有的节点都被加入到生成树中为止。
其实Prim算法就是一个典型的贪心算法。最小生成树的权重:设图 G=(V, E),其中 V 是节点集合,E 是边集合。生成的最小生成树的权重可以用以下公式表示:
其中,weight(u, v) 是边 (u, v) 的权重。
1.3 模型结果及分析
读取每行的坐标数据并计算最小生成树的边长之和,满足题目中的两个要求::(1)每组 估计线长与对应RSMT的差值尽可能小;(2)能应用于评估附件1中的总连接线长。
绘制出最小生成树结果与RSMT的误差曲线如下:
计算其中与RMST误差小于300的值视为合理误差,得到其中小于300值的比例为81.22,精度较高,所以可以利用最小生成树方法来估算总线长。选取两组数据分别绘制出HPWL与最小生成树方法示意图:
Group1:
Group75:
问题一部分代码:
import pandas as pd
import ast
import networkx as nx
# 读取Excel文件
file_path = '附件1.xlsx'
sheet_name = 'Sheet1' # 根据实际情况修改sheet名称
# 读取数据
df = pd.read_excel(file_path, sheet_name=sheet_name)
# 定义函数计算两点间的欧氏距离
def euclidean_distance(p1, p2):
return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5
# 处理接口坐标列
def process_coordinates(coord_str):
coords = ast.literal_eval(coord_str) # 将字符串转换为元组列表
return coords
# 计算每行数据的最小生成树边长之和
def calculate_mst_edge_sum(coords_list):
G = nx.Graph()
# 添加节点
for i, coord in enumerate(coords_list):
G.add_node(i, coord=coord)
# 添加边
for i in range(len(coords_list)):
for j in range(i + 1, len(coords_list)):
distance = euclidean_distance(coords_list[i], coords_list[j])
G.add_edge(i, j, weight=distance)
# 计算最小生成树
mst = nx.minimum_spanning_tree(G)
edge_sum = sum(mst[i][j]['weight'] for i, j in mst.edges())
return edge_sum
# 计算并存储最小生成树边长之和到新列
edge_sums = []
for index, row in df.iterrows():
coord_str = row['接口坐标']
coords_list = process_coordinates(coord_str)
mst_edge_sum = calculate_mst_edge_sum(coords_list)
edge_sums.append(mst_edge_sum)
2024华数杯ABC题思路、代码、成品论文持续更新中。。。。。。
以下传送门,首日优惠,咨询学习从速!!!!!!
以下传送门,首日优惠,咨询学习从速!!!!!!
以下传送门,首日优惠,咨询学习从速!!!!!!
更多推荐
所有评论(0)