当系数未知(但仍然是实数)时如何求解 Python 中的线性方程组
How to solve a Linear System of Equations in Python When the Coefficients are Unknown (but still real numbers)
我不是程序员所以请放轻松!我有一个由 4 个线性方程和 4 个未知数组成的系统,我想我可以使用 python 来相对轻松地求解。然而,我的方程式不是“ 5x+2y+z-w=0 ”的形式,而是我有代数常数 c_i ,我不知道它的明确数值,例如“ c_1 x + c_2 y + c_3 z+ c_4w=c_5 " 将是我的四个方程之一。那么是否存在根据 c_i 给出 x,y,z,w 答案的求解器?
Numpy 有一个函数可以解决这个问题:numpy.linalg.solve
要构造矩阵,我们首先需要消化字符串,将其转化为系数和解的数组。
查找数字
首先我们需要编写一个函数,它接受一个字符串,如“c_1 3”和 returns 数字 3.0。根据您在输入字符串中所需的格式,您可以遍历此数组中的所有字符并在找到非数字字符时停止,或者您可以简单地拆分 space 并解析第二个字符串。以下是两种解决方案:
def find_number(sub_expr):
"""
Finds the number from the format
number*string or numberstring.
Example:
3x -> 3
4*x -> 4
"""
num_str = str()
for char in sub_expr:
if char.isdigit():
num_str += char
else:
break
return float(num_str)
或更简单的解决方案
def find_number(sub_expr):
"""
Returns the number from the format "string number"
"""
return float(sub_expr.split()[1])
Note: See edits
获取矩阵
现在我们可以用它把每个表达式分成两部分:解和用“=”表示的方程。然后等式被“+”拆分为sub_expressions 这样我们最终将字符串“3x+4y = 3”变成
sub_expressions = ["3x", "4y"]
solution_string = "3"
然后每个子表达式都需要输入到我们的 find_numbers
函数中。最终结果可以附加到系数和解矩阵:
def get_matrices(expressions):
"""
Returns coefficient_matrix and solutions from array of string-expressions.
"""
coefficient_matrix = list()
solutions = list()
last_len = -1
for expression in expressions:
# Note: In this solution all coefficients must be explicitely noted and must always be in the same order.
# Could be solved with dicts but is probably overengineered.
if not "=" in expression:
print(f"Invalid expression {expression}. Missing \"=\"")
return False
try:
c_string, s_string = expression.split("=")
c_strings = c_string.split("+")
solutions.append(float(s_string))
current_len = len(c_strings)
if last_len != -1 and current_len != last_len:
print(f"The expression {expression} has a mismatching number of coefficients")
return False
last_len = current_len
coefficients = list()
for c_string in c_strings:
coefficients.append(find_number(c_string))
coefficient_matrix.append(coefficients)
except Exception as e:
print(f"An unexpected Runtime Error occured at {coefficient}")
print(e)
exit()
return coefficient_matrix, solutions
现在让我们编写一个简单的主函数来测试这段代码:
# This is not the code you want to copy-paste
# Look further down.
from sys import argv as args
def main():
expressions = args[1:]
matrix, solutions = get_matrices(expressions)
for row in matrix:
print(row)
print("")
print(solutions)
if __name__ == "__main__":
main()
让我们运行控制台中的程序!
user:$ python3 solve.py 2x+3y=4 3x+3y=2
[2.0, 3.0]
[3.0, 3.0]
[4.0, 2.0]
您可以看到程序正确识别了我们所有的号码
AGAIN: use the find_number function appropriate for your format
拼凑
现在只需将这些矩阵直接泵入 numpy 函数即可:
# This is the main you want
from sys import argv as args
from numpy.linalg import solve as solve_linalg
def main():
expressions = args[1:]
matrix, solutions = get_matrices(expressions)
coefficients = solve_linalg(matrix, solutions)
print(coefficients)
# This bit needs to be at the very bottom of your code to load all functions first.
# You could just paste the main-code here, but this is considered best-practice
if __name__ == '__main__':
main()
现在让我们测试一下:
$ python3 solve.py x*2+y*4+z*0=20 x*1+y*1+z*-1=3 x*2+y*2+z*-3=3
[2. 4. 3.]
如您所见,程序现在为我们解决了这些功能。
出于好奇:数学作业?这感觉就像数学作业。
编辑:在所有测试中出现了一个拼写错误“c_string”而不是“c_strings”,这完全是运气。
编辑 2:经过进一步检查,我建议用“*”分隔子表达式:
def find_number(sub_expr):
"""
Returns the number from the format "string number"
"""
return float(sub_expr.split("*")[1])
这会产生相当可读的输入字符串
我不是程序员所以请放轻松!我有一个由 4 个线性方程和 4 个未知数组成的系统,我想我可以使用 python 来相对轻松地求解。然而,我的方程式不是“ 5x+2y+z-w=0 ”的形式,而是我有代数常数 c_i ,我不知道它的明确数值,例如“ c_1 x + c_2 y + c_3 z+ c_4w=c_5 " 将是我的四个方程之一。那么是否存在根据 c_i 给出 x,y,z,w 答案的求解器?
Numpy 有一个函数可以解决这个问题:numpy.linalg.solve
要构造矩阵,我们首先需要消化字符串,将其转化为系数和解的数组。
查找数字
首先我们需要编写一个函数,它接受一个字符串,如“c_1 3”和 returns 数字 3.0。根据您在输入字符串中所需的格式,您可以遍历此数组中的所有字符并在找到非数字字符时停止,或者您可以简单地拆分 space 并解析第二个字符串。以下是两种解决方案:
def find_number(sub_expr):
"""
Finds the number from the format
number*string or numberstring.
Example:
3x -> 3
4*x -> 4
"""
num_str = str()
for char in sub_expr:
if char.isdigit():
num_str += char
else:
break
return float(num_str)
或更简单的解决方案
def find_number(sub_expr):
"""
Returns the number from the format "string number"
"""
return float(sub_expr.split()[1])
Note: See edits
获取矩阵
现在我们可以用它把每个表达式分成两部分:解和用“=”表示的方程。然后等式被“+”拆分为sub_expressions 这样我们最终将字符串“3x+4y = 3”变成
sub_expressions = ["3x", "4y"]
solution_string = "3"
然后每个子表达式都需要输入到我们的 find_numbers
函数中。最终结果可以附加到系数和解矩阵:
def get_matrices(expressions):
"""
Returns coefficient_matrix and solutions from array of string-expressions.
"""
coefficient_matrix = list()
solutions = list()
last_len = -1
for expression in expressions:
# Note: In this solution all coefficients must be explicitely noted and must always be in the same order.
# Could be solved with dicts but is probably overengineered.
if not "=" in expression:
print(f"Invalid expression {expression}. Missing \"=\"")
return False
try:
c_string, s_string = expression.split("=")
c_strings = c_string.split("+")
solutions.append(float(s_string))
current_len = len(c_strings)
if last_len != -1 and current_len != last_len:
print(f"The expression {expression} has a mismatching number of coefficients")
return False
last_len = current_len
coefficients = list()
for c_string in c_strings:
coefficients.append(find_number(c_string))
coefficient_matrix.append(coefficients)
except Exception as e:
print(f"An unexpected Runtime Error occured at {coefficient}")
print(e)
exit()
return coefficient_matrix, solutions
现在让我们编写一个简单的主函数来测试这段代码:
# This is not the code you want to copy-paste
# Look further down.
from sys import argv as args
def main():
expressions = args[1:]
matrix, solutions = get_matrices(expressions)
for row in matrix:
print(row)
print("")
print(solutions)
if __name__ == "__main__":
main()
让我们运行控制台中的程序!
user:$ python3 solve.py 2x+3y=4 3x+3y=2
[2.0, 3.0]
[3.0, 3.0]
[4.0, 2.0]
您可以看到程序正确识别了我们所有的号码
AGAIN: use the find_number function appropriate for your format
拼凑
现在只需将这些矩阵直接泵入 numpy 函数即可:
# This is the main you want
from sys import argv as args
from numpy.linalg import solve as solve_linalg
def main():
expressions = args[1:]
matrix, solutions = get_matrices(expressions)
coefficients = solve_linalg(matrix, solutions)
print(coefficients)
# This bit needs to be at the very bottom of your code to load all functions first.
# You could just paste the main-code here, but this is considered best-practice
if __name__ == '__main__':
main()
现在让我们测试一下:
$ python3 solve.py x*2+y*4+z*0=20 x*1+y*1+z*-1=3 x*2+y*2+z*-3=3
[2. 4. 3.]
如您所见,程序现在为我们解决了这些功能。
出于好奇:数学作业?这感觉就像数学作业。
编辑:在所有测试中出现了一个拼写错误“c_string”而不是“c_strings”,这完全是运气。
编辑 2:经过进一步检查,我建议用“*”分隔子表达式:
def find_number(sub_expr):
"""
Returns the number from the format "string number"
"""
return float(sub_expr.split("*")[1])
这会产生相当可读的输入字符串