import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
class Goose:
def __init__(self, x, y, vx, vy, perception_radius=2):
self.position = np.array([x, y], dtype=float)
self.velocity = np.array([vx, vy], dtype=float)
self.perception_radius = perception_radius
self.max_speed = 0.5
self.alignment_factor = 0.05
self.cohesion_factor = 0.005
self.separation_factor = 0.05
def update(self, flock):
# 获取邻近的大雁
neighbors = self.get_neighbors(flock)
if len(neighbors) > 0:
# 对齐行为:与邻近大雁的平均方向保持一致
alignment = self.align(neighbors)
# 凝聚行为:向邻近大雁的中心移动
cohesion = self.cohere(neighbors)
# 分离行为:避免与邻近大雁太近
separation = self.separate(neighbors)
# 更新速度
self.velocity += alignment + cohesion + separation
# 限制速度
speed = np.linalg.norm(self.velocity)
if speed > self.max_speed:
self.velocity = self.velocity / speed * self.max_speed
# 更新位置
self.position += self.velocity
# 边界处理 - 如果飞出边界则从另一侧进入
if self.position[0] > 20:
self.position[0] = -20
elif self.position[0] < -20:
self.position[0] = 20
if self.position[1] > 20:
self.position[1] = -20
elif self.position[1] < -20:
self.position[1] = 20
def get_neighbors(self, flock):
neighbors = []
for goose in flock:
if goose != self:
distance = np.linalg.norm(goose.position - self.position)
if distance < self.perception_radius:
neighbors.append(goose)
return neighbors
def align(self, neighbors):
# 计算邻近大雁的平均速度方向
avg_velocity = np.zeros(2)
for goose in neighbors:
avg_velocity += goose.velocity
avg_velocity /= len(neighbors)
# 返回对齐力
return (avg_velocity - self.velocity) * self.alignment_factor
def cohere(self, neighbors):
# 计算邻近大雁的中心位置
center = np.zeros(2)
for goose in neighbors:
center += goose.position
center /= len(neighbors)
# 返回向中心移动的力
return (center - self.position) * self.cohesion_factor
def separate(self, neighbors):
# 计算避免碰撞的力
move_away = np.zeros(2)
for goose in neighbors:
diff = self.position - goose.position
distance = np.linalg.norm(diff)
if distance > 0:
move_away += diff / (distance ** 2) # 距离越近,分离力越大
return move_away * self.separation_factor
class Flock:
def __init__(self, num_geese=20):
self.geese = []
for _ in range(num_geese):
x = random.uniform(-10, 10)
y = random.uniform(-10, 10)
vx = random.uniform(-0.1, 0.1)
vy = random.uniform(-0.1, 0.1)
self.geese.append(Goose(x, y, vx, vy))
def update(self):
for goose in self.geese:
goose.update(self.geese)
# 创建大雁群
flock = Flock(30)
# 设置动画
fig, ax = plt.subplots(figsize=(10, 8))
ax.set_xlim(-20, 20)
ax.set_ylim(-20, 20)
ax.set_title('大雁飞行模拟 - 基于Agent的建模')
ax.set_xlabel('X坐标')
ax.set_ylabel('Y坐标')
# 绘制大雁的箭头
quiver = ax.quiver([], [], [], [], color='blue', scale=10)
def update(frame):
flock.update()
# 更新箭头数据
positions = np.array([goose.position for goose in flock.geese])
velocities = np.array([goose.velocity for goose in flock.geese])
quiver.set_offsets(positions)
quiver.set_UVC(velocities[:, 0], velocities[:, 1])
return quiver,
# 创建动画
ani = FuncAnimation(fig, update, frames=200, interval=50, blit=True)
plt.grid(True, linestyle='--', alpha=0.7)
plt.show()
# 如果需要保存动画,取消下面的注释
# ani.save('goose_flock_simulation.gif', writer='pillow', fps=20)

被折叠的 条评论
为什么被折叠?



