自学内容网 自学内容网

【数学建模学习手册】第一章:解析方法与几何模型(一)

本专栏内容为:数学建模原理 记录学习数学建模

💓博主csdn个人主页:小小unicorn
⏩专栏分类:数学建模
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

前言

今天,人类社会正处在由工业化社会向信息化社会过渡的变革。以数字化为特征的信息社会有两个显著特点:计算机技术的迅速发展与广泛应用;数学的应用向一切领域渗透。随着计算机技术的飞速发展,科计算的作用越来越引起人们的广泛重视,它已经与科学理论和科学实验并列成为人们探索和研究自然界、人类社会的三大基本方法。为了适应这种社会的变革, 培养和造就出一批又一批适应高度信息化社会具有创新能力的高素质的工程技术和管理人才,在各高校开设“数学建模”课程,培养学生的科学计算能力和创新能力,就成为这种新形势下的历史必然。

数学建模是对现实世界的特定对象,为了特定的目的,根据特有的内在规律,对其进行必要的抽象、归纳、假设和简化,运用适当的数学工具建立的一个数学结构。数学建模就是运用数学的思想方法、数学的语言去近似地刻画一个实际研究对象,构建一座沟通现实世界与数学世界的桥梁, 并以计算机为工具应用现代计算技术达到解决各种实际问题的目的。建立一个数学模型的全过程称为数学建模。因此“数学建模”(或数学实验)课程教学对于开发学生的创新意识,提升人的数学素养,培养学生创造性地应用
数学工具解决实际问题的能力,有着独特的功能。

数学建模过程就是一个创造性的工作过程。 人的创新能力首先是创造性思维和具备创新的思想方法。数学本身是一门理性思维科学,数学教学正是通过各个教学环节对学生进行严格的科学思维方法的训练,从而引发人的灵感思维,达到培养学生的创造性思维的能力。同时数学又是一门实用科学,它具有能直接用于生产和实践,解决工程实际中提出的问题,推动生产力的发展和科学技术的进步。

学生通过参加数学建模活动,首先就要了解问题的实际背景,深入到具体学科领域的前沿,这就需要学生具有能迅速查阅大量科学资料,准确获得自己所需信息的能力;同时,不但要求学生必需了解现代数学各
门学科知识和各种数学方法,把所掌握的数学工具创造性地应用于具体的实际问题,构建其数学结构,还要求学生熟悉各种数学软件,熟练地把现代计算机技术应用于解决当前实际问题综合能力,最后还要具有把自己的实践过程和结果叙述成文字的写作能力。通过数学建模全过程的各个环节,学生们进行着创造性的思维活动,模拟了现代科学研究过程。通过“数学建模”课程的教学和数学建模活动极大地开发了学生的创造性思维
的能力,培养学生在面对错综复杂的实际问题时,具有敏锐的观察力和洞察力,以及丰富的想象力。

向量表示法

分析几何问题,在现在这个阶段我们所掌握的方法大体上可以分为三种:

传统几何的演绎-证明体系:

这种体系下的方法都是基于已经被证明了的公理与定理体系(例如勾股定理、正弦定理、圆幂定理等),在解决问题的过程中更强调分析而非计算,往往是通过构造辅助线、辅助平面等利用严密的逻辑推理步步为营推导出最后的结果。这种方法往往分析起来会更加困难,但减少了计算量。

基于向量的计算化几何:

向量被引入几何当中最初的目的是为了表示有向线段,但后来大家发现基于向量的一些运算特性可以把一些数量问题统一化。几何图形中的边长、角度、面积可以转化为向量的模长、内积等求解,平行、垂直等可以转化为向量共线、内积为0等求解,就可以把所有几何问题都变成可计算的问题。这样的方法更加重视计算,并且除了传统的几何向量外,还可以构造直角坐标系从而获得坐标向量,运算更加方便。

基于极坐标与方程的解析几何:

