Python建模是指使用Python编程语言创建数学模型来模拟、分析和预测现实世界中的系统或现象。
它包含几个关键方面:
今天,我将通过一个经典的随机游走案例,带大家理解建模的本质和应用方法。
如果有
100个小球在二项坐标轴的原点,限制如下
那么经历一小时后,这些小球会呈现什么样的情况
这是一个典型的随机游走问题,我们可以用Python来模拟这个过程:
import random
import matplotlib.pyplot as plt
import numpy as np
def random_walk_simulation(num_balls=100, minutes=60):
# 初始化小球位置
positions = [(0, 0) for _ in range(num_balls)]
# 记录所有时刻的位置
all_positions = [[(0, 0)] for _ in range(num_balls)]
# 每分钟的移动
for minute in range(minutes):
for i in range(num_balls):
x, y = positions[i]
# 随机选择方向:0-上,1-下,2-左,3-右
direction = random.randint(0, 3)
if direction == 0: # 上
y += 1
elif direction == 1: # 下
y -= 1
elif direction == 2: # 左
x -= 1
else: # 右
x += 1
positions[i] = (x, y)
all_positions[i].append((x, y))
return positions, all_positions
# 执行模拟
final_positions, history = random_walk_simulation() # 分析最终位置
x_coords = [pos[0] for pos in final_positions]
y_coords = [pos[1] for pos in final_positions]
# 计算统计信息
mean_x = np.mean(x_coords)
mean_y = np.mean(y_coords)
distance_from_origin = [np.sqrt(x**2 + y**2) for x, y in final_positions]
mean_distance = np.mean(distance_from_origin)
print(f"平均X坐标: {mean_x:.2f}")
print(f"平均Y坐标: {mean_y:.2f}")
print(f"平均距离原点: {mean_distance:.2f}") # 设置中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 创建三维波形图可视化概率分布
fig = plt.figure(figsize=(16, 12))
# 子图1: 二维原始散点图(对照)
ax1 = fig.add_subplot(221)
ax1.scatter(x_coords, y_coords, c='blue', alpha=0.6, s=20)
ax1.set_xlabel('X')
ax1.set_ylabel('Y')
ax1.set_title('二维散点图 - 最终位置')
ax1.grid(True)
ax1.axhline(y=0, color='k', linestyle='--', alpha=0.3)
ax1.axvline(x=0, color='k', linestyle='--', alpha=0.3)
# 子图2: 三维概率密度波形图
ax2 = fig.add_subplot(222, projection='3d')
# 创建概率密度网格
# 确定网格范围(基于数据范围,留有余量)
x_min, x_max = min(x_coords)-5, max(x_coords)+5
y_min, y_max = min(y_coords)-5, max(y_coords)+5
# 创建网格
grid_size = 40
x_grid = np.linspace(x_min, x_max, grid_size)
y_grid = np.linspace(y_min, y_max, grid_size)
X, Y = np.meshgrid(x_grid, y_grid)
Z = np.zeros_like(X)
# 计算每个网格点的概率密度(二维高斯核密度估计)
# 使用小球位置计算局部密度
bandwidth = 2.0 # 带宽参数
num_sim_balls = len(final_positions) # 修正变量名
for i in range(grid_size):
for j in range(grid_size):
# 计算当前网格点到所有小球的距离
distances = np.sqrt((X[i,j] - np.array(x_coords))**2 + (Y[i,j] - np.array(y_coords))**2)
# 高斯核密度估计
density = np.sum(np.exp(-distances**2 / (2 * bandwidth**2))) / (num_sim_balls * bandwidth * np.sqrt(2 * np.pi))
Z[i,j] = density
# 平滑处理
Z_smooth = gaussian_filter(Z, sigma=1.5)
# 绘制三维波形表面
surf = ax2.plot_surface(X, Y, Z_smooth, cmap='viridis', alpha=0.9, edgecolor='none', antialiased=True)
ax2.set_xlabel('X')
ax2.set_ylabel('Y')
ax2.set_zlabel('概率密度')
ax2.set_title('三维概率密度波形')
fig.colorbar(surf, ax=ax2, shrink=0.6, label='密度')
ax2.grid(True)
# 子图3: 三维概率分布曲面(不同视角)
ax3 = fig.add_subplot(223, projection='3d')
# 使用对数变换增强低密度区域的可见性
Z_log = np.log1p(Z_smooth) # log(1+x) 避免log(0)
# 绘制平滑的概率分布曲面
surf3 = ax3.plot_surface(X, Y, Z_log, cmap='plasma', alpha=0.8,
edgecolor='none', antialiased=True)
ax3.set_xlabel('X')
ax3.set_ylabel('Y')
ax3.set_zlabel('log(密度)')
ax3.set_title('三维概率曲面')
fig.colorbar(surf3, ax=ax3, shrink=0.6, label='log(密度)')
ax3.grid(True)
# 子图4: 概率密度热图(俯视图)
ax4 = fig.add_subplot(224)
im = ax4.imshow(Z_smooth, extent=[x_min, x_max, y_min, y_max],
origin='lower', cmap='hot', alpha=0.8)
ax4.set_xlabel('X')
ax4.set_ylabel('Y')
ax4.set_title('概率密度热俯视图')
fig.colorbar(im, ax=ax4, shrink=0.7, label='密度')
ax4.grid(True, alpha=0.3)
ax4.axhline(y=0, color='white', linestyle='--', alpha=0.5)
ax4.axvline(x=0, color='white', linestyle='--', alpha=0.5)
plt.tight_layout()
plt.show()
# 概率分布统计分析
print("\n=== 概率分布分析 ===")
print(f"最大概率密度: {np.max(Z_smooth):.4f}")
print(f"平均概率密度: {np.mean(Z_smooth):.4f}")
print(f"密度分布范围: [{np.min(Z_smooth):.4f}, {np.max(Z_smooth):.4f}]")
# 计算概率质量中心
total_mass = np.sum(Z_smooth)
center_x = np.sum(X * Z_smooth) / total_mass
center_y = np.sum(Y * Z_smooth) / total_mass
print(f"概率分布中心: ({center_x:.2f}, {center_y:.2f})")
# 计算分布的不确定性(香农熵近似)
prob_normalized = Z_smooth / total_mass
entropy = -np.sum(prob_normalized * np.log(prob_normalized + 1e-10))
print(f"分布熵(不确定性): {entropy:.2f}")那么运行之后,结果会呈现什么样呢,如下

可以看到,小球平均位置仍在原点附近,呈现中间多,四周少的一个分布情况
这种情况可以称为正态分布特征
那么如果小球多点,我们放入1000个小球,并且运动的时间足够长呢,那情况还会一样吗,我们将时间拉长至一天,也就是1440,结果如下

可以看到,有些小球走的更远了,但总体分布情况与上面分析的一致,概率呈现中间高,四周低的分布情况
通过这个案例,我们理解了Python建模的基本流程:
Python编写模拟程序建模的本质是用计算代替推导,用模拟代替实验。它让我们能够在计算机上"做实验",快速验证想法,预测结果。
学习建模给我最大的启发是:复杂背后往往有简单的规律。随机游走看似混乱,但统计规律却很清晰。这教会我在面对复杂问题时,要先找最简单的模型入手,逐步深入。
Python建模不需要高深的数学,关键是理解问题本质和动手实践。多写代码、多做实验,比死记公式更有用。建议大家从这类简单案例开始,培养建模思维,为解决更复杂的问题打基础。
记住:好的模型不是最复杂的,而是能抓住问题核心的。
我是半月,祝你编码愉快!!!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。