数学建模三剑客 MSN

2024-02-05 01:10
文章标签 建模 数学 三剑客 msn

本文主要是介绍数学建模三剑客 MSN,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(点击上方公号,快速关注我们)


作者:许向武


前言


不管是不是巴萨的球迷,只要你喜欢足球,就一定听说过梅西(Messi)、苏亚雷斯(Suarez)和内马尔(Neymar)这个MSN组合。在众多的数学建模辅助工具中,也有一个犀利无比的MSN组合,他们就是python麾下大名鼎鼎的 Matplotlib + Scipy + Numpy三剑客。


本文是我整理的MSN学习笔记,有些理解可能比较肤浅,甚至是错误的。如果因此误导了某位看官,在工作中造成重大失误或损失,我顶多只能赔偿一顿饭——还得是我们楼下的十元盒饭。特此声明。


文中代码均从我的这台时不时出点问题、闹个情绪的Yoga 3 pro上复制而来,这意味着所有的代码均可在下面的运行环境中顺利运行:


  • pyhton 2.7.8

  • numpy 1.11.1

  • scipy 0.16.1

  • matplotlib 1.5.1


三剑客之Numpy


numpy是一个开源的python科学计算库,包含了很多实用的数学函数,涵盖线性代数、傅里叶变换和随机数生成等功能。最初的numpy其实是scipy的一部分,后来才从scipy中分离出来。


numpy不是python的标准库,需要单独安装。假定你的运行环境已经安装了python包管理工具pip,numpy的安装就非常简单:


pip install numpy


数组对象


ndarray是多维数组对象,也是numpy最核心的对象。在numpy中,数组的维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。通常,一个numpy数组的所有元素都是同一种类型的数据,而这些数据的存储和数组的形式无关。


下面的例子,创建了一个三维的数组(在导入numpy时,一般都简写成np)。


import numpy as np

a = np.array([[1,2,3],[4,5,6],[7,8,9]])


数据类型


numpy支持的数据类型主要有布尔型(bool)、整型(integrate)、浮点型(float)和复数型(complex),每一种数据类型根据占用内存的字节数又分为多个不同的子类型。常见的数据类型见下表。


640?wx_fmt=png


创建数组


通常,我们用np.array()创建数组。如果仅仅是创建一维数组,也可以使用np.arange()或者np.linspace()的方法。np.zeros()、np.ones()、np.eye()则可以构造特殊的数据。np.random.randint()和np.random.random()则可以构造随机数数组。


640?wx_fmt=png


构造复杂数组


很多时候,我们需要从简单的数据结构,构造出复杂的数组。例如,用一维的数据生成二维格点。


重复数组: tile


640?wx_fmt=png


一维数组网格化: meshgrid


640?wx_fmt=png


指定范围和分割方式的网格化: mgrid


640?wx_fmt=png


上面的例子中用到了虚数。构造虚数的方法如下:


>>> complex(2,5)

(2+5j)


数组的属性


numpy的数组对象除了一些常规的属性外,也有几个类似转置、扁平迭代器等看起来更像是方法的属性。扁平迭代器也许是遍历多维数组的一个简明方法,下面的代码给出了一个例子。


640?wx_fmt=png


改变数组维度


numpy数组的存储顺序和数组的维度是不相干的,因此改变数组的维度是非常便捷的操作,除resize()外,这一类操作不会改变所操作的数组本身的存储顺序。


640?wx_fmt=png


索引和切片


对于一维数组的索引和切片,numpy和python的list一样,甚至更灵活。


640?wx_fmt=png


假设有一栋2层楼,每层楼内的房间都是3排4列,那我们可以用一个三维数组来保存每个房间的居住人数(当然,也可以是房间面积等其他数值信息)。


640?wx_fmt=png


数组合并


数组合并除了下面介绍的水平合并、垂直合并、深度合并外,还有行合并、列合并,以及concatenate()等方式。假如你比我还懒,那就只了解前三种方法吧,足够用了。


640?wx_fmt=png


数组拆分


拆分是合并的逆过程,概念是一样的,但稍微有一点不同:


640?wx_fmt=png


数组运算


数组和常数的四则运算,是数组的每一个元素分别和常数运算;数组和数组的四则运算则是两个数组对应元素的运算(两个数组有相同的shape,否则抛出异常)。


640?wx_fmt=png


特别提示:如果想对数组内符合特定条件的元素做特殊处理,下面的代码也许有用。


640?wx_fmt=png


数组方法和常用函数