这种方法其实可以回溯到当初学圆锥曲线的时期,把几何图形的相交、相切、相离抽象成方程解的问题。后来又学习过极坐标和参数方程,就会发现利用极坐标和参数方程去表示曲线实在是太方便了。这样的方法就可以把几何问题转化成一个代数问题来求解,大大提高了求解的效率。

在中学阶段总能够总结出一些常见的公理与定理,例如:
在这里插入图片描述

向量表示与坐标代换

向量并不陌生,但是可能接触最多的是认识到三维,并且还依赖于画图,中学阶段我们也仅仅是接触到了三维向量。其实不然,一个向量可以有不止三个轴,可以有5维,有10维,有10000维,你现在还能依靠图理解向量吗?事实上向量的维数可以是很多维,从代数的意义上你可以认为向量是一个集合,从几何的意义上你又可以认为向量是一个n维欧几里得空间中的一个点:
在这里插入图片描述
和二维、三维空间中的向量一样,高维空间中的向量同样可以进行加减运算、数量乘运算和数乘运算。但毕竟这是一门应用数学课程,我们不打算把太多精力放在任何一本线代课本里面都能找到的公式上,使用 Python NumPy 库举例子恐怕会更加直观。从程序设计的角度来看,如果读者接触过C语言应该会了解数组的概念,而在 C++ 语言中STL里面已经包含了 vector 类型。在 Python 中我们可以使用 NumPy 库来创建和操作向量,例如:

import numpy as np
#创建变量
x = np.array([1, 2, 3, 5, 8])
# array([1, 2, 3, 5, 8])

引入向量的目的并不仅仅是为了在几何图形中更好地表示方向和距离,而是为了利用代数的方法来解决几何问题。向量提供了一种将几何概念转化为代数表达式的方式,从而使得几何问题的解决变得更加简单和直接。

例如,在解决物理问题时,力、速度和加速度等物理量都可以用向量表示。通过向量的加减和数乘运算,我们可以直接计算出合力、相对速度等结果,而不需要借助复杂的几何图形。在计算机图形学中,向量被广泛用于表示和处理图形和动画。通过向量运算,我们可以实现图形的旋转、缩放、平移等变换,以及计算光线的反射和折射等效果。

解析几何法的本质就是利用函数与方程来表示不同的几何曲线。在中学阶段我们都学习过圆锥曲线的方程形式,但在实际问题中我们面临的曲线会更加复杂。尤其是在三维空间中的曲线与曲面,可能会用到多元函数去进行表示,也可能用极坐标或参数方程更加方便,但不管怎么说,解析几何方法的本质就是把各种几何问题都转化为代数问题求解。解方程比起复杂的分析,更依靠计算,而这恰恰是程序所擅长的。

在数学中,坐标变换通常涉及到一系列的矩阵运算,这些矩阵描述了一个坐标系相对于另一个坐标系的位置和方向。旋转变换就是其中的一个典型例子。当我们说一个坐标系相对于另一个坐标系进行了旋转,我们通常是指它绕着一个轴或者点旋转了一定的角度。二维空间的旋转可以简化为点绕原点旋转,而三维空间则涉及到更复杂的轴向旋转。
在这里插入图片描述
在二维空间中,如果我们要将坐标系绕原点旋转一个角度,就可以通过旋转矩阵来实现。旋转矩阵是一个非常简单而又强大的工具,它可以将原始坐标系中的点通过线性变换映射到新坐标系中。对于逆时针旋转,二维旋转矩阵的形式是
在这里插入图片描述
这里, θ θ θ是旋转角度,当应用这个旋转矩阵于一个点 ( x , y ) (x,y) (x,y),它会给出新的坐标 ( x ′ , y ′ ) (x ′ ,y ′ ) (x,y)
这表示了原始点在新坐标系中的位置。

使用NumPy进行这样的变换非常简单。首先,我们创建一个表示点坐标的NumPy数组,然后创建表示旋转矩阵的二维数组。

