化学方程式的平衡是一项常见活动。问题是:我们可以使这个过程自动化吗?
平衡方程的通用方法
假设您知道如何根据基本推论和一种猜测和检查过程(在大多数情况下非常有效)平衡化学方程式,要使该过程自动化,我们需要一种可推广使用的算法。 猜测和检查过程虽然有效,但由于每次策略可能有所不同,因此不容易推广。
相反,我们希望将化学方程式平衡问题视为线性方程组。让我们看一个基本的化学方程式,然后尝试一下。
我们的方程式涉及三个不同的元素。硒(Se),氯化物(Cl)和氧气(O)。我们要解决四个空白,可以将它们重新分配给变量x,y,z,t。
现在,我们可以组装一个向量。这个向量将与方程中有多少个元素一样长,对于每个项,我们将使用该向量来记录[在项中]存在哪些元素以及有多少个元素。
现在,我们有一个线性方程的方程。然后,我们可以将等式右侧的组合移到左侧。这将使箭头右侧的向量为负(等同于使变量为负)。
我们可以轻松地将其转换为等价的矩阵方程组,形式为Ax = b。
现在,求解系数x,y,z和t只是找到一个最佳零空间向量x的问题,该向量不包含任何零(在平衡问题中不能有零系数)或小数(不能有半摩尔),并且要尽可能小。 这是编码问题的难点。
Python分析方程式
我们可以将该系统编码为Python,而问题则分为几个不同的部分。我将使用伪代码来解释我的方法。
该问题可以分为两个主要阶段。解析输入,然后使用线性代数求解系数x。
解析输入
第一个障碍是解析输入。 为了使事情变得方便并让人联想到化学方程式本身,我使输入内容尽可能接近真实的事物。 唯一的警告是,下标变成了更大的数字(您不能输入下标),因此下标由元素后面的数字表示。
另一个警告是,与现实方程式不同,即使您有一个原子,也只表示为“ 1”,输入解析阶段就会容易得多。
最后要注意的是,在多原子内部不能写任何数字。 即使多原子离子内部经常有下标表示它们中某些元素的出现量,但我们仅允许总下标说明存在多少个多原子。
然后,开始编程。
在解析阶段结束时,目标是拥有所有向量,这些向量现在已经存储在向量termvectors列表中。
解x
现在,我们可以通过将术语向量中的向量连接到一个大矩阵A中,创建与所有其他术语向量大小相同的零向量,并求解x的零空间,来快速组装矩阵。
问题是-现在我们有了零空间矢量(定义矩阵零空间的矢量,它们可能不是好的答案。它们要么包含负值,在我们的上下文中是非法的。更常见的是它们将包含非整数) 例如,在我们的运行示例中,空空间矢量(在这种情况下为单个,因为我们只有一个从属列)看起来像:
上述右侧是实际的nullspace numpy ndarray。
因此,在大多数情况下,初始零空间矢量不是我们系数的答案。
关于零空间向量的事情是它们构成了零空间的基础。 这意味着零空间中的任何向量(包括我们所需的答案)都可以表示为零空间基向量的线性组合,其由matrix.nullspace()给出。
因此,现在,我们正在搜索哪些系数需要乘以零空间矩阵,以得到输出答案。
最重要的是为系数的最佳答案提出一个定义。我们知道他们:
必须仅包含整数
只能包含正数
不能包含0
但这意味着我们最佳答案的任何倍数仍将满足标准。即使多个系数在技术上平衡了该方程,也不能以最有效的方式进行平衡。
因此,我们要做的是找到满足所有条件的最小向量。 我们使用范数来衡量矢量的大小(考虑矢量在整个空间中的长度)。 那里有很多很多不同类型的规范,但是我们可能会使用最标准的L2范数。 通常使用某些.norm()命令为大多数软件包预设。
本文完整代码
详情参阅 - 亚图跨际