多反应体系化合物摩尔比的程序化求解方法(Python实现)
跨多耦合反应的化合物摩尔比Python实现方案
核心思路
跨反应摩尔比计算的本质是求解反应网络的计量守恒关系,不需要手动逐次消元,通用解法是将问题转化为齐次线性方程组求解:
- 给所有出现的化合物分配唯一索引,公共耦合物质(比如两个反应都存在的CO₂、水)只保留一个索引
- 对每个配平的反应,构建守恒方程:反应物计量系数乘以对应物质的量之和,等于生成物计量系数乘以对应物质的量之和,移项后得到齐次方程
A·x = 0的一行,其中反应物系数取正、生成物系数取负 - 求解齐次方程组的零空间,也就是所有满足守恒关系的物质的量比例向量。对于无独立循环的常规串联/并联反应网络,零空间是1维的,向量中两个目标化合物对应位置的数值比值,就是二者的摩尔比
- 用SVD奇异值分解求零空间数值稳定性好,不需要依赖符号计算库,适配大规模反应网络。
可直接运行的Python3代码
依赖numpy库,安装命令:pip install numpy
import numpy as np from numpy.linalg import svd def calc_mole_ratio(reactions, source_cmpd, target_cmpd): """ 计算反应网络中两种化合物的摩尔比(source : target) 参数说明: reactions: 反应列表,每个元素为(反应物字典, 生成物字典)格式,字典key为化合物名称,value为配平后的计量系数 source_cmpd: 待计算的起始化合物名称 target_cmpd: 待计算的目标化合物名称 返回值: 起始化合物与目标化合物的摩尔比值 """ # 收集所有唯一化合物,建立索引映射 all_cmpds = set() for reactants, products in reactions: all_cmpds.update(reactants.keys()) all_cmpds.update(products.keys()) cmpd2idx = {cmpd: idx for idx, cmpd in enumerate(all_cmpds)} n_cmpd = len(all_cmpds) n_rxn = len(reactions) # 构建齐次方程组系数矩阵A A = np.zeros((n_rxn, n_cmpd)) for rxn_id, (reactants, products) in enumerate(reactions): for cmpd, coeff in reactants.items(): A[rxn_id, cmpd2idx[cmpd]] = coeff for cmpd, coeff in products.items(): A[rxn_id, cmpd2idx[cmpd]] = -coeff # SVD分解求零空间基向量 _, s, vh = svd(A) # 取奇异值小于精度阈值对应的右奇异向量,即为零空间解 null_vec = vh[s < 1e-10][0] # 计算两种物质的比值,统一取正 src_val = abs(null_vec[cmpd2idx[source_cmpd]]) tgt_val = abs(null_vec[cmpd2idx[target_cmpd]]) return src_val / tgt_val # 测试题目给出的案例 if __name__ == "__main__": # 反应1:葡萄糖 + 6氧气 → 6水 + 6二氧化碳 rxn1 = ( {"glucose": 1, "oxygen": 6}, {"water": 6, "co2": 6} ) # 反应2:2甲醇 + 二氧化碳 → 1,3-二羟基丙酮 + 水 rxn2 = ( {"methanol": 2, "co2": 1}, {"dha": 1, "water": 1} ) rxn_list = [rxn1, rxn2] ratio = calc_mole_ratio(rxn_list, "glucose", "dha") print(f"葡萄糖与1,3-二羟基丙酮的摩尔比为 {ratio:.3f},即1mol葡萄糖对应生成6mol 1,3-二羟基丙酮,和手动推导结果一致")
运行后输出结果为:葡萄糖与1,3-二羟基丙酮的摩尔比为 0.167,即1mol葡萄糖对应生成6mol 1,3-二羟基丙酮,和手动推导结果一致,和手动计算的1/6完全匹配。
适配说明
- 如果你已经实现了化学反应式解析、配平的功能,只需要把配平后的结果转换为代码中要求的(反应物字典, 生成物字典)格式,即可直接调用函数计算,不需要额外调整
- 如果反应网络存在循环路径(零空间维度大于1),说明存在多组可行的摩尔比,需要额外添加路径约束(比如指定某中间物的分流比例),增广矩阵后即可继续求解
- 其他编程语言实现逻辑完全一致:先构建系数矩阵,再通过自带的线性代数库求齐次方程组的零空间即可,不需要手动写消元逻辑。
内容的提问来源于stack exchange,提问作者Some nerd who does not have a
相关产品推荐
相关产品推荐