通过对这两个数组进行点积运算(也就是矩阵乘法),我们就可以得到新的坐标,在Python中可以这样实现:

#二维直角坐标系
#设定旋转角度,以30度为例
#将30度转化为弧度
theta=np.radians(30)
#创建旋转矩阵
Rotation_matrix=np.array([
    [np.cos(theta),-np.sin(theta)],
    [np.sin(theta),np.cos(theta)]
    ])

#假设我们有一个点
a=5
b=3
point=np.array([a,b])
#t通过旋转得到这个点的坐标
rotated_point=Rotation_matrix.dot(point)

print("原坐标为:",point)
print("旋转后的坐标为:",rotated_point)
# 原坐标为: [5 3]
# 旋转后的坐标为: [2.83012702 5.09807621]

此示例代码中,旋转角度是预设的,你可以根据实际情况调整。通过这种方式,我们能够将几何问题通过坐标变换转化为代数问题,使用编程方法来进行高效的计算。这不仅仅适用于理论数学问题,同样也适用于工程、物理学、计算机图形学以及机器人技术等多个领域中。

在这里插入图片描述

在三维空间中,物体的旋转可以围绕三个主轴进行: x \mathrm{x} x轴, y \mathrm{y} y轴和 z \mathrm{z} z轴。这些轴旋转代表了不同方向的运动,并且可以通过旋转矩阵来数学描述。例如,一个点 P ( x , y , z ) P(x, y, z) P(x,y,z) z \mathrm{z} z轴旋转角度 α \alpha α可以表示为
在这里插入图片描述
这个旋转保持 z z z坐标不变,同时在 X Y XY XY平面上变换 x x x y y y坐标。相似地,点P绕 y y y轴旋转角度β的旋转矩阵为:

在这里插入图片描述
这个旋转保持 y y y坐标不变,同时在 X Z XZ XZ平面上变换 x x x z z z坐标。而点 P P P x x x轴旋转角度γ的旋转矩阵为
在这里插入图片描述
在这里插入图片描述
在实际应用中,如机器人学、航空航天和计算机图形学,旋转顺序对于模拟和预测物体如何移动至关重要。例如,飞机的姿态控制就极依赖于绕不同轴的旋转顺序,以精确地模拟和控制飞机的行动。在三维建模和动画制作中,这些旋转变换同样是创建动态、逼真场景的基础。

在Python中,利用NumPy库,我们可以使用如下代码片段来实现三维旋转变换:

#三维直角坐标系
#定义旋转角度,以弧度为单位
alpha=np.radians(30)#绕Z轴转动
beta=np.radians(45)#绕Y轴转动
gamma=np.radians(60)#绕X轴转动

#定义旋转矩阵
R_z=np.array([[np.cos(alpha),-np.sin(alpha),0],
              [np.sin(alpha),np.cos(alpha),0],
              [0,0,1]])
R_y=np.array([[np.cos(beta),0,np.sin(beta)],
              [0,1,0],
              [-np.sin(beta),0,np.cos(beta)]])
R_x=np.array([[1,0,0],
              [0,np.cos(gamma),-np.sin(gamma)],
              [0,np.sin(gamma),np.cos(gamma)]])

#总旋转矩阵
#@表示矩阵乘法
#按照Z轴、Y轴和X轴的顺序进行旋转,计算总的旋转矩阵
R=R_z @ R_y @ R_x
#定义点的坐标
P=np.array([1, 2, 3])
P_Rotated=R @ P

print("旋转后P点的坐标为:",P_Rotated)
# 旋转后P点的坐标为: [3.39062937 0.11228132 1.57829826]

在这里插入图片描述
正是通过这些准确的数学变换和编程实现,我们能够在计算机模拟和实际应用中处理复杂的三维空间问题。无论是设计复杂的机械系统、创建逼真的三维动画,还是开发高级的虚拟现实环境,三维旋转都是不可或缺的基础。

