【数学建模学习笔记【集训十天】之第五天】


SymPy 学习

SymPy 是用于符号数学的 Python 库, 它旨在成为功能齐全的计算机代数系统。 SymPy
包括从基本符号算术到微积分,代数,离散数学和量子物理学的功能。【它可以在 LaTeX 中显示结果】

Pycharm终端安装命令:pip install sympy

符号运算又称计算机代数,通俗地讲就是用计算机推导数学公式,如对表达式进行因式分解、化简、微分、积分、解代数微分方程等。

与数值运算相比,符号计算存在以下的特点

  1. 运算以推理方式进行【因此不受截断误差和累积误差问题的影响】
  2. 符号计算的速度比较慢

SymPy符号运算库能够解简单的线性方程、非线性方程及简单的代数方程组
在SymPy中,提供了solve函数求解符号代数方程或方程组,其调用格式为: S=solve(f, *symbols) # f为符号方程(组),symbols为符号变量

综合应用:::

Rational值、pprint、平方根、SymPy 定义符号、sympy.abc模块、Symbol定义、SymPy 规范表达形式、SymPy 扩展代数表达式、SymPy 求值表达式、var函数定义符号变量

# -*- coding = utf-8 -*-
# @Time : 2022/7/1 9:50
# @Author : lxw_pro
# @File : SymPy 学习.py
# @Software : PyCharm


# Rational值
# SymPy 具有用于处理有理数的Rational

from sympy import Rational

r = Rational(1/2)
r2 = Rational(1/3)
r3 = Rational(1/4)

# 使用有理数
val = (r+r2+r3)*3   # 该表达形式为符号形式
print(val.evalf())  # 可使用evalf()方法对其进行求值

# 注:当不使用有理数时,输出中会有一个小错误


val2 = (1/2+1/3+1/4)*3
print(val2)     # 输出 3.25


print()
# pprint()
# pprint()用于在控制台上漂亮地打印输出
from sympy import pprint, Symbol, exp, sqrt, init_printing

# 对于某些字符,我们需要启用 unicode 支持
init_printing(use_unicode=True)

x = Symbol('x')

pf = sqrt(2)
pprint(pf)
print(pf)

print("="*20)

a = (exp(x)**2)/2
pprint(a)   # 程序会美化输出
print(a)


print()
# 平方根
# 平方根是一个数字,乘以它会产生指定的数量
from sympy import pprint, sqrt, Mul

x = sqrt(2)
y = sqrt(2)

pprint(Mul(x, y, evaluate=False))
print("=")
print(x * y)


print()
# SymPy 符号
# 符号计算适用于符号,以后可以对其进行求值。 使用符号之前,必须在 SymPy 中定义符号
from sympy import Symbol, symbols
from sympy.abc import x, y

fc = 2*x+3*y
print(fc)

# 可从sympy.abc模块导入符号
a = Symbol('a')
b = Symbol('b')

fc2 = a*b-a+b
print(fc2)

# 可用Symbol定义
i, j = symbols('i j')
fc3 = i*j-2+j*i*5
print(fc3)


print()
# SymPy 规范表达形式
# SymPy 会自动将表达式转换为规范形式
from sympy.abc import a, b

bds = a * b + 2 * a - a + b + 32 - b * a + (a+b)*6-9*b
print(bds)  # 简化


# SymPy 扩展代数表达式
# 使用expand(),我们可以扩展代数表达式【即该方法尝试消除幂和乘法】

from sympy import pprint, expand
from sympy.abc import x

ds = (x+1)**2
pprint(ds)

print('='*20)

# 简化
jh = expand(ds)
pprint(jh)


print()
# SymPy 简化表达式
# 可以使用simplify()将表达式更改为更简单的形式

from sympy import pprint, cos, sin, simplify
from sympy.abc import a

jhs = sin(x) / cos(x)
pprint(jhs)

print('='*20)

