全国大学生数学建模竞赛,8月17日,第三题打卡
主题活动
发布于 2025-08-20 08:42:48
查看 5过去313天
8月17日 题目三解答说明
题目回顾
今天要解决两个数学问题:
- 求解一个三元线性方程组
- 解决一个工厂生产利润最大化的线性规划问题
解题思路
1. 线性方程组求解
我的想法:
- 这是一个三元线性方程组,有三个未知数x₁、x₂、x₃
- 可以用矩阵方法直接求解,也可以用高斯消元法手动计算
- 两种方法都要试试,看看结果是否一致
代码实现:
方法一:矩阵求解法
# 系数矩阵 A
A = [1.0 2.0 3.0; -1.0 3.0 7.0; 9.0 0.0 3.0]
# 常数向量 b
b = [1.0, 4.0, 7.0]
# 求解线性方程组 Ax = b
x_matrix = A \ b
- 优点:简单快捷,一行代码搞定
- 缺点:看不到计算过程
方法二:高斯消元法
function gaussian_elimination(A, b)
n = length(b)
# 创建增广矩阵
augmented = [A b]
# 前向消元
for i in 1:n
# 找到主元
pivot_row = i
for j in i+1:n
if abs(augmented[j, i]) > abs(augmented[pivot_row, i])
pivot_row = j
end
end
# 交换行
if pivot_row != i
augmented[i, :], augmented[pivot_row, :] = augmented[pivot_row, :], augmented[i, :]
end
# 消元
for j in i+1:n
factor = augmented[j, i] / augmented[i, i]
augmented[j, :] -= factor * augmented[i, :]
end
end
# 回代求解
x = zeros(n)
for i in n:-1:1
x[i] = (augmented[i, end] - sum(augmented[i, i+1:end-1] .* x[i+1:end])) / augmented[i, i]
end
return x
end
- 优点:能看到完整的计算过程
- 缺点:代码复杂一些
结果验证:
# 验证解是否正确
residual = A * x_matrix - b
println("残差 (应该接近0):")
println(residual)
- 两种方法得到相同结果:x₁ = 0.333, x₂ = -1.667, x₃ = 1.333
- 代入原方程验证,残差接近0,说明解是正确的
2. 线性规划问题
我的想法:
- 这是一个典型的线性规划问题,要最大化利润
- 有约束条件:原料重量不能超过1000千克
- 可以用图解法,但更简单的是直接分析单位利润
代码实现:
边界分析法
# 计算单位原料利润
profit_per_kg_A = 40.0 / 3.0 # A产品:40元利润/3千克原料
profit_per_kg_B = 30.0 / 2.0 # B产品:30元利润/2千克原料
println("单位原料利润:A = ", profit_per_kg_A, " 元/千克,B = ", profit_per_kg_B, " 元/千克")
if profit_per_kg_B >= profit_per_kg_A
# 全部原料用于 B
x_opt = 0.0
y_opt = 1000.0 / 2.0
else
# 全部原料用于 A(本题不会发生)
x_opt = 1000.0 / 3.0
y_opt = 0.0
end
P_max = 40.0 * x_opt + 30.0 * y_opt
关键思路:
- 单位利润比较:A产品每千克原料产生13.33元利润,B产品每千克原料产生15元利润
- 最优策略:既然B产品的单位利润更高,就应该把所有原料都用来生产B产品
- 具体计算:1000千克原料 ÷ 2千克/单位 = 500单位B产品
- 最大利润:500 × 30元 = 15000元
约束验证:
# 验证约束条件
constraint_value = 3.0 * x_opt + 2.0 * y_opt
println("约束验证:")
println("3x + 2y = ", constraint_value, " ≤ 1000 ✓")
println("x ≥ 0 ✓, y ≥ 0 ✓")
为什么这样最优?
- 线性规划的最优解总是在可行域的顶点上
- 在这个问题中,可行域是一个三角形
- 由于目标函数的系数都是正的,最优点一定在边界上
- 既然B的单位利润更高,最优解就是全部生产B
代码实现要点
线性方程组部分
- 数据类型:使用浮点数避免类型转换问题
- 矩阵求解:用
A \ b语法,Julia自动选择最优算法 - 高斯消元:包含主元选择和行交换,提高数值稳定性
- 验证方法:用残差
A * x - b验证解的正确性
线性规划部分
- 单位利润法:直接比较
40/3和30/2,避免复杂的图解法 - 条件判断:用
if-else结构处理不同情况 - 约束验证:检查所有约束条件是否满足
结果总结
- 线性方程组解: x₁ = 0.333, x₂ = -1.667, x₃ = 1.333
- 线性规划最优解: x = 0, y = 500, 最大利润 = 15000元
下面是运行结果