欧拉角图示:
在这里插入图片描述
欧拉角是三维空间中用于表示一个物体相对于一个固定坐标系(通常是参考坐标系或世界坐标系)的方向的一组角。这种表示方法定义了三次旋转,将物体从其初始方向旋转到期望方向。欧拉角通常表示为三个角度: α \alpha α β \beta β,和 γ \gamma γ分别对应于绕 z \mathrm{z} z轴, x \mathrm{x} x轴(或 y \mathrm{y} y轴),以及再次 y \mathrm{y} y轴(或 x \mathrm{x} x轴)的旋转。
欧拉角旋转顺序的不同,定义了不同的旋转方式,最常见的是:
在这里插入图片描述
每次旋转都是围绕变换后的轴,而不是初始的固定轴。这些旋转通常通过旋转矩阵进行计算,并且可以合成为一个单一的矩阵,它描述了总的旋转。在实际应用中,如飞行动力学和计算机图形学,欧拉角非常重要。

这里是Python中计算欧拉角旋转的代码示例,假设采用Z-Y-X顺序:

#欧拉角度:按照Z-Y-X

# 定义欧拉角(以弧度为单位)
alpha1 = np.radians(30)  # 绕 z 轴的 Yaw 角度
beta1 = np.radians(45)   # 绕 y 轴的 Pitch 角度
gamma1 = np.radians(60)  # 绕 x 轴的 Roll 角度

# 构建对应的旋转矩阵
R_Z = np.array([[np.cos(alpha1), -np.sin(alpha1), 0],
                [np.sin(alpha1), np.cos(alpha1), 0],
                [0, 0, 1]])
R_Y = np.array([[np.cos(beta1), 0, np.sin(beta1)],
                [0, 1, 0],
                [-np.sin(beta1), 0, np.cos(beta1)]])
R_X = np.array([[1, 0, 0],
                [0, np.cos(gamma1), -np.sin(gamma1)],
                [0, np.sin(gamma1), np.cos(gamma1)]])

# 总旋转矩阵,注意乘法的顺序
R1 = np.dot(R_X, np.dot(R_Y, R_Z))
print("组合旋转矩阵为:")
print(R1)
# 组合旋转矩阵为:
# [[ 0.61237244 -0.35355339  0.70710678]
#  [ 0.78033009  0.12682648 -0.61237244]
#  [ 0.12682648  0.9267767   0.35355339]]

当你运行这段代码,它会打印出综合所有三次旋转的旋转矩阵R。

Numpy与线性代数

在本节中,我们将探讨Python中最强大的科学计算库之一:NumPy。在深入学习之前,我们需要弄清楚线性代数在实际应用中的重要性。线性代数不仅是理解数据结构、解决数学问题的基础,也是计算机图形学、机器学习等高级领域不可或缺的工具。NumPy库在这里扮演了至关重要的角色,因为它为我们提供了一个高效、便捷的平台来处理数值计算和线性代数运算。接下来的内容,将通过实际的例子展示如何使用NumPy来执行一些基础但强大的线性代数操作。

Numpy与向量矩阵的操作

在科学计算的世界里,NumPy的数组对象是我们解决问题的得力助手。它能让我们轻松地执行向量化运算,这意味着可以一次性处理数据集而不需要使用循环。这种处理方式不仅代码更加简洁,而且运行速度也远快于传统的Python循环。在Numpy中,向量和矩阵都可以用二维数组表示,让我们来看看基本操作。

创建向量和矩阵

import numpy as np
#创建向量
vector=np.array([1,2,3,4,5,6])
#创建矩阵
matrix=np.array([[1,2,3],
                [4,5,6],
                [7,8,9]])
print(vector)
print(matrix)

在这里插入图片描述

向量和矩阵的基本属性

#向量和矩阵的基本属性
# 向量的维度
print(vector.shape) # (6, )
# 矩阵的维度
print(matrix.shape) # (3, 3)
# 矩阵的行数和列数
print(matrix.shape[0])  # 行数, 3
print(matrix.shape[1])  # 列数, 3

