生成无穷多解的增广矩阵
import operator
import numpy as np
import random
import sympy
from sympy import *
def setMat(long=4, wid=5, minNum=-5, maxNum=5, *args, **kwargs) -> Matrix:
"""
随机产生一个用minNum-maxNum数字构成的long行wid列的矩阵。
为了确保行阶梯矩阵里面不含分数,查看随机产生的矩阵的行阶梯里面有没有分数,
如果有,将分数取整,在对不含有分数的行阶梯矩阵进行任意次数的行变换得到最后的矩阵
:param long: 矩阵的行数
:param wid: 矩阵的列数
:param minNum: 最简矩阵包含的最小数
:param maxNum: 最简矩阵里包含的最大数
:param args:
:param kwargs:
:return: 返回一个矩阵
>>> setMat(2,3) #随机生成一个4行5列的行列式
>>> setMat(3,2) #随机生成一个行列式
"""
ranMat = Matrix(np.random.randint(minNum, maxNum, (long, wid))) # 随机产生一个用minNum-maxNum数字构成的long行wid列的矩阵
stepMat = ranMat.rref()[0] # stepMat是最简矩阵
for idx, x in np.ndenumerate(stepMat): # 确保行阶梯的矩阵
stepMat[idx[0] * stepMat.shape[1] + idx[1]] = int(stepMat[idx[0] * stepMat.shape[1] + idx[1]]) # 对行阶梯矩阵取整
if x < minNum or x > maxNum: # 确保矩阵中的数范围是minNum-maxNum之间的数
stepMat[idx[0] * stepMat.shape[1] + idx[1]] = sympy.Integer(random.randint(minNum, maxNum)) # 将矩阵中的行列式取整
for i in range(stepMat.shape[0] - 1): # 将得到的行最简的矩阵进行任意的行变换
a = list(stepMat.row(0))
n = random.randint(1, 3)
b = list(map(lambda x: x * n, stepMat.row(stepMat.shape[0] - 1)))
c = Matrix([np.sum([a, b], axis=0)])
stepMat.row_del(0)
stepMat = stepMat.row_insert(stepMat.shape[0] - 1, c)
for i in range(stepMat.shape[0] - 1): # 将得到的行最简的矩阵进行任意的行变换
a = list(stepMat.row(stepMat.shape[0] - 1))
n = random.randint(1, 3)
b = list(map(lambda x: x * n, stepMat.row(0)))
c = Matrix([np.sum([a, b], axis=0)])
stepMat.row_del(stepMat.shape[0] - 1)
stepMat = stepMat.row_insert(0, c)
return Matrix(stepMat)
为了增加计算的可行性,应该确保生成的longwid的随机矩阵的阶梯型和最简型尽可能的都是整数,所以先随机生成一个longwid的随机矩阵,然后求该随机矩阵的最简型stepMat,然后看该随机矩阵的最简型stepMat是否含有分数,若含有分数直接取整,最后将该最简型进行任意次的初等行变换变成一个任意的矩阵,这样就确保了生成随机的矩阵的最简型和阶梯型尽可能的没有分数,提高了计算的可行性。
def setNotHomEquation(long=4, wid=6, minNum=-2, maxNum=2, returnlist=False) -> Tuple:
"""
生成随机的无穷多解的增广矩阵增广矩阵
:param long:增广矩阵的行数
:param wid: 增光矩阵的列数
:param minNum: 增广矩阵中最小的数
:param maxNum: 增广矩阵中最大的数
:param returnlist: 是否返回列表
:return: (增广矩阵的系数,增广矩阵的值)
>>> setNotHomEquation()
"""
mat = setMat(long, wid, minNum, maxNum) # 生成一个long*wid的增广矩阵
mat2 = Matrix(np.array(mat)[:, :mat.shape[1] - 1]) # 截取增广矩阵的系数矩阵
mat3 = mat.col(mat.shape[1] - 1) # 截取增广矩阵的结果 and np.sum(np.array(mat3)==0)<long
if (mat.rank() < mat.shape[1] - 1 and mat.rank() == mat2.rank() and np.sum(
np.array(mat3) == 0) < long): # 判断非齐次方程是否有无穷多解,如果没有则重新生成
if returnlist:
mat = mat.tolist()
mat2 = mat2.tolist()
mat3 = mat3.tolist()
return [mat2, mat3]
else:
return (mat2, mat3)
else:
(mat2, mat3) = setNotHomEquation(long, wid, minNum, maxNum, returnlist)
return (mat2, mat3)
生成一个longwid的随机矩阵mat作为非齐次方程组的系数矩阵和1long的一维零矩阵作为结果矩阵,为了确保生成的非齐次方程组是无穷多解,利用矩阵的秩小于未知数矩阵并且增广矩阵等于系数矩阵有无穷多解的定理,确保生成的非齐次方程有无穷多解。