• 2023年高教杯数学建模2023B题解析(仅从代码角度出发)


    前言

    最近博主正在和队友准备九月的数学建模,在做往年的题目,博主主要是负责数据处理,运算以及可视化,这里分享一下自己部分的工作,相关题目以及下面所涉及的代码后续我会作为资源上传

    问题求解

    第一题

    第一题的思路主要如下:
    在这里插入图片描述
    在这里插入图片描述
    如果我们基于代码实现的话,代码应该是这样的:

    # 导入相关第三方包
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import math
    
    # 生成测线距离中心点处的距离
    list1=[]
    d=200
    
    for i in range(-800,1000,200):
        list1.append(i)
    df=pd.DataFrame(list1,columns=["测线距离中心点处的距离"])
    
    #计算海水深度和覆盖宽度
    degree1 = 1.5 
    radian1 = degree1 * (math.pi / 180)
    df["海水深度"]=(70-df["测线距离中心点处的距离"]*math.tan(radian1))
    df["海水深度"]=df["海水深度"].round(2)
    degrees2 = 120/2
    radian2 = degrees2 * (math.pi / 180)
    df["覆盖宽度"]=(df["海水深度"]*math.sin(radian2)/math.cos(radian2+radian1))+(df["海水深度"]*math.sin(radian2)/math.cos(radian2-radian1))
    df["覆盖宽度"]=df["覆盖宽度"].round(2)
    
    # 计算重叠率
    leftlist=df["海水深度"]*math.sin(radian2)*1/math.cos(radian1+radian2)
    rightlist=df["海水深度"]*math.sin(radian2)*1/math.cos(radian1-radian2)
    leftlist=leftlist.round(2)
    rightlist=rightlist.round(2)
    leftlist=leftlist.tolist()
    leftlist=leftlist[1:]
    rightlist=rightlist.tolist()
    rightlist=rightlist[:8]
    heights = df["覆盖宽度"].tolist()
    heights=heights[:8]
    list2=[0]
    for i in range(0,8):
        a=(1-200/((leftlist[i]+rightlist[i])*math.cos(radian1)))
        list2.append(a*100)
    
    df["重叠率"]=list2
    df.to_excel("2023B题1.xlsx",index=False)
    

    这样我们就基本上完成了对相关数据的求解,然后我们可以实现一下对于它的可视化,代码与相关结果如下:

    plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    
    
    # Plotting sea depth
    plt.figure(figsize=(10, 6))
    plt.plot(df["测线距离中心点处的距离"], df["海水深度"], marker='o', linestyle='-', color='b', label='海水深度')
    
    # Plotting coverage width
    plt.plot(df["测线距离中心点处的距离"], df["覆盖宽度"], marker='o', linestyle='-', color='g', label='覆盖宽度')
    
    # Plotting overlap rate
    plt.plot(df["测线距离中心点处的距离"], df["重叠率"], marker='o', linestyle='-', color='r', label='重叠率')
    
    # Adding labels and title
    plt.xlabel('测线距离中心点处的距离')
    plt.ylabel('海水深度 / 覆盖宽度 / 重叠率')
    plt.title('海水深度、覆盖宽度和重叠率随距离变化的折线图')
    plt.legend()
    
    # Display plot
    plt.grid(True)
    plt.tight_layout()
    plt.show()
    

    在这里插入图片描述

    第二题

    第二题的思路主要是下面的式子:
    在这里插入图片描述
    博主的求解代码基本如下:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import math
    
    # 生成相关数据
    list1=[]
    list2=[]
    a=0
    for i in range(8):
        ans=a*math.pi/180
        list1.append(ans)
        a+=45
    a=0
    for i in range(8):
        list2.append(a)
        a+=0.3
    b=1.5
    c=60
    randian11=b*math.pi/180
    randian12=c*math.pi/180
    
    # 求解覆盖宽度:
    list3=[]
    for i in range(8):
        list4=[]
        for j in range(8):
            randian21=math.tan(randian11)*-1*math.cos(list1[i])
            randian31=math.tan(randian11)*math.sin(list1[i])
            randian22=math.atan(randian21)
            randian32=math.atan(randian31)
            Da=120-list2[j]*randian21*1852
            W=(Da*math.sin(randian12)/math.cos(randian12+randian32))+(Da*math.sin(randian12)/math.cos(randian12-randian32))
            list4.append(W)
        list3.append(list4)
    

    最后我们的工作就是数据的可视化了,首先是我们的代码部分:

    #对结果的可视化
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    df=pd.DataFrame()
    df["β=0°"]=list3[0]
    df["β=45°"]=list3[1]
    df["β=90°"]=list3[2]
    df["β=135°"]=list3[3]
    df["测量船距海域中心点的距离"]=list2
    plt.figure(figsize=(10, 6))
    plt.plot(df["测量船距海域中心点的距离"], df["β=0°"], label="β=0°")
    plt.scatter(df["测量船距海域中心点的距离"], df["β=0°"]) 
    plt.plot(df["测量船距海域中心点的距离"], df["β=45°"], label="β=45°")
    plt.scatter(df["测量船距海域中心点的距离"], df["β=45°"])  
    plt.plot(df["测量船距海域中心点的距离"], df["β=90°"], label="β=90°")
    plt.scatter(df["测量船距海域中心点的距离"], df["β=90°"]) 
    plt.plot(df["测量船距海域中心点的距离"], df["β=135°"], label="β=135°")
    plt.scatter(df["测量船距海域中心点的距离"], df["β=135°"]) 
    plt.xlabel('测量船距海域中心点的距离')
    plt.ylabel('list3 values')
    plt.legend()
    plt.grid(True)
    plt.show()
            
    

    在这里插入图片描述

    第三题

    前言

    这题与上面的题目仅仅需要我们求解不同,这题的工作主要分为两份:

    1. 求解
    2. 灵敏度分析

    求解

    这题求解的主要思路如下:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    (PS:浅浅吐槽一下,公式真的多,理顺花了我好一会…)
    博主的求解代码如下:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import math
    
    # 设置相关参数
    a=1.5
    b=60
    radian1=a*math.pi/180
    radian2=b* math.pi/180
    D0=110
    Les=4*1852 #待测海域东西宽度
    D=D0+Les/2*math.tan(radian1) #此处Dmax
    x=D*math.tan(radian2)
    D=D-x*math.tan(radian1)
    W1=0
    W2=0
    res_list=[x]  # 存储x
    left_list=[]  # 存储左线坐标
    right_list=[] # 存储右线坐标
    
    while x+W2*math.cos(radian1)<=Les:
        W2=D*math.sin(radian2)/math.cos(radian2-radian1)
        W1=D*math.sin(radian2)/math.cos(radian2+radian1)
        d=(W1+W2)*0.9*math.cos(radian1)/(1+math.sin(radian1)*math.sin(radian2)/math.cos(radian2+radian1)*0.9)
        left_list.append(x-W1*math.cos(radian1))
        right_list.append(x+W2*math.cos(radian1))
        D=D-d*math.tan(radian1)
        x=x+d
        res_list.append(x)
    
    W2=D*math.sin(radian2)/math.cos(radian2-radian1)
    W1=D*math.sin(radian2)/math.cos(radian2+radian1)
    d=(W1+W2)*0.9*math.cos(radian1)/(1+math.sin(radian1)*math.sin(radian2)/math.cos(radian2+radian1)*0.9)
    left_list.append(x-W1*math.cos(radian1))
    right_list.append(x+W2*math.cos(radian1))
    
    print("总条数:%d"%(len(res_list)))  #总条数
    print("最大长度:%f"%(res_list[-1]))  #最大长度
    for i in range(len(res_list)):
        res_list[i]=res_list[i]/1852   
        left_list[i]=left_list[i]/1852
        right_list[i]=right_list[i]/1852
    

    然后就是我们对相关结果的可视化:

    # 可视化
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    plt.axvline(res_list[0], color='red',label='Red Line (测线)')
    plt.axvline(left_list[0], color='green',label='Green Line (条线左侧)')
    plt.axvline(right_list[0], color='blue',label='Blue Line (条线右侧)')
    
    for i in range(1, len(res_list)):
        plt.axvline(res_list[i], color='red')
        plt.axvline(left_list[i], color='green')
        plt.axvline(right_list[i], color='blue')
    
    # 设置图形属性
    plt.title('问题三结果')
    plt.ylabel('由南向北/海里')
    plt.legend()
    
    # 显示图形
    plt.grid(True)
    plt.show()
    

    在这里插入图片描述

    灵敏度分析

    灵敏度的分析思路其实还是很简单,主要是我们要改变开角和坡角的大小来看一下
    看一下对结果的影响:

    • 基于开角变化实现的灵敏度分析及其可视化
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import math
    
    # 设置相关参数
    
    for b in range(100,150,10):
        a=1.5
        radian1=a*math.pi/180
        radian2=b/2* math.pi/180
        D0=110
        Les=4*1852 #待测海域东西宽度
        D=D0+Les/2*math.tan(radian1) #此处Dmax
        x=D*math.tan(radian2)
        D=D-x*math.tan(radian1)
        W1=0
        W2=0
        res_list=[x]
        left_list=[]
        right_list=[]
    
        while x+W2*math.cos(radian1)<=Les:
            W2=D*math.sin(radian2)/math.cos(radian2-radian1)
            W1=D*math.sin(radian2)/math.cos(radian2+radian1)
            d=(W1+W2)*0.9*math.cos(radian1)/(1+math.sin(radian1)*math.sin(radian2)/math.cos(radian2+radian1)*0.9)
            left_list.append(x-W1*math.cos(radian1))
            right_list.append(x+W2*math.cos(radian1))
            D=D-d*math.tan(radian1)
            x=x+d
            res_list.append(x)
    
        W2=D*math.sin(radian2)/math.cos(radian2-radian1)
        W1=D*math.sin(radian2)/math.cos(radian2+radian1)
        d=(W1+W2)*0.9*math.cos(radian1)/(1+math.sin(radian1)*math.sin(radian2)/math.cos(radian2+radian1)*0.9)
        plt.plot(range(len(res_list)), res_list, linestyle='-', label=f'开角为{b}°')
    
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    # 设置标签和标题
    plt.xlabel('i')
    plt.ylabel('res_list[i]')
    plt.title('基于开角变化实现的灵敏度分析及其可视化')
    
    # 添加网格线和图例(可选)
    plt.grid(True)
    plt.legend()
    
    # 显示图形
    plt.show()
        
    

    结果如下:
    在这里插入图片描述

    • 基于开角变化实现的灵敏度分析及其可视化:
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import math
    
    # 设置相关参数
    a_list=[1.3,1.4,1.5]
    for i in range(len(a_list)):
        a=a_list[i]
        b=120
        radian1=a*math.pi/180
        radian2=b/2* math.pi/180
        D0=110
        Les=4*1852 #待测海域东西宽度
        D=D0+Les/2*math.tan(radian1) #此处Dmax
        x=D*math.tan(radian2)
        D=D-x*math.tan(radian1)
        W1=0
        W2=0
        res_list=[x]
        left_list=[]
        right_list=[]
    
        while x+W2*math.cos(radian1)<=Les:
            W2=D*math.sin(radian2)/math.cos(radian2-radian1)
            W1=D*math.sin(radian2)/math.cos(radian2+radian1)
            d=(W1+W2)*0.9*math.cos(radian1)/(1+math.sin(radian1)*math.sin(radian2)/math.cos(radian2+radian1)*0.9)
            left_list.append(x-W1*math.cos(radian1))
            right_list.append(x+W2*math.cos(radian1))
            D=D-d*math.tan(radian1)
            x=x+d
            res_list.append(x)
    
        W2=D*math.sin(radian2)/math.cos(radian2-radian1)
        W1=D*math.sin(radian2)/math.cos(radian2+radian1)
        d=(W1+W2)*0.9*math.cos(radian1)/(1+math.sin(radian1)*math.sin(radian2)/math.cos(radian2+radian1)*0.9)
        plt.plot(range(len(res_list)), res_list, linestyle='-', label=f'坡角为{a}°')
    
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    # 设置标签和标题
    plt.xlabel('i')
    plt.ylabel('res_list[i]')
    plt.title('基于坡角变化实现的灵敏度分析及其可视化')
    
    # 添加网格线和图例(可选)
    plt.grid(True)
    plt.legend()
    
    # 显示图形
    plt.show()
    

    在这里插入图片描述

    第四题

    这题的主要工作就不是我做了,我主要是负责海水深度与横纵坐标数据的可视化,代码如下:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import math
    
    # 导入相关数据
    filepath="../resource/data.xlsx"
    df=pd.read_excel(filepath)
    
    # 数据预处理
    df = df.iloc[1:, 2:]
    list1=df.values.tolist()
    
    list2=[]
    for i in range(251):
        list3=[]
        for j in range(201):
            list3.append(list1[i][j]*-1)
        list2.append(list3)
    list4 = np.arange(0,4.02,0.02) 
    list3 = np.arange(0, 5.02, 0.02)
    
    # 数据可视化
    
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
    
    x, y = np.meshgrid(list4, list3)
    z = np.array(list2)
    
    fig = plt.figure(figsize=(10, 8))
    ax = fig.add_subplot(111, projection='3d')
    
    surf = ax.plot_surface(x, y, z, cmap='viridis')
    
    ax.set_xlabel('横向坐标(由西向东)/海里')
    ax.set_ylabel('纵向坐标(由南向北)/海里')
    
    ax.view_init(elev=30, azim=-45) 
    
    fig.colorbar(surf, aspect=5) 
    
    # 显示图形
    plt.show()
    

    三维图如下:
    在这里插入图片描述

    结语

    以上就是我所做的所有相关工作了,从这个学期有人找我打一下这个比赛,在此之前我从来都没有写过多少python,前一段时间打数维杯才开始看,没几天就上战场了,所幸最后也水了一个一等奖(感谢我的队友们),之前我的好几个学弟也问过怎么学语言之类,我还是觉得除了我们的第一门语言外,其他的就不要找几十小时的视频看了,你看我没看不也是硬逼出来了吗,事情往往不会在你有充分准备时到来,我们更应该学会边做边学,而不是等到学完再做,种一棵树最好的时间是十年前,其次是现在,写给可能有一些纠结的大家,也写给自己,那我们下篇见!over!

  • 相关阅读:
    java八股文面试[数据库]——MySQL的体系架构
    机器学习算法(二十四):启发式算法优化机器学习算法
    基于Java毕业设计东理咨询交流论坛源码+系统+mysql+lw文档+部署软件
    3层结构+7大特点,带你认识华为云IoTEdge
    电大搜题——赋能学习,助力广东开放大学学子
    Python 与 Qt c++ 程序共享内存,传递图片
    Python面向对象三大特征
    JVM 虚拟机 ---->垃圾收集算法
    GB28181协议-SIP协议详解
    山西佳诺德:短视频拍摄的知识有哪些
  • 原文地址:https://blog.csdn.net/qq_73924465/article/details/140297266