数组对象本身提供了计算算数平均值、求最大最小值等内置方法,numpy也提供了很多实用的函数。为了缩减篇幅,下面的代码仅以一维数组为例,展示了这些方法和函数用法。事实上,大多数情况下这些方法和函数对于多维数组同样有效,只有少数例外,比如compress函数。


640?wx_fmt=png


矩阵对象


matrix是矩阵对象,继承自ndarray类型,因此含有ndarray的所有数据属性和方法。不过,当你把矩阵对象当数组操作时,需要注意以下几点:


  • matrix对象总是二维的,即使是展平(ravel函数)操作或是成员选择,返回值也是二维的

  • matrix对象和ndarray对象混合的运算总是返回matrix对象


创建矩阵


matrix对象可以使用一个Matlab风格的字符串来创建(以空格分隔列,以分号分隔行的字符串),也可以用数组来创建。


640?wx_fmt=png


矩阵的特有属性


矩阵有几个特有的属性使得计算更加容易,这些属性有:


640?wx_fmt=png


矩阵乘法


对ndarray对象而言,星号是按元素相乘,dot()函数则当作矩阵相乘。对于matrix对象来说,星号和dot()函数都是矩阵相乘。特别的,对于一维数组,dot()函数实现的是向量点乘(结果是标量),但星号实现的却不是差乘。


640?wx_fmt=png


线性代数模块


numpy.linalg 是numpy的线性代数模块,可以用来解决逆矩阵、特征值、线性方程组以及行列式等问题。


计算逆矩阵


尽管matrix对象本身有逆矩阵的属性,但用numpy.linalg模块求解矩阵的逆,也是非常简单的。


640?wx_fmt=png


计算行列式


如何计算行列式,我早已经不记得了,但手工计算行列式的痛苦,我依然记忆犹新。现在好了,你在手机上都可以用numpy轻松搞定(前提是你的手机上安装了python + numpy)。


m = np.mat('0 1 2; 1 0 3; 4 -3 8')

np.linalg.det(m)                # 什么?这就成了?

2.0


计算特征值和特征向量


截至目前,我的工作和特征值、特征向量还有没任何关联。记录这一节,纯粹是为了我女儿,她正在读数学专业。


640?wx_fmt=png


求解线性方程组


有线性方程组如下:


x – 2y + z = 0
2y -8z = 8
-4x + 5y + 9z = -9


求解过程如下:


640?wx_fmt=png


三剑客之Matplotlib


matplotlib 是python最著名的绘图库,它提供了一整套和Matlab相似的命令API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。matplotlib 可以绘制多种形式的图形包括普通的线图,直方图,饼图,散点图以及误差线图等;可以比较方便的定制图形的各种属性比如图线的类型,颜色,粗细,字体的大小等;它能够很好地支持一部分 TeX 排版命令,可以比较美观地显示图形中的数学公式。


pyplot介绍


Matplotlib 包含了几十个不同的模块, 如 matlab、mathtext、finance、dates 等,而 pyplot 则是我们最常用的绘图模块,这也是本文介绍的重点。


中文显示问题的解决方案


有很多方法可以解决此问题,但下面的方法恐怕是最简单的解决方案了(我只在windows平台上测试过,其他平台请看官自测)。


640?wx_fmt=png


绘制最简单的图形


>>> import numpy as np

>>> import matplotlib.pyplot as plt

>>> x = np.arange(0, 2*np.pi, 0.01)

>>> y = np.sin(x)

>>> plt.plot(x, y)

>>> plt.show()


640?wx_fmt=png


设置标题、坐标轴名称、坐标轴范围


如果你在python的shell中运行下面的代码,而shell的默认编码又不是utf-8的话,中文可能仍然会显示为乱码。你可以尝试着把 u’正弦曲线’ 写成 ‘正弦曲线’.decode(‘gbk’)或者‘正弦曲线’.decode(‘utf-8’)


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


设置点和线的样式、宽度、颜色


plt.plot函数的调用形式如下:


plot(x, y, color='green', linestyle='dashed', linewidth=1, marker='o', markerfacecolor='blue',markersize=6)

plot(x, y, c='g', ls='--', lw=1, marker='o', mfc='blue', ms=6)


  1. color指定线的颜色,可简写为“c”。颜色的选项为:

  • 蓝色: ‘b’ (blue)

  • 绿色: ‘g’ (green)

  • 红色: ‘r’ (red)

  • 墨绿: ‘c’ (cyan)

  • 洋红: ‘m’ (magenta)

  • 黄色: ‘y’ (yellow)

  • 黑色: ‘k’ (black)

  • 白色: ‘w’ (white)

  • 灰度表示: e.g. 0.75 ([0,1]内任意浮点数)

  • RGB表示法: e.g. ‘#2F4F4F’ 或 (0.18, 0.31, 0.31)