在这里插入图片描述

索引和切片

#索引和切片
# 索引
print(vector[0])  # 输出第一个元素, 1
print(matrix[1, 1])  # 输出第二行第二列的元素, 5

# 切片
print(vector[0:2])  # 输出前两个元素, [1, 2]
print(matrix[0:2, 0:2])  # 输出左上角的2x2子矩阵, [[1, 2], [4, 5]]

在这里插入图片描述

向量和矩阵的运算

#向量矩阵的运算
# 向量加法
vector1 = np.array([1, 2, 3])
vector2 = np.array([4, 5, 6])
print("向量加法")
print(np.add(vector1, vector2))
# [5, 7, 9]

# 矩阵乘法
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])
print("矩阵乘法结果:")
print(np.dot(matrix1, matrix2))  
# 或使用 matrix1 @ matrix2
print(matrix1@matrix2)
# [[19, 22],
#  [43, 50]]

在这里插入图片描述

利用Numpy进行线性代数基本运算

NumPy中,我们可以利用数组的广播机制来进行各种线性代数运算。例如,你可以轻松地将一个标量与一个向量或矩阵相乘,而不需要编写任何循环。NumPy也提供了计算矩阵的转置、行列式、逆矩阵等常见操作的函数。

import numpy as np
#利用Numpy进行线性代数基本运算
# 数量乘法示例
scalar = 5
scaled_vector = scalar * vector
print("数量乘法:")
print("Scaled vector:", scaled_vector)
# Scaled vector: [ 5 10 15]

# 矩阵的转置示例
transposed_matrix = matrix.T
print("矩阵转置:")
print("Transposed matrix:\n", transposed_matrix)
# Transposed matrix:
# [[1, 4, 7]
#  [2, 5, 8]
#  [3, 6, 9]]

# 计算行列式示例
matrix_determinant = np.linalg.det(matrix)
print("计算行列式:")
print("Matrix determinant:", matrix_determinant)
# Matrix determinant: 0.0

# 求解线性方程组示例
A = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
solution = np.linalg.solve(A, b)
print("线性方程组:")
print("Solution of the linear system:", solution)
# Solution of the linear system: [2. 3.]

在这里插入图片描述

numpy.linalg 的使用

最后,我们不能不提NumPy中的 linalg 子模块,它包含了一系列关于线性代数的函数。无论是求解方程组,还是计算特征值、特征向量,乃至执行奇异值分解,linalg 模块都能够提供帮助。通过这些工具,我们可以探索矩阵的深层属性,并应用于各种数学和工程问题。下面是一些 numpy.linalg 模块的使用示例:

计算逆矩阵

import numpy as np
# If the matrix is singular, use the pseudo-inverse
pseudo_inverse_matrix = np.linalg.pinv(matrix)
print("Pseudo-inverse of the matrix:")
print(pseudo_inverse_matrix)
# Pseudo-inverse of the matrix:
# [[-6.38888889e-01 -1.66666667e-01  3.05555556e-01]
#  [-5.55555556e-02  4.20756436e-17  5.55555556e-02]
#  [ 5.27777778e-01  1.66666667e-01 -1.94444444e-01]]

在这里插入图片描述

特征值和特征向量

#特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(matrix)
print("特征值:")
print(eigenvalues)
# [ 1.61168440e+01 -1.11684397e+00 -1.30367773e-15]
print("特征向量:")
print(eigenvectors)
# [[-0.23197069 -0.78583024  0.40824829]
#  [-0.52532209 -0.08675134 -0.81649658]
#  [-0.8186735   0.61232756  0.40824829]]

在这里插入图片描述

奇异值分解

