2022中青杯A题-高校数学建模竞赛与课程Sz教育

高校数学建模竞赛与课程SZ教育

题目叙述

在这里插入图片描述
在这里插入图片描述

模型的建立与求解

研究现状

层次分析加数据可视化图表
  相比其他大学数学课程,数学建模的教学内容和教学过程包含了更多sz元素。原因之一是其教学内容主要来源于学生们感同身受的实际生活,因而容易得到学生的认同;另一方面,数学建模的教学要求学生们亲自动手进行实践,克服了其他数学教学环节纸上谈兵的弊端,容易使sz思想深入人心。数学建模在sz教育中的独特作用体现在以下几个方面。
  理想的数学模型往往不是一蹴而就的,是通过千难万苦不断试错和检验,才最终被抽象概括出来,形成在工程技术领域应用广泛的数学模型。例如英国经济学家马尔萨斯于1798年提出了人口按照几何级数增长的人口模型。荷兰生物学家韦吕勒在19世纪中叶发展了马尔萨斯模型,提出来了一种阻滞增长模型,更加客观地描述人口和许多物种数量的变化规律。如今,传染病研究人员为了利用人口理论研究传染病的传播,进一步发展了韦吕勒的结果,使得这一理论得到进一步发展。
  建模求解过程需要学生综合运用数学知识、计算机编程、信息搜索等过程来得到数学模型的解,是整个数学建模过程最有传统数学味道的过程。由于数学建模实践作业或者竞赛往往有时间限制,学生们要在速度和准确性之间达到平衡,太慢了无法在规定时间完成项目,而一味追求速度,则可能在中间换接出错,导致所有建模过程从头再来。通过数学建模的求解过程,学生们能够体会到欲速则不达的道理,踏踏实实,一步一个脚印地推进项目的进展,在这个过程中培养自己的耐心和毅力。

发展趋势

灰色预测

在这里插入图片描述

程序代码

from decimal import *


class GM11():
    def __init__(self):
        self.f = None

    def isUsable(self, X0):
        '''判断是否通过光滑检验'''
        # 条件判断及循环
        X1 = X0.cumsum()
        rho = [X0[i] / X1[i - 1] for i in range(1, len(X0))]
        rho_ratio = [rho[i + 1] / rho[i] for i in range(len(rho) - 1)]
        print("rho:", rho)
        print("rho_ratio:", rho_ratio)
        flag = True
        for i in range(2, len(rho) - 1):
            if rho[i] > 0.5 or rho[i + 1] / rho[i] >= 1:
                flag = False
        if rho[-1] > 0.5:
            flag = False
        if flag:
            print("数据通过光滑校验")
        else:
            print("该数据未通过光滑校验")

        '''判断是否通过级比检验'''
        lambds = [X0[i - 1] / X0[i] for i in range(1, len(X0))]
        X_min = np.e ** (-2 / (len(X0) + 1))
        X_max = np.e ** (2 / (len(X0) + 1))
        for lambd in lambds:
            if lambd < X_min or lambd > X_max:
                print('该数据未通过级比检验')
                return
        print('该数据通过级比检验')

    def train(self, X0):
        X1 = X0.cumsum()
        Z = (np.array([-0.5 * (X1[k - 1] + X1[k]) for k in range(1, len(X1))])).reshape(len(X1) - 1, 1)
        # 数据矩阵A、B
        A = (X0[1:]).reshape(len(Z), 1)
        B = np.hstack((Z, np.ones(len(Z)).reshape(len(Z), 1)))
        # 求灰参数
        a, u = np.linalg.inv(np.matmul(B.T, B)).dot(B.T).dot(A)
        u = Decimal(u[0])
        a = Decimal(a[0])
        print("灰参数a:", a, ",灰参数u:", u)
        self.f = lambda k: (Decimal(X0[0]) - u / a) * np.exp(-a * k) + u / a

    def predict(self, k):
        X1_hat = [float(self.f(k)) for k in range(k)]
        X0_hat = np.diff(X1_hat)
        X0_hat = np.hstack((X1_hat[0], X0_hat))
        return X0_hat

    def evaluate(self, X0_hat, X0):
        '''
        根据后验差比及小误差概率判断预测结果
        :param X0_hat: 预测结果
        :return:
        '''
        S1 = np.std(X0, ddof=1)  # 原始数据样本标准差
        S2 = np.std(X0 - X0_hat, ddof=1)  # 残差数据样本标准差
        C = S2 / S1  # 后验差比
        Pe = np.mean(X0 - X0_hat)
        temp = np.abs((X0 - X0_hat - Pe)) < 0.6745 * S1
        p = np.count_nonzero(temp) / len(X0)  # 计算小误差概率
        print("原数据样本标准差:", S1)
        print("残差样本标准差:", S2)
        print("后验差比:", C)
        print("小误差概率p:", p)


if __name__ == '__main__':
    import matplotlib.pyplot as plt
    import numpy as np

    plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

    # 原始数据X
    X = np.array(
        [21.2, 22.7, 24.36, 26.22, 28.18, 30.16, 32.34, 34.72, 37.3, 40.34, 44.08, 47.92, 51.96, 56.02, 60.14,
         64.58,
         68.92, 73.36, 78.98, 86.6])
    # 训练集
    X_train = X[:int(len(X) * 0.7)]
    # 测试集
    X_test = X[int(len(X) * 0.7):]

    model = GM11()
    model.isUsable(X_train)  # 判断模型可行性
    model.train(X_train)  # 训练
    Y_pred = model.predict(len(X))  # 预测
    Y_train_pred = Y_pred[:len(X_train)]
    Y_test_pred = Y_pred[len(X_train):]
    score_test = model.evaluate(Y_test_pred, X_test)  # 评估

    # 可视化
    plt.grid()
    plt.plot(np.arange(len(X_train)), X_train, '->')
    plt.plot(np.arange(len(X_train)), Y_train_pred, '-o')
    plt.legend(['授课人数实际值', '灰色预测模型预测值'])
    plt.title('训练集')
    plt.show()

    plt.grid()
    plt.plot(np.arange(len(X_test)), X_test, '->')
    plt.plot(np.arange(len(X_test)), Y_test_pred, '-o')
    plt.legend(['授课人数实际值', '灰色预测模型预测值'])
    plt.title('测试集')
    plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值