问题一
在这个反潜作战的投弹问题中,我们的目标是最大化深弹命中潜艇的概率。为此,我们需要从几个方面分析和优化投弹方案,包括潜艇的水平误差和引爆深度的设定。
问题拆解
-
水平命中概率:因为潜艇在水平面上的位置并不是完全确定的,它的横向(东西方向)和纵向(南北方向)的坐标存在误差,这种误差服从正态分布。我们要计算深弹落在潜艇长宽范围内的概率,即在100米长和20米宽的区域内,深弹击中潜艇的可能性。
- 由于误差服从正态分布,我们可以利用标准正态分布的累积分布函数(CDF)来计算深弹落点在这个区域的概率。
- 换句话说,我们要最大化深弹落在潜艇长宽范围内的概率,具体就是让投弹的落点尽可能接近潜艇的中心位置。
# 水平方向命中概率函数
def horiz_hit_prob(length, width, error_xy):
# 计算X方向命中概率
x_prob = norm.cdf(length / 2 / error_xy) - norm.cdf(-length / 2 / error_xy)
# 计算Y方向命中概率
y_prob = norm.cdf(width / 2 / error_xy) - norm.cdf(-width / 2 / error_xy)
# 返回水平方向总的命中概率(X方向 * Y方向)
return x_prob * y_prob
-
垂直命中概率:潜艇的深度是已知且没有误差的,所以重点是分析引爆深度的设定。
- 触发引信引爆:当深弹落在潜艇的上方,且引爆深度比潜艇的上表面更浅时,引信会引爆。
- 定深引信引爆:如果深弹的落点虽然不在潜艇的正上方,但在一定的杀伤半径(20米)内,且引爆深度在潜艇上方,也会通过定深引信引爆。
# 垂直方向命中概率(假设深度定位没有误差)
def vert_hit_prob(trigger_depth, radius, depth):
# 如果炸弹引爆深度小于潜艇上表面(触发引信引爆)
if depth < trigger_depth:
return 1.0 # 直接命中
# 如果炸弹在潜艇上方的杀伤半径内(定深引信引爆)
elif depth < trigger_depth + radius:
return 1.0 # 仍然命中
# 否则,超出杀伤半径,无法命中
else:
return 0.0 # 没有命中
综合命中概率:我们将水平命中概率和垂直引爆条件结合起来,总的命中概率就是两者的乘积。
# 计算总的命中概率
def total_hit_prob():
# 计算水平方向的命中概率
p_horiz = horiz_hit_prob(sub_len, sub_width, error_xy)
# 计算垂直方向的命中概率(引爆深度在潜艇顶部的上方范围内)
p_vert = vert_hit_prob(trigger_depth, radius, sub_depth)
# 返回总的命中概率 = 水平概率 * 垂直概率
return p_horiz * p_vert
最大化命中概率的关键点
-
水平投弹的准确性:我们知道,潜艇的水平位置误差服从正态分布,因此最优的策略是让投弹落点的期望值尽量靠近潜艇的中心,这样才能增加深弹落在潜艇范围内的概率。
-
引爆深度的选择:因为潜艇的深度是确定的,引爆深度应该设定在一个尽量靠近潜艇上方的较小深度。这样可以确保触发引信的有效性,同时还可以保证如果深弹落点不完全准确时,定深引信也能引爆。
直观的解题思路
- 水平精准投弹:通过调整投弹的落点坐标,使得它尽量靠近潜艇的中心,从而最大化水平命中概率。
- 合适的引爆深度:选择一个合适的引爆深度,既能保证触发引信的工作,又能确保在偏差较大的情况下定深引信也能起作用。
- 平衡误差和半径:深弹的杀伤半径为20米,因此即便投弹位置有一定的偏差,只要落点在潜艇附近且引爆深度合适,仍然有可能通过定深引信引爆。
最终,通过综合考虑投弹落点的水平坐标和引爆深度,我们可以找出一个最佳的投弹策略,从而最大化命中概率。
这个问题的实质就是在已知潜艇水平位置有误差的情况下,找到一个合理的投弹方案,既保证落点尽量精准,又能通过引爆深度的调整来弥补落点偏差带来的影响。
第二问
在此次数学建模问题中,我们需要分析潜艇在三维空间中的定位误差,并计算深弹命中的概率。我们将通过详细的模型构建过程以及代码实现,来进行这一分析。
1. 模型建立
1.1 坐标系定义
首先,假设潜艇的中心位置位于坐标系的原点 O(0,0,0)O(0, 0, 0)O(0,0,0)。在水平方向上,潜艇的定位误差(X和Y方向)服从正态分布,其标准差为水平定位误差。此外,潜艇在深度方向的定位误差(Z方向)服从截尾的正态分布。我们还设定了一些基本的参数来描述潜艇的几何尺寸和误差范围。
import numpy as np
from scipy.stats import norm
# 参数设定
sub_len = 100 # 潜艇长度 (m)
sub_width = 20 # 潜艇宽度 (m)
sub_height = 25 # 潜艇高度 (m)
sub_depth = 150 # 潜艇中心深度 (m)
sigma_xy = 120 # 水平方向的定位误差 (m)
sigma_z = 40 # 深度方向的定位误差 (m)
min_depth = 120 # 潜艇的最小深度 (m)
expl_radius = 20 # 炸弹的杀伤半径 (m)
trigger_depth = sub_depth + sub_height # 触发引信的引爆深度
1.2 引爆条件
在这个模型中,我们假设深弹有两种引爆机制:
- 触发引信引爆:当深弹落在潜艇的水平平面范围内,且引爆深度低于潜艇上表面时,触发引信会引爆深弹。
- 定深引信引爆:如果深弹的引爆深度高于潜艇上表面,但潜艇仍在深弹的杀伤范围内,定深引信会引爆深弹。
2. 投弹命中概率的表达
2.1 水平方向的命中概率
潜艇在水平方向上的命中概率由潜艇的长度、宽度以及水平方向的定位误差决定。我们使用正态分布的累积分布函数来计算水平方向的命中概率。以下是计算水平命中概率的函数:
# 水平方向的命中概率函数
def horiz_hit_prob(length, width, sigma_xy):
# X方向上的命中概率,计算潜艇在长度方向被命中的概率
x_prob = norm.cdf(length / 2 / sigma_xy) - norm.cdf(-length / 2 / sigma_xy)
# Y方向上的命中概率,计算潜艇在宽度方向被命中的概率
y_prob = norm.cdf(width / 2 / sigma_xy) - norm.cdf(-width / 2 / sigma_xy)
# 水平方向总的命中概率 = X命中概率 * Y命中概率
return x_prob * y_prob
在这个函数中,我们通过分别计算X和Y方向的命中概率,最终得到水平命中概率。
2.2 垂直方向的命中概率
垂直方向的命中概率与潜艇的深度误差以及定深引信的杀伤半径相关。触发引信和定深引信的命中概率分别表示为:
- 触发引信的引爆概率:即深弹引爆深度低于潜艇上表面的概率。
- 定深引信的引爆概率:即深弹的引爆深度高于潜艇上表面但仍在潜艇杀伤半径内的概率。
以下是计算垂直命中概率的函数:
# 垂直方向的命中概率函数
def vert_hit_prob(h0, sigma_z, min_depth, height, radius):
# 计算触发引信引爆的概率,也就是深度小于潜艇上表面的情况
trigger_prob = norm.cdf(h0 + height, loc=h0, scale=sigma_z) - norm.cdf(min_depth, loc=h0, scale=sigma_z)
# 计算定深引信引爆的概率,潜艇在深弹的杀伤半径范围内时会被引爆
depth_prob = norm.cdf(h0 + height + radius, loc=h0, scale=sigma_z) - norm.cdf(h0 + height, loc=h0, scale=sigma_z)
# 单边截尾的归一化处理
norm_factor = 1 - norm.cdf(min_depth, loc=h0, scale=sigma_z)
# 返回总的垂直命中概率 = 触发引信概率 + 定深引信概率
return (trigger_prob + depth_prob) / norm_factor
这个函数首先计算触发引信的概率,再计算定深引信的概率,最后进行归一化处理。
2.3 总命中概率
总命中概率为水平方向和垂直方向命中概率的乘积。对应的计算函数如下:
# 计算总的命中概率
def total_hit_prob():
# 计算水平方向的命中概率
p_horiz = horiz_hit_prob(sub_len, sub_width, sigma_xy)
# 计算垂直方向的命中概率
p_vert = vert_hit_prob(sub_depth, sigma_z, min_depth, sub_height, expl_radius)
# 返回总命中概率 = 水平概率 * 垂直概率
return p_horiz * p_vert
3. 计算并输出结果
最后,我们调用 total_hit_prob
函数来计算总的命中概率,并输出结果:
# 运行计算并输出结果
hit_prob = total_hit_prob()
print(f"最大命中概率: {hit_prob:.4f}")
第三问
在这个问题中,我们的目标是优化反潜作战中的投弹策略,以最大化命中潜艇的概率。通过调整投弹阵列的间隔(a
和 b
),以及引爆深度(Z_trigger
),我们可以设计出最优的投弹策略。代码主要通过三种投弹策略来计算命中概率,并使用粒子群优化(PSO)算法对这些策略进行优化。以下是详细的解题思路:
1. 基础参数与潜艇定位
- 定位误差:潜艇的水平定位误差服从正态分布,设定为
sigma_x = 50
和sigma_y = 50
。这些参数用于生成潜艇的位置。 - 炸弹阵列:投弹区域是一个 3x3 的矩阵,每个单元格代表一个炸弹的投放位置。
# 创建一个3x3的炸弹位置阵列
def bomb_positions():
return np.array([[0, 0], [0, 1], [0, 2],
[1, 0], [1, 1], [1, 2],
[2, 0], [2, 1], [2, 2]])
2. 命中概率计算
- 计算未命中区域的概率:炸弹未命中潜艇时,该区域会被排除在外,从而更新后续炸弹的命中概率。
# 计算未命中区域的概率(在正态分布中排除掉的区域)
def calc_excluded_prob(x, y, sigma_x, sigma_y, radius):
prob_x = norm.cdf(x + radius, 0, sigma_x) - norm.cdf(x - radius, 0, sigma_x)
prob_y = norm.cdf(y + radius, 0, sigma_y) - norm.cdf(y - radius, 0, sigma_y)
return prob_x * prob_y
炸弹命中概率:根据炸弹与潜艇的距离计算命中概率。如果炸弹在潜艇的杀伤半径内,则命中概率较高,否则随着距离增加命中概率下降。
# 计算炸弹的命中概率
def calc_hit_prob(bomb_pos, sub_pos, base_prob, rem_prob):
dist = np.sqrt((bomb_pos[0] - sub_pos[0]) ** 2 + (bomb_pos[1] - sub_pos[1]) ** 2)
if dist <= radius:
return base_prob * rem_prob
else:
return base_prob * rem_prob / (dist / radius)
3. 三种投弹策略
- 策略一:斜方向投弹
- 沿 3x3 矩阵的对角线投放炸弹。逐步排除未命中的区域,从而提高后续投弹的命中概率。
def diagonal_bombing(positions, sub_pos, base_prob):
results = []
rem_prob = 1.0
diagonal_pos = [positions[0], positions[4], positions[8]]
for pos in diagonal_pos:
hit_prob = calc_hit_prob(pos, sub_pos, base_prob, rem_prob)
results.append(hit_prob)
excl_prob = calc_excluded_prob(pos[0], pos[1], sigma_x, sigma_y, radius)
rem_prob -= excl_prob
base_prob *= rem_prob
while len(results) < 9:
results.append(0)
return results
策略二:中心扩展投弹
- 先投放中心炸弹,再投放上下左右的炸弹,最后投放四角的炸弹。这种策略对称性强,适合潜艇更可能位于中心的情况。
def center_out_bombing(positions, sub_pos, base_prob):
results = []
rem_prob = 1.0
center_pos = positions[4]
neighbors = [positions[1], positions[3], positions[5], positions[7]]
corners = [positions[0], positions[2], positions[6], positions[8]]
hit_prob = calc_hit_prob(center_pos, sub_pos, base_prob, rem_prob)
results.append(hit_prob)
excl_prob = calc_excluded_prob(center_pos[0], center_pos[1], sigma_x, sigma_y, radius)
rem_prob -= excl_prob
base_prob *= rem_prob
for pos in neighbors + corners:
hit_prob = calc_hit_prob(pos, sub_pos, base_prob, rem_prob)
results.append(hit_prob)
excl_prob = calc_excluded_prob(pos[0], pos[1], sigma_x, sigma_y, radius)
rem_prob -= excl_prob
base_prob *= rem_prob
return results
策略三:顺时针/逆时针投弹
- 按照顺时针或逆时针顺序投放炸弹,从边缘向内逐渐覆盖潜艇的可能位置。
def circular_bombing(positions, sub_pos, base_prob, clockwise=True):
results = []
rem_prob = 1.0
if clockwise:
order = [positions[0], positions[1], positions[2], positions[5], positions[8],
positions[7], positions[6], positions[3], positions[4]]
else:
order = [positions[0], positions[3], positions[6], positions[7], positions[8],
positions[5], positions[2], positions[1], positions[4]]
for pos in order:
hit_prob = calc_hit_prob(pos, sub_pos, base_prob, rem_prob)
results.append(hit_prob)
excl_prob = calc_excluded_prob(pos[0], pos[1], sigma_x, sigma_y, radius)
rem_prob -= excl_prob
base_prob *= rem_prob
return results
4. 优化策略
- 使用粒子群优化(PSO)算法来调整投弹间隔(
a
和b
)以及引爆深度(Z_trigger
),以找到最优参数组合,使总命中概率最大化。
# 优化目标函数,用于计算总命中概率
def optimize_strategy(x):
a, b, Z_trigger = x
sub_pos = generate_sub_position()
positions = bomb_positions()
base_prob = Z_trigger / 200.0
diag_probs = diagonal_bombing(positions, sub_pos, base_prob)
center_probs = center_out_bombing(positions, sub_pos, base_prob)
circ_probs = circular_bombing(positions, sub_pos, base_prob, clockwise=True)
total_prob = sum(diag_probs) + sum(center_probs) + sum(circ_probs)
return -total_prob # 取负值用于最小化问题
# 使用PSO优化a, b, Z_trigger
lb = [20, 20, 170]
ub = [60, 60, 190]
best_params, best_prob = pso(optimize_strategy, lb, ub, swarmsize=30, maxiter=50)
最后,根据优化结果选择最优策略并进行排序。
strategies = [("斜方向投弹", sum(diag_probs)),
("中心扩展投弹", sum(center_probs)),
("顺时针投弹", sum(circ_probs))]
sorted_strategies = sorted(strategies, key=lambda x: x[1], reverse=True)
for i, (name, prob) in enumerate(sorted_strategies):
print(f"第 {i + 1} 名: {name}, 总命中概率: {prob:.4f}")
通过分析潜艇的定位误差,调整投弹阵列的间隔和定深引信的引爆深度,结合三种不同的投弹策略(斜方向、中心扩展、顺时针/逆时针),并使用粒子群优化算法进行参数优化,我们成功设计出了最优的投弹方案,使潜艇被命中的概率最大化。
论文更新:
https://note.youdao.com/s/YVjtHq80