#奇异值分解
U, S, V = np.linalg.svd(matrix)
print(U)
# [[-0.21483724  0.88723069  0.40824829]
#  [-0.52058739  0.24964395 -0.81649658]
#  [-0.82633754 -0.38794278  0.40824829]]
print(S)
# [1.68481034e+01 1.06836951e+00 4.41842475e-16]
print(V)
# [[-0.47967118 -0.57236779 -0.66506441]
#  [-0.77669099 -0.07568647  0.62531805]
#  [-0.40824829  0.81649658 -0.40824829]]

在这里插入图片描述

范数计算

#范数计算
norm = np.linalg.norm(vector)
print("范数计算:")
print(norm)
# 3.7416573867739413

在这里插入图片描述

使用Python解方程与方程组

在科学计算和工程应用中,经常会遇到需要求解方程或方程组的问题。Python提供了强大的数学库,如NumpySympy,可以帮助我们轻松地解决这些问题。

利用Numpy求线性方程(组)的数值解

Numpy是Python中一个用于数值计算的库,它提供了很多用于矩阵运算的功能。我们可以使用Numpy中的linalg.solve函数来解线性方程组。例如,我们有以下方程组:

10 x x x - y y y - 2 z z z=72,
- x x x + 10 y y y - 2 z z z=83,
- x x x - y y y + 5 z z z=432.
我们可以使用以下代码来求解这个方程组:

#求解方程组:
import numpy as np
a = np.array([[10, -1, -2], [-1, 10, -2], [-1, -1, 5]])
b = np.array([[72], [83], [42]])
c = np.linalg.solve(a, b)
print(c)
#[[11.]
# [12.]
# [13.]]

#此外,我们还可以使用矩阵的逆来求解方程组,即:
x = np.linalg.inv(a).dot(b)
print(x)
# [[11.]
# [12.]
# [13.]]

在这里插入图片描述

利用Sympy求方程(组)的解析解

SympyPython中一个用于符号计算的库,它可以提供方程的解析解,而不仅仅是数值解。什么是解析解和数值解呢?简单来说,解析解是指用数学符号(如x、y、𝜋等)表示的解,而数值解是指用具体的数字表示的解。

Sympy中,我们首先需要创建符号变量,然后使用 solve函数来求解方程或方程组。例如:

from sympy import symbols, solve, nonlinsolve

x, y = symbols('x y')
print(solve(x * 2 - 2, x))  # 解方程2x - 2 = 0
# [1]

print(solve([x + y - 35, x * 2 + y * 4 - 94], x, y))  # 解方程组x + y = 35, 2x + 4y = 94
# {x:23, y:12}

print(solve(x**2 + x - 20, x))  # 解方程x^2 + x - 20 = 0
# [-5, 4]

a, b, c, d = symbols('a b c d', real=True)
print(nonlinsolve([a**2 + a + b, a - b], [a, b]))  # 解非线性方程组a^2 + a + b = 0, a - b = 0
# {(-2, -2), (0, 0)}

在这里插入图片描述

具体案例:

以下是一个具体案例:
在这里插入图片描述
上图给出的是平面型Stewart平台示意图,它模拟一个操作装置,其中包括一个三角形( A B C ABC ABC)平台,平台位于一个由3个支柱( P 1 P_{1} P1, P 2 P_{2} P2 P 3 P_{3} P3)控制的固定平面中。图中的三角形( A B C ABC ABC)表示平面型Stewart平台,它的尺寸由3个长度 L 1 L_{1} L1 L 2 L_{2} L2 L 3 L_{3} L3确定。平台的位置由 3 3 3个支柱的可变长度的 3 3 3个参数 P 1 P_{1} P1 P 2 P_{2} P2 P 3 P_{3} P3所控制。需要解决的问题是,在给定一组参数 P 1 P_{1} P1 P 2 P_{2} P2 P 3 P_{3} P3的值后,计算出 A A A点的坐标 ( x , y ) (x, y) (x,y)和角度 θ \theta θ的值( θ \theta θ L 3 L_{3} L3 x x x轴的夹角)。请你完成:
在这里插入图片描述