j = simplify(jhs)
print(j)


print()
# 比较两个表达式【】
from sympy import pprint, sin, cos, Symbol

x = Symbol('x')

a = cos(x)**2-sin(x)**2
b = cos(2*x)

print(a.equals(b))  # 输出 True

print(a == b)       # 输出 False


# SymPy 求值表达式
# 可以通过替换符号来求值表达式

from sympy import pi

print(pi.evalf(6))  # 代表保留6位数


from sympy import pprint
from sympy.abc import a, b

ba = a*b
print(ba.subs([(a, 3), (b, 2)]))    # 输出 6


print()
# 在SymPy库中,定义符号或符号函数的命令如下:
import sympy as sp
x, y, z = sp.symbols('x, y, z')     # 后面括号内可不用, 【定义符号变量x, y, z】

a, b = sp.symbols('a, b', cls=sp.Function)  # 定义多个符号函数

w = sp.Function('w')                # 定义符号函数


# 当然,也可以用var函数定义符号变量或符号函数,其格式如下:
import sympy as sp

sp.var('x, y, z')
sp.var('x y z')
sp.var('a, b', cls=sp.Function)


SymPy 求解方程

# -*- coding = utf-8 -*-
# @Time : 2022/7/1 15:30
# @Author : lxw_pro
# @File : SymPy 学习-2.py
# @Software : PyCharm


# SymPy求解方程
# 用solve()或solveset()求解方程
from sympy import Symbol, solve

x = Symbol('x')
sol = solve(x ** 2 - x, x)  # 求解x**2-x=0中的x

print(sol)      # 输出 [0, 1]


# 可将Eq用于公式
from sympy import pprint, Eq, solve, Symbol

s = Symbol('s')

eq = Eq(s**2-2, 2)      # 表示s**2-2=2
pprint(eq)

sol2 = solve(eq, s)
print(sol2)             # 输出 [-2, 2]


# 使用solveset(),可找到给定间隔的解决方案
from sympy import Symbol, pprint, Interval
from sympy.solvers import solveset

y = Symbol('y')

sol3 = solveset(y**2-4, y, Interval(0, 100))
print(sol3)             # 输出 {2}



SymPy 序列

  • 序列是其中允许重复的对象的枚举集合
  • 序列可以是有限的或无限的
  • 元素的数量称为序列的长度

与集合不同,同一元素可以在序列中的不同位置出现多次【元素的顺序很重要】

相关代码如下:



from sympy import pprint, sequence, summation
from sympy.abc import z

c = sequence(z, (z, 1, 10))
print(c)    # 输出  SeqFormula(z, (z, 1, 10))
pprint(c)   # 输出 [1, 2, 3, 4, …]
print(list(c))      # 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 序列的长度
print(c.length)     # 输出 10

# 求和
print(summation(c.formula, (z, c.start, c.stop)))   # 输出 55

print(sum(list(c)))                                 # 同上


SymPy 极限

# SymPy 极限
# 极限是函数(或序列)“接近”作为输入(或索引)“接近”某个值的值
from sympy import limit, oo     # oo表示无穷大
from sympy.abc import w

l1 = limit(1/w, w, oo)          # 计算1/w的极限【其中 w 接近正无穷大】
print(l1)   # 输出 0

l2 = limit(1/w, w, 0)           # 计算1/w的极限【其中 x 接近 0】
print(l2)   # 输出 oo



SymPy 矩阵

# SymPy 矩阵
# 在 SymPy 中,可使用矩阵。
# 矩阵是数字或其他数学对象的矩形数组,为其定义了运算
# 矩阵用于计算,工程或图像处理
from sympy import pprint, Matrix

M = Matrix([
    [2, 6, 1],
    [5, 2, 0],
    [1, 4, 5]
])

M2 = Matrix([1, 2, 3])
print(M)        # 输出 Matrix([[2, 6, 1], [5, 2, 0], [1, 4, 5]])
pprint(M)

