数学建模应掌握的十类算法(详解版)
1. 蒙特卡罗方法 (Monte-Carlo 方法, MC)
蒙特卡罗方法是一种基于随机采样和统计学原理的模拟算法,用于解决数值计算和模拟中的复杂问题。它尤其适用于多维积分、概率问题、复杂系统的模拟等。
示例代码 - 蒙特卡罗法求π值
- Python:
import random
def monte_carlo_pi(num_samples):
inside_circle = 0
for _ in range(num_samples):
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
if x**2 + y**2 <= 1:
inside_circle += 1
pi_estimate = (inside_circle / num_samples) * 4
return pi_estimate
# 计算 π 值,使用 10000 次采样
num_samples = 10000
pi_value = monte_carlo_pi(num_samples)
print(f"Estimated Pi value: {pi_value}")
- MATLAB:
function pi_estimate = monte_carlo_pi(num_samples)
inside_circle = 0;
for i = 1:num_samples
x = rand()*2 - 1; % 在 [-1, 1] 范围内生成随机数
y = rand()*2 - 1;
if x^2 + y^2 <= 1
inside_circle = inside_circle + 1;
end
end
pi_estimate = (inside_circle / num_samples) * 4;
end
% 计算 π 值,使用 10000 次采样
num_samples = 10000;
pi_value = monte_carlo_pi(num_samples);
fprintf('Estimated Pi value: %f\n', pi_value);
2. 数据拟合、参数估计、插值等数据处理算法
数据拟合和插值在数据处理中是非常常见的技术,用于找到数据的趋势或在已知数据点间插值。
示例代码 - 二次多项式拟合
- Python:
import numpy as np
import matplotlib.pyplot as plt
# 样本数据
x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([0, 1, 4, 9, 16, 25])
# 二次多项式拟合
coefficients = np.polyfit(x, y, 2)
p = np.poly1d(coefficients)
# 拟合后的曲线
x_fit = np.linspace(0, 5, 100)
y_fit = p(x_fit)
# 绘制
plt.scatter(x, y, label='Data Points')
plt.plot(x_fit, y_fit, label='Quadratic Fit', color='red')
plt.legend()
plt.show()
- MATLAB:
x = [0 1 2 3 4 5];
y = [0 1 4 9 16 25];
% 二次多项式拟合
p = polyfit(x, y, 2);
% 拟合后的曲线
x_fit = linspace(0, 5, 100);
y_fit = polyval(p, x_fit);
% 绘制
scatter(x, y);
hold on;
plot(x_fit, y_fit, 'r');
legend('Data Points', 'Quadratic Fit');
hold off;
3. 规划类问题算法
规划类问题常见的有线性规划和整数规划。线性规划用于在给定约束条件下求解最优解。
示例代码 - 线性规划求解
- Python (使用
scipy.optimize
):
from scipy.optimize import linprog
# 目标函数: 最小化 c*x
c = [-1, -2] # 目标是最大化,所以使用负号表示最小化
# 不等式约束: A_ub * x <= b_ub
A_ub = [[-2, 1], [1, 2]]
b_ub = [1, 5]
# 边界: x1 和 x2 的取值范围
x_bounds = (0, None)
y_bounds = (0, None)
# 求解线性规划问题
res = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=[x_bounds, y_bounds])
print(f'Optimal value: {-res.fun}') # 目标最大化
print(f'Optimal solution: {res.x}')
- MATLAB:
f = [-1 -2]; % 目标函数系数 (目标最大化)
A = [-2 1; 1 2]; % 不等式约束系数矩阵
b = [1; 5]; % 不等式约束常数向量
lb = [0; 0]; % 边界条件
% 求解线性规划问题
[x, fval] = linprog(f, A, b, [], [], lb, []);
fprintf('Optimal value: %f\n', -fval); % 最大化目标函数
fprintf('Optimal solution: x1 = %f, x2 = %f\n', x(1), x(2));
4. 图论问题
图论问题在数学建模中非常常见,常用算法包括最短路径、最大流、二分图匹配等。
示例代码 - Dijkstra算法求最短路径
- Python:
import heapq
def dijkstra(graph, start):
queue = [(0, start)]
distances = {node: float('inf') for node in graph}
distances[start] = 0
while queue:
current_distance, current_node = heapq.heappop(queue)
if current_distance > distances[current_node]:
continue
for neighbor, weight in graph[current_node].items():
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(queue, (distance, neighbor))
return distances
# 图的邻接表表示
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
# 计算从'A'到所有节点的最短路径
distances = dijkstra(graph, 'A')
print(distances)
- MATLAB (使用自定义实现):
function distances = dijkstra(graph, start)
n = length(graph);
distances = inf(1, n);
visited = false(1, n);
distances(start) = 0;
while any(~visited)
[~, u] = min(distances .* (~visited));
visited(u) = true;
for v = 1:n
if graph(u, v) > 0 && ~visited(v)
distances(v) = min(distances(v), distances(u) + graph(u, v));
end
end
end
end
% 图的邻接矩阵表示
graph = [
0 1 4 0;
1 0 2 5;
4 2 0 1;
0 5 1 0
];
% 计算从节点1开始的最短路径
distances = dijkstra(graph, 1);
disp(distances);
以上是常见数学建模算法的部分详解和代码实现。这些代码可以进行扩展,解决不同类型的数学建模问题。
1. 蒙特卡罗方法(Monte-Carlo方法, MC)
该算法又称计算机随机性模拟方法,也称统计试验方法。这 一方法源于美国在第一次世界大战进行的研制原子弹的“曼 哈顿计划”。该计划的主持人之一、数学家冯·诺伊曼用驰名 世界的赌城—摩纳哥的 Monte Carlo—来命名这种方法。 MC方法是一种基于“随机数”的计算方法,能够比较逼真地 描述事物的特点及物理实验过程,解决一些数值方法难以解 决的问题。MC方法的雏型可以追溯到十九世纪后期的蒲丰(Buffon) 随机投针试验,即著名的蒲丰问题。 MC方法通过计算机仿真(模 拟)解决问题,同时也可以通过模拟来检验自己模型的正确 性,几乎是比赛时必用的方法。
2. 数据拟合、参数估计、插值等数据处理算法
比赛中通常会遇到大量的数据需要处理,而处理数据的关键就在于这些算法,通常使用
MATLAB
作为工具。与图形处理有关的问题很多与拟合有关系。
3. 规划类问题算法
此类问题主要有线性规划、整数规划、多元规划、二次规划等。竞赛中很多问题都和数学规划有关,可以说不少的模型都可以归结为一组不等式作为约束条件、几个函数表达式作为目标函数的问题,遇到这类问题,求解就是关键了。
4. 图论问题
这类问题算法有很多,包括:
Dijkstra
、Floyd
、Prim
、Bellman-Ford
,最大流,二分匹配等问题。
5. 计算机算法设计中的问题
计算机算法设计包括很多内容:动态规划、回溯搜索、分治算法、分枝定界等计算机算法。
6. 最优化理论的三大非经典算法
模拟退火法(SA)、神经网络(NN)、遗传算法(GA)
7. 网格算法和穷举算法
网格算法和穷举法一样,只是网格法是连续问题的穷举。比如要求在
N
个变量情况下的最优化问题,那么对这些变量可取的空间进行采点,比如在[a, b]
区间内取M+1
个点, 就是a,a+(b-a)/M,a+2(b-a)/M,...,b
。那么这样循环就 需要进行(M + 1)^N
次运算,所以计算量很大。
8. 连续问题离散化的方法
很多问题都是实际来的,数据可以是连续的,而计算机只能处理离散的数据,因此需要将连续问题进行离散化处理后再用计算机求解。比如差分代替微分、求和代替积分等思想都是把连续问题离散化的常用方法。
9. 数值分析方法
数值分析研究各种求解数学问题的数值计算方法,特别 是适合于计算机实现的方法与算法。它的主要内容包括 函数的数值逼近、数值微分与数值积分、非线性方程的 数值解法、数值代数、常微分方程数值解等。数值分析 是计算数学的一个重要分支,把理论与计算紧密结合,是 现代科学计算的基础 。
MATLAB
等数学软件中已经有很 多数值分析的函数可以直接调用。
10. 图象处理算法
赛题中有一类问题与图形有关,即使问题与图形无 关,论文中也会需要图片来说明问题,这些图形如 何展示以及如何处理就是需要解决的问题,通常使 用
MATLAB
进行处理。