社会力模型:Social force model for pedestrian dynamics
Social Force Model——社会力模型-CSDN博客
简介:
时间:1995
期刊:《Physical Review E》
作者:Dirk Helbing and P´eter Moln´ar
摘要:
提出一种描述行人运动的“社会力模型”。认为行人的运动可看作是受到一系列“社会力”的驱动,这些力反映了行人内在的动机,而非直接由外部物理接触产生。
模型主要包括以下几个方面:
加速项:行人以一定的期望速度前进,当实际速度偏离目标速度时,会有一个加速/减速过程使其趋向期望速度。
相互排斥力:行人与其他行人或障碍物之间保持一定距离,这种排斥作用通过一个随距离呈指数衰减的势能函数来描述。
吸引力:在某些情境下,行人会受到其他个体或物体的吸引,例如朋友、街头表演者或橱窗展示。
该模型将上述各项“力”相加,构成非线性耦合的 Langevin 方程,从而模拟行人群体的自组织现象,如动态车道形成以及通过狭窄通道时的往复交替现象。
创新点:
①首次将“社会力”这一概念引入行人运动的建模中
②多项力的综合考虑
③非线性耦合 Langevin 方程模拟随机性带来的个体差异和突发现象
④扩展性与普适性
相关工作:
加速项:
他/她想要尽可能舒适地到达某个目的地
:行人实际位置
:行人的目标位置
如果行人的运动不受干扰,他/她将以一定的期望速度向期望方向
行走
:实际速度偏差
:期望速度
:松弛时间
相互排斥力:
行人与行人距离:
他/她与其他行人保持一定的距离
:行人
和行人
之间由于距离
产生的排斥势能
:行人
和行人
相对位置
原因:行人需要空间来进行下一步,而其他行人会考虑到这一点
行人与建筑距离:
行人还与建筑物、墙壁、街道、障碍物等的边界保持一定的距离。
: 行人
和障碍物 B 之间由于距离
而产生的排斥势能
:行人
和障碍物 B 相对位置
吸引力:
行人有时会被其他人(朋友、街头艺术家等)或物品(如橱窗展示)吸引。
:函数,表示行人
对目标 i 的吸引力势能,这个势能随时间 t 和行人与目标之间的距离
变化
:行人
由于目标 i 存在而感受到的吸引力
:行人
和目标 i 之间的相对位置向量
与排斥力不同,吸引力通常随着时间 t 递减,因为行人对目标兴趣会随着时间推移而减少。
总效应:
综上所述,排斥和吸引对行人行为的影响由式给出
社会力模型定义:
图示:
增加了一个波动项,它考虑了行为的随机变化。
相关代码:
参考代码:
foreach(Agent agent in Agents)
{
if (agent.IsActivity == true)
{
Vector2 self_Force = Get_Self_Force(agent);
Vector2 other_Force = Get_OtherAgents_Force(agent);
Vector2 obstacle_Force = Get_Obstacle_Force(agent);
Vector2 Sum = self_Force + other_Force + obstacle_Force;
Vector2 Dex_speed = Sum / agent.Mass * Paramaters._ε;
agent.Real_speed += Dex_speed * Paramaters._Scale;
agent.Real_speed = GetRealSpeed(agent);
agent.Position = new PointF(agent.Position.X + (agent.Real_speed.X * Paramaters.TimeStep),
agent.Position.Y + (agent.Real_speed.Y * Paramaters.TimeStep));
agent.Self = new RectangleF((agent.Position.X - agent.Radius), (agent.Position.Y - agent.Radius), agent.Radius * 2f, agent.Radius * 2f);
}
}
示例实现:
缺少吸引力部分
import numpy as np
import matplotlib.pyplot as plt
# 定义行人类
class Pedestrian:
def __init__(self, pos, vel, desired_direction, v0, tau):
self.pos = np.array(pos, dtype=float) # 当前位置 (二维向量)
self.vel = np.array(vel, dtype=float) # 当前速度 (二维向量)
self.desired_direction = np.array(desired_direction, dtype=float) # 期望运动方向(单位向量)
self.v0 = v0 # 期望速度
self.tau = tau # 调整时间常数
# 驱动力:行人向其期望速度加速
def driving_force(ped):
desired_velocity = ped.v0 * ped.desired_direction
return (desired_velocity - ped.vel) / ped.tau
# 排斥力函数:简单采用指数衰减模型
def repulsive_force(ped_i, ped_j, A=2.0, B=0.3):
r_ij = ped_i.pos - ped_j.pos
distance = np.linalg.norm(r_ij)
if distance == 0:
return np.array([0.0, 0.0])
# 指向 ped_i 的单位向量
direction = r_ij / distance
# 排斥力大小
force_magnitude = A * np.exp(-distance / B)
return force_magnitude * direction
# 更新单个行人状态:合成所有作用力并更新速度与位置
def update_pedestrian(ped, pedestrians, dt):
F_drive = driving_force(ped)
F_rep_total = np.array([0.0, 0.0])
# 计算来自其他行人的排斥力
for other in pedestrians:
if other is not ped:
F_rep_total += repulsive_force(ped, other)
# 总作用力
F_total = F_drive + F_rep_total
# 更新速度(简单欧拉积分)
ped.vel += F_total * dt
# 更新位置
ped.pos += ped.vel * dt
# 主函数:初始化行人并进行简单模拟
def simulate(num_pedestrians=20, steps=500, dt=0.1):
pedestrians = []
# 随机生成行人初始状态
for _ in range(num_pedestrians):
pos = np.random.rand(2) * 10 # 在 10x10 区域内随机位置
vel = np.zeros(2)
# 设定所有行人均朝右运动
desired_direction = np.array([1.0, 0.0])
v0 = 1.3 # 期望速度
tau = 0.5 # 调整时间常数
pedestrians.append(Pedestrian(pos, vel, desired_direction, v0, tau))
# 用于存储轨迹便于后续绘图
trajectories = [ [ped.pos.copy()] for ped in pedestrians ]
for _ in range(steps):
# 更新每个行人的状态
for ped in pedestrians:
update_pedestrian(ped, pedestrians, dt)
# 保存轨迹数据
for i, ped in enumerate(pedestrians):
trajectories[i].append(ped.pos.copy())
# 绘制所有行人的轨迹
plt.figure(figsize=(8, 8))
for traj in trajectories:
traj = np.array(traj)
plt.plot(traj[:, 0], traj[:, 1])
plt.scatter(traj[0, 0], traj[0, 1], c='green', marker='o') # 起点
plt.scatter(traj[-1, 0], traj[-1, 1], c='red', marker='x') # 终点
plt.title("社会力模型下行人运动轨迹")
plt.xlabel("X 位置")
plt.ylabel("Y 位置")
plt.grid(True)
plt.show()
if __name__ == "__main__":
simulate()