14.37 replace_if equal

本文介绍了一个使用C++标准模板库(STL)中replace_if函数的示例,展示了如何将vector容器中满足特定条件的元素替换为新值。通过自定义谓词函数equ,实现了对vector中值为3的元素进行替换。
#include <iostream>
#include <vector>
#include <algorithm>

class equ{
public:
    equ(int val) : value(val) {}
    bool operator()(int newval) {
        return newval == value;
    }
private:
    int value;
};

int main() {
    std::vector<int> v{1,2,3,4,5};
    equ a(3);
    std::replace_if(v.begin(), v.end(), a, 100);
    // or std::replace_if(v.begin(), v.end(), equ(3), 100);
    for (const auto &i:v) {
        std::cout << i << std::endl;
    }
}
import tkinter as tk import math from tkinter import messagebox class Calculator: def __init__(self, root): self.root = root self.root.title("复杂计算器") self.root.geometry("400x400") self.root.resizable(False, False) self.current_interface = "simple" self.expression = "" self.last_result = "" self.create_widgets() self.setup_keyboard_bindings() # 设置键盘绑定 def create_widgets(self): # 创建菜单栏 self.menu_bar = tk.Menu(self.root) self.root.config(menu=self.menu_bar) self.interface_menu = tk.Menu(self.menu_bar, tearoff=0) self.interface_menu.add_command(label="标准计算器", command=self.show_simple_interface) self.interface_menu.add_command(label="科学计算器", command=self.show_complex_interface) self.menu_bar.add_cascade(label="模式", menu=self.interface_menu) # 创建简单界面 self.simple_frame = tk.Frame(self.root) self.simple_frame.pack(fill="both", expand=True) self.simple_entry = tk.Entry(self.simple_frame, font=("Arial", 24), justify="right") self.simple_entry.pack(fill="x", padx=10, pady=10) self.simple_buttons_frame = tk.Frame(self.simple_frame) self.simple_buttons_frame.pack(fill="both", expand=True) self.create_simple_buttons() # 创建复杂界面 self.complex_frame = tk.Frame(self.root) self.complex_frame.pack(fill="both", expand=True) self.complex_entry = tk.Entry(self.complex_frame, font=("Arial", 20), bd=5, relief="ridge", justify="right", state="readonly") self.complex_entry.pack(fill="x", padx=10, pady=10) self.history_frame = tk.Frame(self.complex_frame) self.history_frame.pack(fill="x", padx=10, pady=5) self.history_list = tk.Listbox(self.history_frame, height=2, font=("Arial", 10), bd=2) self.history_list.pack(fill="x", padx=5, pady=5) self.complex_buttons_frame = tk.Frame(self.complex_frame) self.complex_buttons_frame.pack(fill="both", expand=True) self.create_complex_buttons() # 默认显示简单界面 self.show_simple_interface() def setup_keyboard_bindings(self): # 绑定键盘事件 self.root.bind("<Key>", self.on_key_press) def create_simple_buttons(self): buttons = [ ("7", 0, 0), ("8", 0, 1), ("9", 0, 2), ("/", 0, 3), ("4", 1, 0), ("5", 1, 1), ("6", 1, 2), ("*", 1, 3), ("1", 2, 0), ("2", 2, 1), ("3", 2, 2), ("-", 2, 3), ("0", 3, 0), ("C", 3, 1), ("=", 3, 2), ("+", 3, 3) ] for (text, row, col) in buttons: button = tk.Button(self.simple_buttons_frame, text=text, font=("Arial", 18), width=5, height=2, command=lambda t=text: self.on_simple_button_click(t)) button.grid(row=row, column=col, padx=5, pady=5) def create_complex_buttons(self): buttons = [ # 第1行 ("7", 0, 0), ("8", 0, 1), ("9", 0, 2), ("/", 0, 3), ("C", 0, 4), # 第2行 ("4", 1, 0), ("5", 1, 1), ("6", 1, 2), ("*", 1, 3), ("(", 1, 4), # 第3行 ("1", 2, 0), ("2", 2, 1), ("3", 2, 2), ("-", 2, 3), (")", 2, 4), # 第4行 ("0", 3, 0), (".", 3, 1), ("=", 3, 2), ("+", 3, 3), ("√", 3, 4), # 第5行 - 科学功能 ("sin", 4, 0), ("cos", 4, 1), ("tan", 4, 2), ("π", 4, 3), ("e", 4, 4), # 第6行 - 指数运算 ("x²", 5, 0), ("x³", 5, 1), ("eˣ", 5, 2), ("10ˣ", 5, 3), ("n!", 5, 4), ] for (text, row, col) in buttons: btn = tk.Button( self.complex_buttons_frame, text=text, font=("Arial", 12), bd=3, relief="raised", command=lambda t=text: self.on_complex_button_click(t) ) btn.grid(row=row, column=col, sticky="nsew", padx=2, pady=2) # 网格自适应 for i in range(6): self.complex_buttons_frame.grid_rowconfigure(i, weight=1) for i in range(5): self.complex_buttons_frame.grid_columnconfigure(i, weight=1) def show_simple_interface(self): self.simple_frame.pack(fill="both", expand=True) self.complex_frame.pack_forget() self.current_interface = "simple" def show_complex_interface(self): self.complex_frame.pack(fill="both", expand=True) self.simple_frame.pack_forget() self.current_interface = "complex" # 重置科学计算器状态 self.expression = "" self.last_result = "" self.complex_entry.config(state="normal") self.complex_entry.delete(0, tk.END) self.complex_entry.insert(0, "0") self.complex_entry.config(state="readonly") self.history_list.delete(0, tk.END) def on_simple_button_click(self, text): if text == "C": self.simple_entry.delete(0, tk.END) elif text == "=": try: result = eval(self.simple_entry.get()) self.simple_entry.delete(0, tk.END) self.simple_entry.insert(0, str(result)) except Exception as e: self.simple_entry.delete(0, tk.END) self.simple_entry.insert(0, "错误") else: self.simple_entry.insert(tk.END, text) def on_complex_button_click(self, text): self.complex_entry.config(state="normal") if text == "=": self.calculate() elif text == "C": self.clear_all() else: self.append_expression(text) self.complex_entry.config(state="readonly") def append_expression(self, text): if text in ["sin", "cos", "tan", "√"]: self.expression += f"{text}(" elif text in ["x²", "x³"]: self.expression += f"**{2 if text == 'x²' else 3}" elif text in ["eˣ", "10ˣ"]: self.expression += f"{math.e if text == 'eˣ' else 10}**" elif text == "n!": self.expression += f"math.factorial(" elif text == "π": self.expression += str(math.pi) elif text == "e": self.expression += str(math.e) else: self.expression += text self.complex_entry.delete(0, tk.END) self.complex_entry.insert(0, self.expression) def calculate(self): try: expr = self.expression expr = expr.replace("π", str(math.pi)).replace("e", str(math.e)) expr = expr.replace("sin", "math.sin").replace("cos", "math.cos").replace("tan", "math.tan") expr = expr.replace("√", "math.sqrt") result = eval(expr, {"math": math}) self.last_result = str(result) self.complex_entry.delete(0, tk.END) self.complex_entry.insert(0, result) self.history_list.insert(0, f"{self.expression} = {result}") self.expression = self.last_result except Exception as e: messagebox.showerror("错误", f"计算失败:{str(e)}") self.complex_entry.delete(0, tk.END) self.complex_entry.insert(0, "错误") def clear_all(self): self.expression = "" self.complex_entry.delete(0, tk.END) self.complex_entry.insert(0, "0") def on_key_press(self, event): key = event.char keysym = event.keysym.lower() if self.current_interface == "simple": self.handle_simple_key(key, keysym) else: self.handle_complex_key(key, keysym) def handle_simple_key(self, key, keysym): key_map = { "0": "0", "1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "6": "6", "7": "7", "8": "8", "9": "9", "+": "+", "-": "-", "*": "*", "/": "/", ".": ".", "=": "=", "return": "=", "c": "C", "backspace": "C" } if key in key_map: self.on_simple_button_click(key_map[key]) elif keysym in key_map: self.on_simple_button_click(key_map[keysym]) def handle_complex_key(self, key, keysym): key_map = { "0": "0", "1": "1", "2": "2", "3": "3", "4": "4", "5": "5", "6": "6", "7": "7", "8": "8", "9": "9", "+": "+", "-": "-", "*": "*", "/": "/", ".": ".", "=": "=", "return": "=", "c": "C", "backspace": "C", "(": "(", ")": ")", } # 处理功能键 function_keys = { "s": "sin", "c": "cos", "t": "tan", "r": "√", "p": "π", "e": "e", "2": "x²", "3": "x³" } if key in key_map: self.on_complex_button_click(key_map[key]) elif keysym in function_keys: self.on_complex_button_click(function_keys[keysym]) elif keysym == "escape": self.clear_all() if __name__ == "__main__": root = tk.Tk() app = Calculator(root) root.mainloop() 解释每一行代码的用途
06-24
untitled16 最优成本:27364.4246 函数或变量 'baseSplitRoutes' 无法识别。 出错 untitled16>printDeliveryPlan (第 493 行) vehicle_routes = baseSplitRoutes(route_order, depot_id, params, distance_matrix); 出错 untitled16 (第 655 行) printDeliveryPlan(best_solution, struct(... >> %% 基础数据加载 node_coords = [ 12039.846772,3908.892133 12051.704390,3899.422153 12038.547752,3904.837542 ]; % 配送节点坐标 customer_data = xlsread('新建 Microsoft Excel 工作表.xlsx', 'Sheet1'); customer_coords = customer_data(:, 1:2); % 客户坐标 delivery_demand = customer_data(:,3); % 正向配送需求 recycle_demand = customer_data(:,4); % 逆向回收需求 %% 参数设置 max_distance = 400; % 单程最大距离(km) vehicle_speed = 50; % 车速(km/h) vehicle_capacity = 10; % 单车运载量 depot_capacity = 10000; % 节点服务能力 operating_cost = 400; % 节点运营成本 cr1 = 300; % 车辆租赁成本 c0 = 200; % 车辆启动成本 c1 = 0.64; % 载重运输成本系数(元/吨·公里) c2 = 1.96; % 空车行驶成本系数(元/公里) known_solution.node1 = [6,7,9,10,14,18,20,21,34,39,40,44,51,53,59,62,64,69,76,78,... 79,82,93,94,97,99,104,105,114,119,126,127,128,129,130,133,134,158,159,160]; known_solution.node2 = [3,4,12,16,17,19,27,28,29,30,31,33,42,45,47,48,49,50,55,56,... 57,61,66,81,83,84,85,90,91,92,98,101,102,103,111,113,115,118,122,123,... 124,132,136,137,138,139,140,141,142,143,144,145,147,148,149,150,151,152,153,154,... 155,161,162,163]; known_solution.node3 = [1,2,5,8,11,13,15,22,23,24,25,26,32,35,36,37,38,41,43,46,... 52,54,58,60,63,65,67,68,70,71,72,73,74,75,77,80,86,87,88,89,... 95,96,100,106,107,108,109,110,112,116,117,120,121,125,131,135,146,156,157]; %% 距离矩阵生成 all_points = [node_coords; customer_coords]; distance_matrix = squareform(pdist(all_points, 'euclidean')); %% 遗传算法参数 pop_size = 100; % 种群数量 max_gen = 200; % 最大迭代次数 cross_rate = 0.85; % 交叉概率 mutate_rate = 0.1; % 变异概率 function population = enhancedInitialization(pop_size, num_nodes, num_customers, known_solution) population = cell(1, pop_size); % 1. 注入已知解 population{1} = encodeSolution(known_solution, num_customers); % 2. 添加聚类初始化解(20%) for i = 2:ceil(pop_size*0.2) population{i} = clusterBasedInitialization(num_nodes, num_customers, distance_matrix); end % 3. 添加最近邻初始化解(20%) for i = ceil(pop_size*0.2)+1:ceil(pop_size*0.4) population{i} = nearestNeighborInitialization(num_nodes, num_customers, distance_matrix); end % 4. 随机初始化其余解 for i = ceil(pop_size*0.4)+1:pop_size allocation = randi(num_nodes, 1, num_customers); sequence = randperm(num_customers); population{i} = [allocation, sequence]; end end %% 染色体编码函数 function chrom = clusterBasedInitialization(num_nodes, num_customers, dist_mat) [idx, ~] = kmeans(customer_coords, num_nodes); % 按坐标聚类 % 按聚类结果分配节点 allocation = zeros(1, num_customers); sequences = cell(1, num_nodes); for n = 1:num_nodes cluster_members = find(idx == n); allocation(cluster_members) = n; % 为聚类内客户生成优化序列 if ~isempty(cluster_members) sequences{n} = twoOptOptimization(cluster_members, n, dist_mat); else sequences{n} = []; end end % 合并所有序列 full_sequence = []; for n = 1:num_nodes full_sequence = [full_sequence, sequences{n}]; end chrom = [allocation, full_sequence]; end %% 适应度函数 function [total_cost] = fitnessFunc(chrom, distance_matrix, params) nodes_num = size(params.node_coords,1); customers_num = length(params.customer_coords); allocation = chrom(1:customers_num); sequence = chrom(customers_num+1:end); total_cost = 0; for n = 1:nodes_num node_customers = find(allocation == n); node_delivery = sum(params.delivery_demand(node_customers)); node_recycle = sum(params.recycle_demand(node_customers)); % 节点容量检查 if node_delivery > params.depot_capacity total_cost = total_cost + 1e6; % 容量惩罚 continue; end % 路径规划 %% 修正后的路径规划逻辑 if ~isempty(node_customers) % 获取客户在全局路径序列中的位置 [~, seq_positions] = ismember(node_customers, sequence); % 组合过滤条件(同时处理0值和超限索引) valid_mask = (seq_positions <= length(sequence)); valid_positions = seq_positions(valid_mask); % 按染色体序列顺序重构路径 if ~isempty(valid_positions) % 按sequence中的原始顺序排序 [~, sort_idx] = sort(valid_positions); route_order = node_customers(valid_mask); route_order = route_order(sort_idx); % 保持染色体序列顺序 else route_order = []; end % 强化数据验证 if ~isempty(route_order) assert(all(ismember(route_order, sequence)),... '路径包含不存在于全局序列的客户: %s', mat2str(route_order)); assert(max(route_order) <= max(sequence),... '客户索引超限: %d > %d', max(route_order), max(sequence)); end i = 1; vehicle_count = 0; while i <= length(route_order) % 初始化当前路径段 segment = []; current_delivery = 0; current_recycle = 0; % 遍历客户构建可行路径段 for j = i:length(route_order) customer = route_order(j); % 检查新增客户是否超出容量 temp_delivery = current_delivery + params.delivery_demand(customer); temp_recycle = current_recycle + params.recycle_demand(customer); vehicle_routes = baseSplitRoutes(route_order, n, params, distance_matrix); if temp_delivery > params.vehicle_capacity || temp_recycle > params.vehicle_capacity % 超过容量时保留j之前的客户作为当前段 break; end % 更新当前段信息 segment = [segment, customer]; current_delivery = temp_delivery; current_recycle = temp_recycle; end % 处理有效路径段 if ~isempty(segment) vehicle_count = vehicle_count + 1; % 计算该段的运输成本(从仓库出发并返回) transport_cost = calculateSegmentCost(segment, n, params, distance_matrix); total_cost = total_cost + transport_cost; end % 移动索引到下一个未处理的客户 i = i + length(segment); % 处理单个客户超容的特殊情况 if isempty(segment) && i <= length(route_order) % 如果当前客户单独超容,跳过并施加惩罚 total_cost = total_cost + 1e6; i = i + 1; end end [node_cost, vehicles] = calculateNodeCost(route_order, n, params, distance_matrix); % 计算运输成本 if ~isempty(segment) vehicle_count = vehicle_count + 1; transport_cost = 0; % 配送中心到第一个客户 from = n; to = segment(1) + nodes_num; distance = distance_matrix(from, to); transport_cost = transport_cost + (params.c1*current_delivery + params.c2)*distance; % 客户间移动 for k = 2:length(segment) from = segment(k-1) + nodes_num; to = segment(k) + nodes_num; distance = distance_matrix(from, to); remaining_delivery = current_delivery - sum(params.delivery_demand(segment(1:k-1))); transport_cost = transport_cost + (params.c1*remaining_delivery + params.c2)*distance; end % 返回配送中心 from = segment(end) + nodes_num; to = n; distance = distance_matrix(from, to); transport_cost = transport_cost + (params.c1*current_recycle + params.c2)*distance; total_cost = total_cost + node_cost + params.operating_cost; end end % 累加固定成本 total_cost = total_cost + params.operating_cost + vehicle_count*(params.cr1 + params.c0); end end figure('Name','适应度进化曲线','NumberTitle','off'); h_plot = plot(0, 0, 'b-', 0, 0, 'r--'); title('适应度进化过程'); xlabel('迭代代数'); ylabel('适应度值'); legend('最佳适应度', '平均适应度'); grid on; hold on; %% 修正后的可视化函数(分拆为两个独立函数) function visualizeRoutes(chrom, depot_coords, customer_coords) % 整体路径可视化函数 num_customers = length(customer_coords); num_depots = size(depot_coords,1); figure; hold on; % 绘制仓库 scatter(depot_coords(:,1), depot_coords(:,2), 100, 'k^', 'filled'); % 绘制客户点 scatter(customer_coords(:,1), customer_coords(:,2), 50, 'bo'); % 解析路径 for d = 1:num_depots depot_customers = find(chrom(1:num_customers) == d); if ~isempty(depot_customers) [~, seq_pos] = ismember(depot_customers, chrom(num_customers+1:end)); valid_seq = seq_pos(seq_pos > 0); [~, order] = sort(valid_seq); sorted_customers = depot_customers(order); route = [depot_coords(d,:); customer_coords(sorted_customers,:); depot_coords(d,:)]; plot(route(:,1), route(:,2), 'LineWidth', 1.5); end end hold off; title('全局配送路径'); xlabel('X坐标'); ylabel('Y坐标'); legend('仓库', '客户点'); end function visualizeDepotRoutes(chrom, depot_coords, customer_coords) % 各节点独立路径可视化函数 num_customers = length(customer_coords); num_depots = size(depot_coords,1); for d = 1:num_depots figure('Position', [200+(d-1)*50, 200+(d-1)*50, 600, 400]); hold on; title(['配送中心' num2str(d) '路径规划']); % 绘制当前配送中心 scatter(depot_coords(d,1), depot_coords(d,2), 150, 'r^', 'filled'); depot_customers = find(chrom(1:num_customers) == d); if ~isempty(depot_customers) [~, seq_pos] = ismember(depot_customers, chrom(num_customers+1:end)); valid_seq = seq_pos(seq_pos > 0 & seq_pos <= length(chrom)-num_customers); [~, order] = sort(valid_seq); sorted_customers = depot_customers(order); % 客户点标注 scatter(customer_coords(sorted_customers,1),... customer_coords(sorted_customers,2),... 80, 'bo', 'filled'); text_offset = 0.1 * max(range(customer_coords)); text(customer_coords(sorted_customers,1)+text_offset,... customer_coords(sorted_customers,2)+text_offset,... cellstr(num2str(sorted_customers')),... 'FontSize',8); % 路径绘制 route = [depot_coords(d,:); customer_coords(sorted_customers,:); depot_coords(d,:)]; plot(route(:,1), route(:,2), 'b--o',... 'LineWidth',1.5,... 'MarkerSize',6,... 'MarkerFaceColor','w'); else text(mean(depot_coords(d,1)), mean(depot_coords(d,2)),... '无服务客户',... 'HorizontalAlignment','center',... 'FontSize',12); end xlabel('X坐标 (米)'); ylabel('Y坐标 (米)'); grid on; axis equal; hold off; end end %% 交叉操作函数实现 function [child1, child2] = depotCrossover(parent1, parent2, num_customers) % 分配部分交叉(均匀交叉) alloc_part1 = parent1(1:num_customers); alloc_part2 = parent2(1:num_customers); mask = randi([0 1], 1, num_customers); child1_alloc = alloc_part1.*mask + alloc_part2.*(~mask); child2_alloc = alloc_part1.*(~mask) + alloc_part2.*mask; % 路径顺序交叉(OX交叉) seq_part1 = parent1(num_customers+1:end); seq_part2 = parent2(num_customers+1:end); [child1_seq, child2_seq] = oxCrossover(seq_part1, seq_part2); child1 = [child1_alloc, child1_seq]; child2 = [child2_alloc, child2_seq]; end %% 修正后的OX交叉辅助函数 function [child1, child2] = oxCrossover(parent1, parent2) n = length(parent1); cp = sort(randi(n-1,1,2)); % 确保交叉点有效 if cp(1) == cp(2), cp(2) = cp(2)+1; end % 防止相同切点 % 子代1生成 segment = parent1(cp(1):cp(2)); remaining = parent2(~ismember(parent2, segment)); child1 = [remaining(1:cp(1)-1), segment, remaining(cp(1):end)]; % 子代2生成(修正索引错误) segment = parent2(cp(1):cp(2)); remaining = parent1(~ismember(parent1, segment)); % 确保索引不越界 if (cp(1)-1) <= length(remaining) part1 = remaining(1:cp(1)-1); else part1 = remaining(1:end); end child2 = [part1, segment, remaining(cp(1):end)]; end %% 变异操作函数实现 function mutated = localSearchMutation(chrom, num_nodes, num_customers, dist_mat) allocation = chrom(1:num_customers); sequence = chrom(num_customers+1:end); % 随机选择一种局部优化方式 mutation_type = randi(3); switch mutation_type case 1 % 2-opt优化 depot_id = randi(num_nodes); depot_customers = find(allocation == depot_id); if length(depot_customers) > 1 [~, pos] = ismember(depot_customers, sequence); sequence(pos) = twoOptOptimization(depot_customers, depot_id, dist_mat); end case 2 % 节点间交换 % 选择两个不同节点 swap_nodes = randperm(num_nodes, 2); node1_cust = find(allocation == swap_nodes(1)); node2_cust = find(allocation == swap_nodes(2)); % 随机选择要交换的客户 swap_count = min([ceil(0.2*length(node1_cust)), ceil(0.2*length(node2_cust)), 3]); cust1 = datasample(node1_cust, swap_count, 'Replace', false); cust2 = datasample(node2_cust, swap_count, 'Replace', false); % 执行交换 allocation(cust1) = swap_nodes(2); allocation(cust2) = swap_nodes(1); case 3 % 路径内交换 swap_points = randperm(num_customers, 2); sequence(swap_points) = sequence(fliplr(swap_points)); end mutated = [allocation, sequence]; end %% 历史最优成本可视化 % 生成累积最优成本数组 cumulative_min = cummin(best_history); figure('Color','w'); plot(cumulative_min, 'b-o',... 'LineWidth',1.2,... 'MarkerSize',4,... 'MarkerFaceColor','w'); % 设置坐标轴标签 xlabel('迭代代数'); ylabel('历史最优成本 (元)'); title('全局最优成本进化过程'); % 自动标注最终最优值 [final_min, final_gen] = min(cumulative_min); text(final_gen, final_min,... sprintf(' %.2f万 @%d代', final_min/10000, final_gen),... 'VerticalAlignment','bottom',... 'FontSize',9); % 智能坐标轴设置 ax = gca; ax.YAxis.Exponent = floor(log10(final_min)) - 1; % 自动确定指数 grid on; %% 新增的运输成本计算函数 function cost = calculateRouteCost(route, params, distance_matrix) num_nodes = size(params.node_coords,1); depot_id = mode(params.chrom(route)); % 获取所属配送中心 % 正向运输成本 forward_cost = 0; current_load = sum(params.delivery_demand(route)); % 配送中心到第一个客户 from = depot_id; to = route(1) + num_nodes; distance = distance_matrix(from, to); forward_cost = forward_cost + (params.c1*current_load + params.c2)*distance; % 客户间运输 for k = 2:length(route) from = route(k-1) + num_nodes; to = route(k) + num_nodes; distance = distance_matrix(from, to); current_load = current_load - params.delivery_demand(route(k-1)); forward_cost = forward_cost + (params.c1*current_load + params.c2)*distance; end % 逆向运输成本 recycle_load = sum(params.recycle_demand(route)); from = route(end) + num_nodes; to = depot_id; distance = distance_matrix(from, to); recycle_cost = (params.c1*recycle_load + params.c2)*distance; cost = forward_cost + recycle_cost; end %% 配送方案输出函数 function printDeliveryPlan(best_solution, params, distance_matrix) num_depots = size(params.node_coords,1); num_customers = size(params.customer_coords,1); % 解析染色体 allocation = best_solution(1:num_customers); global_sequence = best_solution(num_customers+1:end); % 创建结果结构体 depot_info = struct(... 'DepotID', {},... 'Vehicles', {},... 'TotalCost', {},... 'Details', {}); % 遍历所有配送中心 for depot_id = 1:num_depots % 获取当前配送中心分配的客户 customers = find(allocation == depot_id); if isempty(customers) continue; end % 获取路径顺序 [~, seq_pos] = ismember(customers, global_sequence); valid_seq = seq_pos(seq_pos > 0); [~, sort_idx] = sort(valid_seq); route_order = customers(sort_idx); % 路径分割 vehicle_routes = baseSplitRoutes(route_order, depot_id, params, distance_matrix); % 计算成本和详细信息 depot_cost = 0; vehicle_details = cell(length(vehicle_routes),1); for v = 1:length(vehicle_routes) route = vehicle_routes{v}; [cost, detail] = calculateVehicleCost(route, depot_id, params, distance_matrix); vehicle_details{v} = detail; depot_cost = depot_cost + cost; end % 添加固定成本 depot_cost = depot_cost + params.operating_cost + ... length(vehicle_routes)*(params.cr1 + params.c0); % 存储结果 depot_info(end+1) = struct(... 'DepotID', depot_id,... 'Vehicles', length(vehicle_routes),... 'TotalCost', depot_cost,... 'Details', {vehicle_details}); end %% 打印结果 fprintf('========== 全局配送方案 ==========\n'); total_cost = sum([depot_info.TotalCost]); fprintf('总运营成本: %.2f 万元\n', total_cost/10000); for d = 1:length(depot_info) fprintf('\n=== 配送中心%d ===\n', depot_info(d).DepotID); fprintf('派出车辆: %d\n', depot_info(d).Vehicles); fprintf('中心总成本: %.2f 万元\n', depot_info(d).TotalCost/10000); % 打印车辆明细 fprintf('\n车辆明细:\n'); fprintf('%-8s%-12s%-12s%-10s%-10s%-12s%-15s\n',... '车辆ID','正向载货量','逆向载载量','里程(km)','运输成本','总成本','服务客户顺序'); for v = 1:length(depot_info(d).Details) detail = depot_info(d).Details{v}; total = detail.transport_cost + params.cr1 + params.c0; % 生成客户顺序字符串 customer_str = strjoin(arrayfun(@(x) sprintf('%d',x), detail.customers, 'UniformOutput', false),'->'); fprintf('%-8d%-12.2f%-12.2f%-10.2f%-10.2f%-12.2f%-15s\n',... v,... detail.delivery_load,... detail.recycle_load,... detail.distance,... detail.transport_cost,... total,... customer_str); % 新增客户顺序输出 end end end %% 非递归路径分割函数 function vehicle_routes = adaptiveSplitRoutes(route_order, depot_id, params, dist_mat) vehicle_routes = {}; remaining_cust = route_order; while ~isempty(remaining_cust) current_route = []; current_load = 0; max_insert_score = -Inf; best_candidate = []; % 尝试所有可行插入位置 for i = 1:length(remaining_cust) candidate = remaining_cust(i); new_load = current_load + params.delivery_demand(candidate) + ... params.recycle_demand(candidate); if new_load <= params.vehicle_capacity % 计算插入得分(距离增益/需求比例) if isempty(current_route) distance_gain = dist_mat(depot_id, depot_id + candidate); else last_cust = current_route(end); original_dist = dist_mat(depot_id + last_cust, depot_id); new_dist = dist_mat(depot_id + last_cust, depot_id + candidate) + ... dist_mat(depot_id + candidate, depot_id); distance_gain = original_dist - new_dist; end insert_score = distance_gain/(1 + params.delivery_demand(candidate)); if insert_score > max_insert_score max_insert_score = insert_score; best_candidate = candidate; best_index = i; end end end % 添加最佳客户或创建新车 if ~isempty(best_candidate) current_route(end+1) = best_candidate; current_load = current_load + params.delivery_demand(best_candidate) + ... params.recycle_demand(best_candidate); remaining_cust(best_index) = []; else vehicle_routes{end+1} = current_route; current_route = []; current_load = 0; end end % 添加最后一条路径 if ~isempty(current_route) vehicle_routes{end+1} = current_route; end end %% 修正后的车辆成本计算函数 function [total_cost, detail] = calculateVehicleCost(route, depot_id, params, distance_matrix) num_nodes = size(params.node_coords,1); % 运输成本计算 transport_cost = 0; total_distance = 0; % 仓库到第一个客户 from = depot_id; to = route(1) + num_nodes; distance = distance_matrix(from, to); transport_cost = transport_cost + (params.c1*sum(params.delivery_demand(route)) + params.c2)*distance; total_distance = total_distance + distance; % 客户间移动 for k = 2:length(route) from = route(k-1) + num_nodes; to = route(k) + num_nodes; distance = distance_matrix(from, to); remaining_delivery = sum(params.delivery_demand(route(k:end))); transport_cost = transport_cost + (params.c1*remaining_delivery + params.c2)*distance; total_distance = total_distance + distance; end % 返回仓库 from = route(end) + num_nodes; to = depot_id; distance = distance_matrix(from, to); transport_cost = transport_cost + (params.c1*sum(params.recycle_demand(route)) + params.c2)*distance; total_distance = total_distance + distance; % 修正后的结构体定义(合并字段定义) detail = struct(... 'customers', route,... % 客户顺序 'delivery_load', sum(params.delivery_demand(route)),... 'recycle_load', sum(params.recycle_demand(route)),... 'distance', total_distance,... 'transport_cost',transport_cost); total_cost = transport_cost + params.cr1 + params.c0; end %% 在主循环后调用输出函数(添加在结果显示部分) % 结果显示 disp(['最优成本:' num2str(best_cost)]); visualizeRoutes(best_solution, node_coords, customer_coords); visualizeDepotRoutes(best_solution, node_coords, customer_coords); % 分节点视图 %% 修改后的printDeliveryPlan调用 printDeliveryPlan(best_solution, struct(... 'node_coords', node_coords,... 'customer_coords', customer_coords,... 'delivery_demand', delivery_demand,... 'recycle_demand', recycle_demand,... 'depot_capacity', depot_capacity,... 'vehicle_capacity', vehicle_capacity,... 'max_distance', max_distance,... % 新增字段 'operating_cost', operating_cost,... 'cr1', cr1,... 'c0', c0,... 'c1', c1,... 'c2', c2), distance_matrix); function optimized_route = twoOptOptimization(route, distance_matrix, params) num_nodes = length(route); improved = true; best_route = route; best_cost = calculateRouteCost(route, params, distance_matrix); while improved improved = false; for i = 1:num_nodes-1 for j = i+2:num_nodes new_route = best_route; new_route(i+1:j) = new_route(j:-1:i+1); new_cost = calculateRouteCost(new_route, params, distance_matrix); if new_cost < best_cost best_route = new_route; best_cost = new_cost; improved = true; end end end end optimized_route = best_route; end function selected = tournamentSelection(population, fitness, tournament_size, elite_num) pop_size = length(population); selected = cell(1, pop_size - elite_num); % 留出精英位置 % 精英保留 [~, elite_idx] = mink(fitness, elite_num); elite = population(elite_idx); % 锦标赛选择 for i = 1:length(selected) candidates = randperm(pop_size, tournament_size); [~, idx] = min(fitness(candidates)); selected{i} = population{candidates(idx)}; end % 合并精英和选择结果 selected = [selected, elite]; end function optimized_routes = optimizedSplitRoutes(route_order, depot_id, params, distance_matrix) % 调用基础函数 raw_routes = baseSplitRoutes(route_order, depot_id, params, distance_matrix); % 2-opt优化处理 optimized_routes = cellfun(@(x) twoOptOptimization(x, distance_matrix, params),... raw_routes, 'UniformOutput', false); end function transport_cost = calculateSegmentCost(segment, depot_id, params, distance_matrix) num_nodes = size(params.node_coords,1); transport_cost = 0; % 正向运输成本 current_delivery = sum(params.delivery_demand(segment)); % 配送中心到第一个客户 from = depot_id; to = segment(1) + num_nodes; distance = distance_matrix(from, to); transport_cost = transport_cost + (params.c1*current_delivery + params.c2)*distance; % 客户间运输 for k = 2:length(segment) from = segment(k-1) + num_nodes; to = segment(k) + num_nodes; distance = distance_matrix(from, to); remaining_delivery = current_delivery - sum(params.delivery_demand(segment(1:k-1))); transport_cost = transport_cost + (params.c1*remaining_delivery + params.c2)*distance; end % 逆向运输成本 recycle_load = sum(params.recycle_demand(segment)); from = segment(end) + num_nodes; to = depot_id; distance = distance_matrix(from, to); transport_cost = transport_cost + (params.c1*recycle_load + params.c2)*distance; end function [vehicle_routes, extra_vehicles] = enhancedSplitRoutes(route_order, depot_id, params, distance_matrix) vehicle_routes = {}; extra_vehicles = struct('customers', {}, 'count', {}, 'cost', {}); i = 1; while i <= length(route_order) current_load = 0; segment = []; extra_count = 0; % 逐个客户装载直到容量上限 for j = i:length(route_order) customer = route_order(j); new_load = current_load + params.delivery_demand(customer) + params.recycle_demand(customer); % 分载条件检查 if new_load > params.vehicle_capacity % 处理单个客户超容的情况 if isempty(segment) extra_count = extra_count + 1; extra_vehicles(end+1) = struct(... 'customers', customer,... 'count', 1,... 'cost', params.c0 + params.cr1); i = i + 1; % 跳过当前客户 break; end % 正常分载处理 break; end segment = [segment, customer]; current_load = new_load; end if ~isempty(segment) vehicle_routes{end+1} = segment; i = i + length(segment); end % 记录额外车辆数 if extra_count > 0 extra_vehicles(end).count = extra_count; end end end %% 修改后的成本计算函数 function [node_cost, extra_info] = calculateNodeCost(route_order, depot_id, params, distance_matrix) [vehicle_routes, extra_vehicles] = enhancedSplitRoutes(route_order, depot_id, params, distance_matrix); transport_cost = 0; % 常规运输成本 for v = 1:length(vehicle_routes) segment = vehicle_routes{v}; transport_cost = transport_cost + calculateSegmentCost(segment, depot_id, params, distance_matrix); end % 额外车辆成本 extra_cost = sum([extra_vehicles.cost]) .* sum([extra_vehicles.count]); % 总成本计算 node_cost = transport_cost + ... (length(vehicle_routes) * (params.cr1 + params.c0)) + ... extra_cost; % 返回额外车辆信息 extra_info = extra_vehicles; end %% 新增预处理校验函数 function validateDemands(delivery, recycle, capacity) % 检查单个客户总需求 client_total = delivery + recycle; if any(client_total > capacity) violators = find(client_total > capacity); err_msg = sprintf('客户%d总需求超标: ', violators(1)); for v = violators' err_msg = sprintf('%s\n- 客户%d: %.1f (限额%.1f)',... err_msg, v, client_total(v), capacity); end error(err_msg); end end function diversity = computePopulationDiversity(population) num_indv = length(population); num_genes = length(population{1}); gene_diversity = zeros(1, num_genes); for i = 1:num_indv for j = i+1:num_indv gene_diversity = gene_diversity + (population{i} ~= population{j}); end end diversity = mean(gene_diversity) / num_genes; end% 初始化存储数组 best_history = zeros(max_gen,1); avg_history = zeros(max_gen,1); %% 遗传算法主循环 population = arrayfun(@(x) createChrom(size(node_coords,1), size(customer_coords,1)),... 1:pop_size, 'UniformOutput', false); best_cost = Inf; adaptive_params = struct(... 'cross_rate', 0.85,... % 初始交叉率 'mutate_rate', 0.15,... % 初始变异率 'stagnation', 0); % 停滞计数器 for gen = 1:max_gen % 计算适应度 %% 修改后的适应度函数调用(添加max_distance字段) costs = cellfun(@(x) fitnessFunc(x, distance_matrix, struct(... 'node_coords', node_coords,... 'customer_coords', customer_coords,... 'delivery_demand', delivery_demand,... 'recycle_demand', recycle_demand,... 'depot_capacity', depot_capacity,... 'vehicle_capacity', vehicle_capacity,... 'max_distance', max_distance,... % 新增字段 'operating_cost', operating_cost,... 'cr1', cr1,... 'c0', c0,... 'c1', c1,... 'c2', c2)),... population); [min_cost, idx] = min(costs); current_avg = mean(costs); best_history(gen) = min_cost; avg_history(gen) = current_avg; % 更新可视化曲线 set(h_plot(1), 'XData', 1:gen, 'YData', best_history(1:gen)); set(h_plot(2), 'XData', 1:gen, 'YData', avg_history(1:gen)); xlim([1 max_gen]); drawnow; if min_cost < best_cost best_solution = population{idx}; best_cost = min_cost; end % 选择操作 selected_pop = tournamentSelection(population, costs, 3); % 交叉操作 %% 修正后的交叉操作部分 % 交叉操作 new_population = cell(1, pop_size); for i = 1:2:pop_size % 从selected_pop获取父代个体 parent1 = selected_pop{i}; parent2 = selected_pop{i+1}; if rand() < cross_rate [child1, child2] = depotCrossover(parent1, parent2, size(customer_coords,1)); new_population{i} = child1; new_population{i+1} = child2; else new_population{i} = parent1; new_population{i+1} = parent2; end end % 变异操作 for i = 1:pop_size if rand() < mutate_rate new_population{i} = depotMutate(new_population{i},... size(node_coords,1),... size(customer_coords,1)); end end if gen > 20 && std(costs) < 0.1*mean(costs) adaptive_params.cross_rate = min(0.95, adaptive_params.cross_rate + 0.05); adaptive_params.mutate_rate = min(0.3, adaptive_params.mutate_rate + 0.02); else adaptive_params.cross_rate = 0.85; adaptive_params.mutate_rate = 0.15; end diversity = computePopulationDiversity(population); % 动态调整参数 if gen > 20 % 提前收敛时提高变异率 if diversity < 0.3 mutate_rate = min(0.3, mutate_rate * 1.2); cross_rate = max(0.6, cross_rate * 0.9); % 发散时提高交叉率 elseif diversity > 0.7 mutate_rate = max(0.05, mutate_rate * 0.8); cross_rate = min(0.95, cross_rate * 1.1); end end % 显示当前参数状态 fprintf('Generation %d: CR=%.3f, MR=%.3f, Diversity=%.2f\n',... gen, cross_rate, mutate_rate, diversity); % 使用调整后的参数 cross_rate = adaptive_params.cross_rate; mutate_rate = adaptive_params.mutate_rate; population = new_population; end %% 结果显示 disp(['最优成本:' num2str(best_cost)]); visualizeRoutes(best_solution, node_coords, customer_coords);
06-04
# -*- coding: utf-8 -*- """ 钢结构格构柱计算与绘图系统 - 自动生成计算书和示意图 """ import pandas as pd import numpy as np import math import matplotlib.pyplot as plt from matplotlib.patches import Rectangle, Polygon from datetime import datetime import os import re # 添加这一行 class SteelLacedColumnSystem: """钢结构格构柱计算与绘图系统""" def __init__(self, csv_file='channel_sections.csv'): self.csv_file = csv_file self.results = {} self.params = {} def verify_stability(self, section_name, tie_plate_spacing, plate_size, steel_grade, gap, L, N, fd): """钢结构稳定性验算""" # 保存参数用于绘图 self.params = { 'section_name': section_name, 'tie_plate_spacing': tie_plate_spacing, 'plate_size': plate_size, 'steel_grade': steel_grade, 'gap': gap, 'L': L, 'N': N, 'fd': fd } content = [] content.append("# 轴心受压格构柱整体稳定性验算") content.append("") try: df = pd.read_csv(self.csv_file) numeric_columns = ['A', 'Ix', 'Iy', 'iy', 'x0', 'ix'] for col in numeric_columns: if col in df.columns: df[col] = pd.to_numeric(df[col], errors='coerce') section_data = df[df['model'] == section_name].iloc[0] except: error_msg = f"错误: 无法加载截面数据 '{section_name}'" content.append(error_msg) return content, False A_single = section_data['A'] Ix_single = section_data['Ix'] Iy_single = section_data['Iy'] iy_single = section_data['iy'] ix_single = section_data['ix'] y0 = section_data['x0'] fy_dict = {'Q235B': 235, 'Q345B': 345, 'Q390B': 390, 'Q420B': 420} fy = fy_dict.get(steel_grade, 235) y0_value = gap - 2 * y0 A_total = 2 * A_single Ix_total = 2 * (Iy_single + A_single * (y0_value * 0.5) ** 2) ix_total = math.sqrt(Ix_total / A_total) iy_total = ix_single slenderness_ratio_x = L / ix_total slenderness_ratio_0x = slenderness_ratio_x slenderness_ratio_1 = (tie_plate_spacing - plate_size[1]) / iy_single slenderness_ratio_0y = math.sqrt(slenderness_ratio_x ** 2 + slenderness_ratio_1 ** 2) max_slenderness_ratio = max(slenderness_ratio_0x, slenderness_ratio_0y) steel_params_b_class = { 'Q235': [0.650, 0.965, 0.300], 'Q345': [0.650, 0.965, 0.300], 'Q390': [0.650, 0.965, 0.300], 'Q420': [0.650, 0.965, 0.300] } alpha1, alpha2, alpha3 = steel_params_b_class.get(steel_grade[:-1], steel_params_b_class['Q235']) lambda_n = max_slenderness_ratio / math.pi * math.sqrt(fy / 206000) if lambda_n <= 0.215: phi = 1 - alpha1 * lambda_n ** 2 else: phi = ((alpha2 + alpha3 * lambda_n + lambda_n ** 2) - math.sqrt((alpha2 + alpha3 * lambda_n + lambda_n ** 2) ** 2 - 4 * lambda_n ** 2)) / ( 2 * lambda_n ** 2) # 计算稳定承载力 N_capacity = phi * A_total * fd * 0.1 # 输出结果到内容 content.append("## 一、输入参数") content.append("") content.append(f"- 槽钢型号: [{section_name}") content.append(f"- 缀板间距: {tie_plate_spacing*10} mm") content.append(f"- 缀板尺寸: {plate_size[0]*10}×{plate_size[1]*10}×{plate_size[2]*10} mm") content.append(f"- 钢材牌号: {steel_grade}, 设计强度:fd= {fd} N/mm²") content.append(f"- 构件长度: {L/100} m") content.append(f"- 轴心压力设计值: N={N} kN") content.append("## 二、截面特性") content.append(f"- 查阅规范GBT706-2016《热轧型钢》") content.append(f"- 截面总面积: A=2×{A_single}={A_total} cm²") content.append(f"- 对x轴回转半径: ix={ix_total:.2f} cm") content.append(f"- 对y轴回转半径: iy={iy_total:.2f} cm") content.append("## 三、稳定性计算") content.append(f"- 对x轴长细比: λx={slenderness_ratio_x:.2f}") content.append(f"- 单肢长细比: λ1={tie_plate_spacing - plate_size[1]}/{iy_single}={slenderness_ratio_1:.2f}") content.append(f"- 换算长细比: λ0x = √(λx² + λ1²) = √({slenderness_ratio_x:.2f}² + {slenderness_ratio_1:.2f}²)={slenderness_ratio_0y:.2f}") content.append(f"- 最大长细比: {max_slenderness_ratio:.2f}") content.append(f"- 相对长细比 λ_n: λn=λ0x/(π*√(fy/E))={slenderness_ratio_0y:.2f}/π*√(235/2.06×10⁵)={lambda_n:.3f}") content.append(f"- 稳定系数: φ=1/(2λ²)*[(a2+a3λn+λn²)-√((a2+a3λn+λn²)²-4λn²)]={phi:.4f}") content.append("## 四、承载力计算") content.append("") content.append(f"- 稳定承载力:Ncrd=φAf={phi:.4f}×{A_total}×10²×{fd}={N_capacity:.4f} kN") content.append(f"- 承载力与设计值比值: ({N}-{N_capacity:.4f})/{N_capacity:.4f}={(abs(N_capacity - N) / N_capacity)*100:.4f}%") content.append("") content.append("## 五、验算结果") content.append("") if N_capacity >= N: content.append("✅ 验算结果: 满足承载能力要求") result = True else: content.append("❌ 验算结果: 不满足承载能力要求") result = False if abs(N_capacity - N) / N_capacity < 0.05: content.append("⚠️ 工程设计验算结果:承载力在5%内,可以考虑满足要求") else: content.append("⚠️ 工程设计验算结果:承载力不在5%内,考虑不满足要求") # 保存结果 self.results['stability'] = { 'N_capacity': N_capacity, 'phi': phi, 'slenderness_ratios': { 'x': slenderness_ratio_x, 'y': slenderness_ratio_0y, 'single': slenderness_ratio_1, 'max': max_slenderness_ratio }, 'result': result } return content, result def create_schematic_diagram(self): """创建格构柱示意图""" if not self.params: return None fig, ax = plt.subplots(figsize=(12, 10)) ax.set_aspect('equal') ax.set_xlim(0, 100) ax.set_ylim(0, 150) ax.grid(False) ax.set_axis_off() # 绘制主视图 up_left_rect = Rectangle((20, 60), 10, 80, linewidth=2, edgecolor='black', facecolor='lightblue') ax.add_patch(up_left_rect) up_right_rect = Rectangle((60, 60), 10, 80, linewidth=2, edgecolor='black', facecolor='lightblue') ax.add_patch(up_right_rect) down_plate = Rectangle((25, 70), 40, 10, linewidth=2, edgecolor='black', facecolor='none') ax.add_patch(down_plate) up_plate = Rectangle((25, 120), 40, 10, linewidth=2, edgecolor='black', facecolor='none') ax.add_patch(up_plate) # 绘制俯视图 vertices_1 = np.array([ [20, 20], [20, 45], [30, 45], [30, 42], [23, 42], [23, 23], [30, 23], [30, 20] ]) left_polygon = Polygon(vertices_1, closed=True, linewidth=2, edgecolor='black', facecolor='lightblue', alpha=0.7) ax.add_patch(left_polygon) vertices_2 = np.array([ [60, 20], [60, 23], [67, 23], [67, 42], [60, 42], [60, 45], [70, 45], [70, 20] ]) right_polygon = Polygon(vertices_2, closed=True, linewidth=2, edgecolor='black', facecolor='lightblue', alpha=0.7) ax.add_patch(right_polygon) Top_down_plate = Rectangle((25, 17), 40, 3, linewidth=2, edgecolor='black', facecolor='none') ax.add_patch(Top_down_plate) Top_up_plate = Rectangle((25, 45), 40, 3, linewidth=2, edgecolor='black', facecolor='none') ax.add_patch(Top_up_plate) # 添加标注 self._add_annotations(ax) # 添加标题 # ax.set_title('格构柱结构示意图', fontsize=16, pad=20) # plt.tight_layout() # plt.savefig('schematic_diagram.png', dpi=300, bbox_inches='tight', facecolor='white') # plt.close() return 'schematic_diagram.png' def _add_annotations(self, ax): """添加标注""" plate_size = self.params['plate_size'] tie_plate_spacing = self.params['tie_plate_spacing'] section_name = self.params['section_name'] # 绘制标注线 ax.axhline(y=130, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-') ax.axhline(y=120, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-') ax.axhline(y=80, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-') ax.axhline(y=70, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-') ax.axhline(y=75, xmin=5 / 100, xmax=25 / 100, color='red', linewidth=2, linestyle='-') ax.axhline(y=35, xmin=5 / 100, xmax=25 / 100, color='red', linewidth=2, linestyle='-') ax.axvline(x=79, ymin=70 / 150, ymax=130 / 150, color='red', linewidth=2, linestyle='-') # 添加标注文本 ax.text(75, 123, f"{plate_size[1] * 10}", fontsize=12, color='red', ha='center', rotation=90) ax.text(75, 100, f"{tie_plate_spacing * 10 - plate_size[1] * 10}", fontsize=12, color='red', ha='center', rotation=90) ax.text(75, 73, f"{plate_size[1] * 10}", fontsize=12, color='red', ha='center', rotation=90) ax.text(5, 77, f"-{plate_size[0] * 10}×{plate_size[1] * 10}×{plate_size[2] * 10}", fontsize=12, color='red', ha='center') ax.text(5, 37, f"[{section_name}", fontsize=12, color='red', ha='center') def generate_report(self, section_name, tie_plate_spacing, plate_size, steel_grade, gap, L, N, fd, filename="钢结构格构柱计算书.docx"): """生成完整计算书""" content = [] content.append("# 钢结构格构柱计算书") content.append(f"计算时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") content.append("---") # 稳定性计算 stability_content, stability_result = self.verify_stability( section_name, tie_plate_spacing, plate_size, steel_grade, gap, L, N, fd ) content.extend(stability_content) # 添加示意图 diagram_path = self.create_schematic_diagram() if diagram_path: content.append("## 六、结构示意图") content.append("") content.append("![格构柱示意图](schematic_diagram.png)") content.append("图1: 格构柱结构示意图") # 保存到文档 self._create_word_document(content, filename) return content def _create_word_document(self, content, filename): """创建Word文档""" try: from docx import Document from docx.shared import Inches doc = Document() for line in content: if line.startswith('# '): doc.add_heading(line[2:], level=0) elif line.startswith('## '): doc.add_heading(line[3:], level=1) elif line.startswith('### '): doc.add_heading(line[4:], level=2) elif line.startswith('![') and '](' in line: # 修改这里 # 提取图片路径 match = re.search(r'!\[.*\]\((.*?)\)', line) if match: image_path = match.group(1) if os.path.exists(image_path): doc.add_picture(image_path, width=Inches(4)) doc.add_paragraph("") # 添加空行 else: doc.add_paragraph(line) doc.save(filename) print(f"计算书已保存到 '{filename}'") except ImportError: with open(filename.replace('.docx', '.txt'), 'w', encoding='utf-8') as f: f.write("\n".join(content)) print(f"注意: docx库未安装,计算书已保存为文本文件 '{filename.replace('.docx', '.txt')}'") def show_schematic(self): """显示示意图""" diagram_path = self.create_schematic_diagram() if diagram_path and os.path.exists(diagram_path): img = plt.imread(diagram_path) plt.figure(figsize=(12, 10)) plt.imshow(img) plt.axis('off') plt.title('格构柱结构示意图', fontsize=16) plt.tight_layout() plt.show() def main(): """主函数""" calculator = SteelLacedColumnSystem() # 示例参数 params = { 'section_name': "28b", 'tie_plate_spacing': 83, 'plate_size': [26, 20, 1], 'steel_grade': "Q235B", 'gap': 26, 'L': 600, 'N': 1600, 'fd': 215 } # 生成计算书 content = calculator.generate_report(**params, filename="钢结构格构柱计算书.docx") # 显示示意图 calculator.show_schematic() # 在控制台输出 print("\n".join(content).replace("![图像]", "[图像]")) if __name__ == "__main__": main() 帮我看看这个完整的代码,帮我把word输出后的公式改一下格式,表示出如Ncrd的下标crd,并且把输出的计算书格式优化一下
最新发布
09-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值