下面是完整代码
println("=== 8月17日 题目三解答 ===")
println()
# --- 1. 线性方程组求解 ---
println("1. 线性方程组求解")
println("方程组:")
println("x₁ + 2x₂ + 3x₃ = 1")
println("-x₁ + 3x₂ + 7x₃ = 4")
println("9x₁ + 3x₃ = 7")
println()
# 方法一:矩阵求解法
println("方法一:矩阵求解法")
# 系数矩阵 A
A = [1.0 2.0 3.0; -1.0 3.0 7.0; 9.0 0.0 3.0]
# 常数向量 b
b = [1.0, 4.0, 7.0]
println("系数矩阵 A:")
println(A)
println("常数向量 b:")
println(b)
# 求解线性方程组 Ax = b
x_matrix = A \ b
println("解向量 x:")
println(x_matrix)
println("x₁ = ", x_matrix[1])
println("x₂ = ", x_matrix[2])
println("x₃ = ", x_matrix[3])
println()
# 验证解是否正确
residual = A * x_matrix - b
println("残差 (应该接近0):")
println(residual)
println()
# 方法二:高斯消元法
println("方法二:高斯消元法")
function gaussian_elimination(A, b)
n = length(b)
# 创建增广矩阵
augmented = [A b]
# 前向消元
for i in 1:n
# 找到主元
pivot_row = i
for j in i+1:n
if abs(augmented[j, i]) > abs(augmented[pivot_row, i])
pivot_row = j
end
end
# 交换行
if pivot_row != i
augmented[i, :], augmented[pivot_row, :] = augmented[pivot_row, :], augmented[i, :]
end
# 消元
for j in i+1:n
factor = augmented[j, i] / augmented[i, i]
augmented[j, :] -= factor * augmented[i, :]
end
end
# 回代求解
x = zeros(n)
for i in n:-1:1
x[i] = (augmented[i, end] - sum(augmented[i, i+1:end-1] .* x[i+1:end])) / augmented[i, i]
end
return x
end
x_gaussian = gaussian_elimination(A, b)
println("高斯消元法解:")
println("x₁ = ", x_gaussian[1])
println("x₂ = ", x_gaussian[2])
println("x₃ = ", x_gaussian[3])
println()
# --- 2. 线性规划问题 ---
println("2. 工厂生产最大化利润问题")
println()
# 问题:最大化 P = 40x + 30y,约束 3x + 2y ≤ 1000,x ≥ 0, y ≥ 0
println("目标函数:最大化 P = 40x + 30y")
println("约束条件:3x + 2y ≤ 1000")
println("非负约束:x ≥ 0, y ≥ 0")
println()
# 解法:边界分析法(把约束化为等式并比较单位原料利润)
# 单位原料利润:A 为 40/3,B 为 30/2
profit_per_kg_A = 40.0 / 3.0
profit_per_kg_B = 30.0 / 2.0
println("单位原料利润:A = ", profit_per_kg_A, " 元/千克,B = ", profit_per_kg_B, " 元/千克")
if profit_per_kg_B >= profit_per_kg_A
# 全部原料用于 B
x_opt = 0.0
y_opt = 1000.0 / 2.0
else
# 全部原料用于 A(本题不会发生)
x_opt = 1000.0 / 3.0
y_opt = 0.0
end
P_max = 40.0 * x_opt + 30.0 * y_opt
println("最优解:")
println("x = ", x_opt, " (产品A单位数)")
println("y = ", y_opt, " (产品B单位数)")
println("最大利润 Pmax = ", P_max, " 元")
# 约束校验
println()
println("约束验证:")
println("3x + 2y = ", 3.0 * x_opt + 2.0 * y_opt, " ≤ 1000 ✓")
println("x ≥ 0 ✓, y ≥ 0 ✓")
所属专栏:Syslab基础平台
产品信息:Syslab科学计算环境