定义问题的几何关系:

在这里插入图片描述

建立方程组:

在这里插入图片描述

解方程组以确定𝐴点坐标和角度 θ θ θ

在这里插入图片描述

利用Scipy求方程(组)的数值解:

在进行数值求解时,fsolve Scipy库中用于解决非线性方程组的一个非常有用的函数。它通常用于查找方程组的根,其中方程组可以是非线性的,并且不保证有解析解。接下来我们将会对例题进行求解。

首先,尝试使用 Sympy库解方程组时,我们发现问题无法解决。这是因为所面临的方程组可能没有简洁的解析解,或者是解析解超出了Sympy库的计算范围。以下是尝试解方程的代码和得到的结果:

from sympy import symbols, cos, sin, pi, nonlinsolve
import numpy as np
x, y, theta = symbols('x y theta', real=True)
L1, L2, L3 = 3, 3, 3
p1, p2, p3 = 5, 5, 3
x1, x2, y2 = 5, 0, 6
# 计算内角β
b = np.arccos((L2**2 + L3**2 - L1**2) / (2 * L2 * L3))
print(b)
# 尝试解方程组
solution = nonlinsolve([
    (x + L3 * cos(theta) - x1)**2 + (y + L3 * sin(theta))**2 - p1**2,
    x**2 + y**2 - p2**2,
    (x + L2 * cos(pi/3 + theta))**2 + (y + L2 * sin(pi/3 + theta) - y2)**2 - p3**2
], [x, y, theta])
print(solution)
# 1.0471975511965979

得到的输出表明,我们没有找到方程组的解析解。在这种情况下,我们转向数值解法,特别是Scipy库中的fsolve函数,来找到方程组的数值解。以下是使用fsolve的案例:

from scipy.optimize import fsolve
from math import sin, cos, pi
# 定义方程组
def equations(vars):
    x, y, theta = vars
    L1, L2, L3 = 3, 3, 3
    p1, p2, p3 = 5, 5, 3
    x1, x2, y2 = 5, 0, 6
    # 根据问题描述定义的方程
    eq1 = (x + L3*cos(theta) - x1)**2 + (y + L3*sin(theta))**2 - p2**2
    eq2 = x**2 + y**2 - p1**2
    eq3 = (x + L2*cos(pi/3 + theta))**2 + (y + L2*sin(pi/3 + theta) - y2)**2 - p3**2
    return [eq1, eq2, eq3]
# 初始猜测值
initial_guess = [-1.37, 4.80, 0.12]
# 使用fsolve求解方程组
result = fsolve(equations, initial_guess)
print(result)
# [1.15769945 4.86412705 0.02143414]

执行以上代码,我们得到了方程组的一组数值解。

上面的代码中,equations 函数定义了一个方程组,它接受一个变量列表(在这里是 x, y, 和 theta),然后返回一个方程组列表。然后,我们使用 fsolve 来求解这个方程组,并且提供了一个初始猜测值列initial_guess。fsolve会尝试找到这些方程的根,这意味着它会寻找满足方程组为零的 x, y, 和 theta的值。

Scipy 库中,除了 fsolve,还有其他几个函数可以用于解决类似的问题,比如:

  1. brentq bisection:这些函数是用于求解单变量方程的根的,适用于在指定区间内具有一个根的情况。
  2. root:这个函数提供了一个更加通用的接口来求解多变量方程组的根,它允许选择不同的算法,比如 hybr, lm, broyden1, 等等。
  3. newton:用于求解单变量方程的根,当你有方程的导数信息时特别有用。

对于复杂的方程组,尤其是当没有解析解时,使用数值方法通常是解决问题的可行方式。在使用数值方法时,很重要的一点是要有一个合理的初始猜测,因为这些方法很大程度上依赖于起始点,并且可能收敛到局部解,或者在某些情况下可能根本不收敛。


原文地址:https://blog.csdn.net/weixin_72066135/article/details/140176547

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!