linestyle指定线型,可简写为“ls”。线型的选项为:

  • 实线: ‘-’ (solid line)

  • 虚线: ‘–’ (dashed line)

  • 虚点线: ‘-.’ (dash-dot line)

  • 点线: ‘:’ (dotted line)

  • 无: ”或’ ‘或’None’

linewidth指定线宽,可简写为“lw”。

marker描述数据点的形状

  • 点线: ‘.’

  • 点线: ‘o’

  • 加号: ‘+

  • 叉号: ‘x’

  • 上三角: ‘^’

  • 上三角: ‘v’

markerfacecolor指定数据点标记的表面颜色,可 简写为“ mfc”。

markersize指定数据点标记的大小,可 简写为“ ms”。


文本标注和图例


我们分别使用不同的线型、颜色来绘制以10、e、2为基的一组幂函数曲线,演示文本标注和图例的使用。


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


在绘制图例时,loc用于指定图例的位置,可用的选项有:


  • best

  • upper right

  • upper left

  • lower left

  • lower right


绘制多轴图


在介绍如何将多幅子图绘制在同一画板的同时,顺便演示如何绘制直线和矩形。我们可以使用subplot函数快速绘制有多个轴的图表。subplot函数的调用形式如下:


subplot(numRows, numCols, plotNum)


subplot将整个绘图区域等分为numRows行 * numCols列个子区域,然后按照从左到右,从上到下的顺序对每个子区域进行编号,左上的子区域的编号为1。如果numRows,numCols和plotNum这三个数都小于10的话,可以把它们缩写为一个整数,例如subplot(323)和subplot(3,2,3)是相同的。subplot在plotNum指定的区域中创建一个轴对象。如果新创建的轴和之前创建的轴重叠的话,之前的轴将被删除。


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


三剑客之Scipy


前面已经说过,最初的numpy其实是scipy的一部分,后来才从scipy中分离出来。scipy函数库在numpy库的基础上增加了众多的数学、科学以及工程计算中常用的库函数。例如线性代数、常微分方程数值求解、信号处理、图像处理、稀疏矩阵等等。由于其涉及的领域众多,我之于scipy,就像盲人摸大象,只能是摸到哪儿算哪儿。


插值


一维插值和二维插值,是我最常用的scipy的功能之一,也是最容易上手的。


一维插值和样条插值


下面的例子清楚地展示了线性插值和样条插值之后的数据形态。


640?wx_fmt=png


将原始数据以及线性插值和样条插值之后的数据绘制在一起,效果会比较明显:


640?wx_fmt=png


代码如下:


640?wx_fmt=png


特别说明:样条插值附带了很多默认参数,下面是简单的说明。详情请自行搜索。


scipy.interpolate.splrep(x, y, w=None, xb=None, xe=None, k=3, task=0, s=None, t=None, full_output=0,per=0, quiet=1)

# 参数s用来确定平滑点数,通常是m-SQRT(2m),m是曲线点数。如果在插值中不需要平滑应该设定s=0。splrep()输出的是一个3元素的元胞数组(t,c,k),其中t是曲线点,c是计算出来的系数,k是样条阶数,通常是3阶,但可以通过k改变。

scipy.interpolate.splev(x, tck, der=0)

# 其中的der是进行样条计算是需要实际计算到的阶数,必须满足条件der<=k


拟合


在工作中,我们常常需要在图中描绘某些实际数据观察的同时,使用一个曲线来拟合这些实际数据。所谓拟合,就是找出符合数据变化趋势的曲线方程,或者直接绘制出拟合曲线。


使用numpy.polyfit拟合


下面这段代码,基于Numpy模块,可以直接绘制出拟合曲线,但我无法得到曲线方程(尽管输出了一堆曲线参数)。这是一个值得继续深入研究的问题。


640?wx_fmt=png


3个拟合结果显示在下图中。


640?wx_fmt=png


640?wx_fmt=png


使用scipy.optimize.optimize.curve_fit拟合


scipy提供的拟合,貌似需要先确定带参数的曲线方程,然后由scipy求解方程,返回曲线参数。我们还是以上面的一组数据为例使用scipy拟合曲线。


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


可以看出,曲线近似正弦函数。构建函数y=a*sin(x*pi/6+b)+c,使用scipy的optimize.curve_fit函数求出a、b、c的值:


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


求解非线性方程(组)