print('='*20)

print(M*M2)     # 输出 Matrix([[17], [9], [24]])
pprint(M*M2)



SymPy 绘图

# SymPy 绘图
# SymPy 包含用于绘图的模块
# 它基于 Matplotlib 构建

from sympy.abc import l
import sympy as sp
from sympy.plotting import plot

plot(1/l)

运行结果如下:

在这里插入图片描述


1-解代数方程

# 题目描述:
'''
利用solve求下列符号代数方程的解。
ax**2+bx+c=0,其中x为未知数

'''

import sympy as sp

# 定义符号变量
a, b, c, x = sp.symbols('a, b, c, x')
xx = sp.solve(a*x**2+b*x+c, x)

print(xx)   # 输出 [(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]



2-求方程组的符号解

1234564564555656456

相关程序代码如下:

import sympy as sp

# x1, x2 = sp.var('x1, x2')
x1, x2 = sp.symbols('x1, x2')
s = sp.solve([x1**2+x2**2-1, x1-x2], [x1, x2])

print(s)    # 输出 [(-sqrt(2)/2, -sqrt(2)/2), (sqrt(2)/2, sqrt(2)/2)]


# 使用符号数组求解【方法二】
import sympy as sp

x = sp.var('x:2')   # 定义符号数组
S = sp.solve([x[0]**2+x[1]**2-1, x[0]-x[1]], x)     # 注意最外面的中括号

print(S)    # 输出 [(-sqrt(2)/2, -sqrt(2)/2), (sqrt(2)/2, sqrt(2)/2)]

3-求矩阵特征值和特征向量

在这里插入图片描述

相关程序代码如下:

import sympy as sp

jz = sp.Matrix([
    [0, 0, 0, 1],
    [0, 0, 1, 0],
    [0, 1, 0, 0],
    [1, 0, 0, 0]
])

print("特征值:", jz.eigenvals())   # 输出 {-1: 2, 1: 2}
print("特殊向量:\n", jz.eigenvects())

运行结果如下:

在这里插入图片描述


模型与算法学习:

欢迎关注:我的主页
学习笔记来源于哔哩哔哩上的教学视频,链接为:第10讲
线性规划模型_哔哩哔哩_bilibili

这里面的大佬讲得非常好,大家感兴趣的可以去看看!

在工程技术、经济管理、科学研究、军事作战训练及日常生活等众多领域,人们常常会遇到各种优化问题。例如,在生产经营中,我们总是希望制定最优的生产计划,充分利用已有的人力、物力资源,获得最大的经济效益;在运输问题中,我们总是希望设计最优的运输方案,在完成运输任务的前提下,力求运输成本最小等。【针对优化问题的数学建模问题也是数学建模竞赛中一类比较常见的问题,这样的问题常常可以使用数学规划模型进行研究。】
数学规划是运筹学的一个重要分支,而线性规划又是数学规划中的一部分主要内容。很多实际问题都可以归结为“线性规划”问题。线性规划有比较完善的理论基础和有效的求解方法,在实际问题中有极其广泛地应用。特别是随着计算机技术的飞速发展,线性规划的应用在深度和广度上有了极大的提高。

线性规划模型(LP):

考虑问题编写步骤

  1. 问题分析

  2. 模型假设

  3. 符号说明

  4. 模型建立

建立线性规划模型通常需要以下3个步骤:

  1. 分析问题,找出决策变量
  2. 根据问题所给条件,找出决策变量必须满足的一组线性等式或者不等式约束,即为约束条件
  3. 根据问题的目标,构造关于决策变量的一个线性函数,即为目标函数

线性规划模型的一般形式

max(min)z=c1x1+c2x2+...+cnxn

123
123456


【可行解:满足约束条件式的解,称为线性规划问题的可行解 】
【最大解:使目标函数式达到最大值的可行解】

灵敏度分析:

