数模模拟题的复盘

我们做的问题是:第十六届华中杯问题C。这个问题在数学建模竞赛中属于十分简单的问题。我大体的思路就是:

问题一思路:

  1. 归一化波长数据
  2. 画出归一化波长-横坐标散点图
  3. 得到散点图后,判断适合用何种曲线拟合
  4. 采用数据点拟合并画图
  5. 选择合适的插值方法,插入数据点后再次拟合
  6. 比较两次拟合的结果

问题二思路:

  1. 采用迭代方法求函数的离散表达式(可取x区间长0.01等)
  2. 增加迭代次数,更改迭代模型(几何近似or微分)
  3. 建立曲线函数表达式,分析不同情况下求得函数表达式的精确性

问题三思路:

  1. 采用问题二的最佳方案,划分训练集和测试集
  2. 利用训练集求出预测函数表达式,再对测试集进行预测
  3. 对结果进行误差分析(残差,均方误差),分析误差产生的原因

此后,我阅读了某优秀论文,发现其基本思想与我几乎一致。

对于我们初学者想到的这种老套的既有模型,我的总结如下:

  1. 本次第一题的结果几乎都维持在2.2附近,这说明曲线的曲率近似为定值,应想到原曲线为一个圆。这说明我们对结果的解释不够完善。在做完一件事之后,一定要回头给一个好的解释。
  2. 不应该拘泥于题目文件本身,积极寻找相关领域论文,从机理方面做误差分析等实际情况的考虑。
  3. 公式过程十分完善,推导很“数学”。虽然使用的都是可以用既有Matlab或Python函数求解的模型,但数模究竟是数模,必须要有完善的数学推理,这部分要把b装足了。
  4. 学会变着法儿画图,但是要对每个图片的意义做好阐述。不要认为联系实际,给出合理解释的部分比较low!
  5. 有时候,我们只能想到一个大致的思路,但是可以由此触发比较高级的算法,例如想到要插值,可以选用不太老套的插值方法。
  6. 不要小看中学数学中学过的初等几何知识。

定位为编程辅助建模,意味着二者我都要会!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 原始数据
test_1 = np.array([1529.808, 1529.807, 1529.813, 1529.812, 1529.814, 1529.809])
test_2 = np.array([1541.095, 1541.092, 1541.090, 1541.093, 1541.094, 1541.091])

# 归一化 (标准化可选)
test1 = test_1 / np.mean(test_1)
test2 = test_2 / np.mean(test_2)
dist = 0.6

# 生成测试点位置
test_points = np.array([1*dist, 2*dist, 3*dist, 4*dist, 5*dist, 6*dist])

# 构建 DataFrame
df = pd.DataFrame({
"testpoint": test_points,
"test1": test1,
"test2": test2
})

# 提取数据
x = df["testpoint"].values
y1 = df["test1"].values
y2 = df["test2"].values

# 三次多项式拟合
coef1_cubic = np.polyfit(x, y1, 3)
coef2_cubic = np.polyfit(x, y2, 3)
poly1_cubic = np.poly1d(coef1_cubic)
poly2_cubic = np.poly1d(coef2_cubic)

# 生成更平滑的拟合曲线
x_dense = np.linspace(min(x), max(x), 100)
y1_dense = poly1_cubic(x_dense)
y2_dense = poly2_cubic(x_dense)

# 绘图
plt.figure(figsize=(8, 5))
plt.scatter(x, y1, color="blue", label="Test1 Data")
plt.scatter(x, y2, color="red", label="Test2 Data")
plt.plot(x_dense, y1_dense, linestyle="--", color="blue", alpha=0.7, label="Cubic Fit 1 (smooth)")
plt.plot(x_dense, y2_dense, linestyle="--", color="red", alpha=0.7, label="Cubic Fit 2 (smooth)")

plt.xlabel("Test Point Distance")
plt.ylabel("Normalized Wavelength")
plt.legend()
plt.title("Cubic Polynomial Fit (Smoothed)")
plt.grid()
plt.show()

# 输出拟合系数
print("Test1 三次拟合系数:", coef1_cubic)
print("Test2 三次拟合系数:", coef2_cubic)

test=[test1,test2]
#波长数据
x_need=[0.3,0.4,0.5,0.6,0.7]
y1_predict=poly1_cubic(x_need)
y2_predict=poly2_cubic(x_need)
y1_predict=y1_predict*np.mean(test_1)
y2_predict=y2_predict*np.mean(test_2)
#曲率数据
lamda0=[1529,1540]
c=4200
def lamda2K(y,i):
return(c*(y-lamda0[i]))/lamda0[i-1]
y1_predict=lamda2K(y1_predict,0)
y2_predict=lamda2K(y2_predict,1)

def get_K(x,i):
y_predict=poly1_cubic(x)/np.mean(test[i-1])
y_predict=lamda2K(y_predict,i-1)


print(y1_predict)
print(y2_predict)

以上为第一问代码。其输出结果也一并贴在下方。

第一问结果