在数学建模中,需要对一些稀奇古怪的方程(组)求解,Matlab自然是首选,但Matlab不是免费的,scipy则为我们提供了免费的午餐!scipy.optimize库中的fsolve函数可以用来对非线性方程(组)进行求解。它的基本调用形式如下:


fsolve(func, x0)


func(x)是计算方程组误差的函数,它的参数x是一个矢量,表示方程组的各个未知数的一组可能解,func返回将x代入方程组之后得到的误差;x0为未知数矢量的初始值。


我们先来求解一个简单的方程:sin(x)−cos(x)=0.2


>>> from scipy.optimize import fsolve

>>> import numpy as np

>>> def f(A):

    x = float(A[0])

    return [np.sin(x) - np.cos(x) - 0.2]

 

>>> result = fsolve(f, [1])

array([ 0.92729522])

>>> print result

[0.92729522]

>>> print f(result)

[2.7977428707082197e-09]


哈哈,易如反掌!再来一个方程组:


4x2−2sin(yz)=0

5y+3=0

yz−1.5=0


640?wx_fmt=png


图像处理


在scipy.misc模块中,有一个函数可以载入Lena图像——这副图像是被用作图像处理的经典示范图像。我只是简单展示一下在该图像上的几个操作。


  1. 载入Lena图像,并显示灰度图像

  2. 应用中值滤波扫描信号的每一个数据点,并替换为相邻数据点的中值

  3. 旋转图像

  4. 应用Prewitt滤波器(基于图像强度的梯度计算)


640?wx_fmt=png


640?wx_fmt=png


640?wx_fmt=png


后记


这篇博文自2016年9月初动笔,断断续续写了5个多月。延宕这么久,除了自身懒惰的原因外,主要是因为MSN这个主题涉及的内容太过繁杂,又极其晦涩,无论怎么努力,总怕挂一漏万、贻笑大方。


现在好了,终于写完了。倘若哪位看官发现了谬误,请自行修改,顺便通知我一声;若因此文受益而想约饭、约酒,请发邮件至:

xufive@gmail.com



【关于作者】


许向武:山东远思信息科技有限公司CEO,网名牧码人,齐国土著,太公之后。少小离家,独闯江湖,后归隐于华不注山。素以敲击键盘为业,偶尔游戏于各网络对局室,擅长送财送分,深为众棋友所喜闻乐见。


【关于投稿】


如果大家有原创好文投稿,请直接给公号发送留言。


① 留言格式:
【投稿】+《 文章标题》+ 文章链接

② 示例:
【投稿】《不要自称是程序员,我十多年的 IT 职场总结》:http://blog.jobbole.com/94148/


③ 最后请附上您的个人简介哈~



看完本文有收获?请转发分享给更多人

关注「Python开发者」,提升Python技能

640?wx_fmt=png

640?wx_fmt=jpeg

这篇关于数学建模三剑客 MSN的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/679354

相关文章

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

OCC开发_变高箱梁全桥建模

概述     上一篇文章《OCC开发_箱梁梁体建模》中详细介绍了箱梁梁体建模的过程。但是,对于实际桥梁,截面可能存在高度、腹板厚度、顶底板厚度变化,全桥的结构中心线存在平曲线和竖曲线。针对实际情况,通过一个截面拉伸来实现全桥建模显然不可能。因此,针对变高箱梁,本文新的思路来实现全桥建模。 思路 上一篇文章通过一个截面拉伸生成几何体的方式行不通,我们可以通过不同面来形成棱柱的方式实现。具体步骤

CSP-J基础之数学基础 初等数论 一篇搞懂(一)

文章目录 前言声明初等数论是什么初等数论历史1. **古代时期**2. **中世纪时期**3. **文艺复兴与近代**4. **现代时期** 整数的整除性约数什么样的整数除什么样的整数才能得到整数?条件:举例说明:一般化: 判断两个数能否被整除 因数与倍数质数与复合数使用开根号法判定质数哥德巴赫猜想最大公因数与辗转相除法计算最大公因数的常用方法:举几个例子:例子 1: 计算 12 和 18

2024年AMC10美国数学竞赛倒计时两个月:吃透1250道真题和知识点(持续)

根据通知,2024年AMC10美国数学竞赛的报名还有两周,正式比赛还有两个月就要开始了。计划参赛的孩子们要记好时间,认真备考,最后冲刺再提高成绩。 那么如何备考2024年AMC10美国数学竞赛呢?做真题,吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一。通过做真题,可以帮助孩子找到真实竞赛的感觉,而且更加贴近比赛的内容,可以通过真题查漏补缺,更有针对性的补齐知识的短板。