指对系统因周围条件变化显示出来的敏感程度的分析。

对于数学规划模型,一定要做灵敏度分析

1 线性规划模型相关代码如下:

# -*- coding = utf-8 -*-
# @Time : 2022/7/1 11:52
# @Author : lxw_pro
# @File : 线性规划-1.py
# @Software : PyCharm

from scipy import optimize as op
import numpy as np

c = np.array([3, 2, -5])
a = np.array([[5, -2, 1], [1, 3, -1]])
b = np.array([-3, 6])
yy = np.array([[1, 1, 1]])
by = np.array([5])
# 求解
da = op.linprog(c, a, b, yy, by)
print(da)
运行结果如下:

564585

Fun: 目标函数最小值
X: 最优解


整数规划模型(IP)

在人们的生产实践中,经常会遇到以下类型的问题:
用人单位在招聘员工时,要求所招聘的不同技术水平的员工数量必须为整数;汽车企业在制定生产计划时,要求所生产的不同类型的汽车数量必须为整数等等。

整数规划:要求一部分或全部决策变量必须取整数值的规划问题

从决策变量的取值范围来看,整数规划通常可以分为以下几种类型:

  • 纯整数规划:全部决策变量都必须取整数值的整数规划模型
  • 混合整数规划:决策变量中有一部分必须取整数值,另一部分可以不取整数值的整数规划模型
  • 0~1整数规划:决策变量只能取0或1的整数规划

特别地,如果一个线性规划模型中的部分货全部 决策变量取整数值,则称该线性规划模型为整数线性规划模型

4564545455
4545884545
数学模型:

1254


2 整数规划模型相关代码如下:

import cvxpy as cp

x = cp.Variable(6, integer=True)
obj = cp.Minimize(sum(x))

mx = [x[0]+x[5] >= 35, x[0]+x[1] >= 40,
      x[1]+x[2] >= 50, x[2]+x[3] >= 45,
      x[3]+x[4] >= 55, x[4]+x[5] >= 30,
      x >= 0]

wt = cp.Problem(obj, mx)
wt.solve(solver='GLPK_MI')
print('最优值为:', wt.value)
print('最优解为:', x.value)

如果运行错误的话,记得终端安装cvxopt
安装命令:pip install cvxopt

'''
快速修复1:如果安装python包CVXOPT(pip安装CVXOPT),

然后CVXPY可以使用开源的混合整数线性规划

求解器“GLPK”。如果您的问题是非线性的,那么您可以安装SCIP

(pip安装pyscipopt)。

快速修复2:可以显式指定solver='ECOS/u BB'。这可能导致

在不正确的解决方案中,不建议使用。

'''

2-2 利用Python求余数运算编写程序代码:

# 利用Python求余数运算编写程序代码:
import cvxpy as cp
import numpy as np

sz = np.array([35, 40, 50, 45, 55, 30])
x2 = cp.Variable(6, integer=True)
obj2 = cp.Minimize(sum(x2))
sm2 = [x >= 0]
for i in range(6):
    sm2.append(x2[(i-1) % 6] + x2[i] >= sz[i])
wt2 = cp.Problem(obj2, sm2)
wt2.solve(solver='GLPK_MI')

print('最优值:', wt2.value)
print('最优解:', x2.value)

请添加图片描述


总结:

*今天我又学习了处理Python数据分析的另一个库SymPy,一开始感觉没什么意思,可跟着跟着觉得还是挺不错的,虽然学点有点粗糙,但这并不影响我对它的喜欢。*啊哈哈,要是太喜欢,后面有时间了就准备细学!!!

上一章链接:【数学建模学习笔记【集训十天】之第四天】

每日一言:

我们一生中会和很多人相遇,有些人只是为了擦肩而过,有些人是等着一见如故。

持续更新中…

猜你喜欢

转载自blog.csdn.net/m0_66318554/article/details/125556546