基于Python模拟SFM社会力模型单房间疏散场景

一,实验报告 内容(名称):社会力模型仿真 院( 系) 名称 计算机学院 专业名称 计算机科学与技术 指导教师 宋晓 学号 18373584 姓名 甘天淳 二

本文包含相关资料包-----> 点击直达获取<-------

一、实验报告

内容(名称):社会力模型仿真

院( 系) 名称 计算机学院
专业名称 计算机科学与技术
指导教师 宋晓
学号 18373584
姓名 甘天淳

二、实验目的

​ 应用社会力模型,仿真模拟单房间疏散场景下的人员流动情况,熟悉社会力模型的基本方程和相关 的路径规划算法。在此基础上进行多次仿真,分析障碍物摆放位置和人员密度对总疏散时间和平均疏散 时间的影响,并对现实情况进行拟合,提出指导性意见。

三、数学模型描述

3.1 模型基本框架

​ 社会力模型是一种以牛顿力学为理论基础,假设行人受到社会力作用产生加速度从而运动的模型。 在该模型中,行人同时受到三种作用力的影响,即 驱动力、 人与人之间的作用力 、 人与障碍物之间的作用力 ,这三种作用力产生的合力作用于该行人,产生一个加速度,驱动行人运动。其中,驱动力是该个体对自己施加的社会力,体现了其在主观意识的影响下移动到目的地的需求;人与人之间的作用力是 周围其他个体对该个体施加的社会力,体现了其尽量与他人保持一定距离的需求;人与障碍物之间的作 用力是障碍物(或墙壁)对该个体施加的社会力,体现了其与障碍物保持一定距离的需求。

社会力模型的主要方程如下:

其中,

1

3.2 模型细节扩充

在基本框架的基础上,对模型细节做以下扩充及解释:

本实验中,选取图书馆单一房间的疏散情形为仿真场景,房间大小为x,仅存在单一出口且其在房间右侧,房间内有四个书架,大小分别为x,x。,房间构造例图如下:

图 1 房间构造例图

全过程中均将人员当做圆看待,其半径(即肩宽的一半)服从均匀分布,疏散开始时刻,人员在房 间内随机分布(不存在人员互相重叠或与墙壁重叠的情况),社会力模型公式中各常量取值、各变量取 值范围如下:

四、编程实现与调试过程

​ 本实验中,使用Python编写面向对象的程序,其接受初始时刻人员总数量、人员最大移动速度desired_speed作为输入参数,随机生成人员初始位置,在逐步推进时间的同时计算各人员收到的社会力及对应的加速度,更新其位置并显示在GUI上,除此之外,实时显示当前时间及房间中剩余人数,仿真结束后生成密度图。源代码的部分重要函数将以附录形式呈现,以下分三部分对代 码实现与运行结果做出解释。

4.1 数据结构与组织形式

​ 采用面向对象的程序构造方式,首先介绍仿真有关各类(由于篇幅限制略去方法的具体实现,仅以 注释形式给出重要方法的解释):

​ 二维向量 :用以描述二维平面中的力、速度、位置、方向等信息。

2

​ 圆形 :用以描述场景中的人员信息。

```python class Circle:

Attributes:

def init (self, x, y, vx, vy, mass, scene=None) def get_radius(self) def distance_to(self, other) # 计算与参数other的距离

根据other的类型(Circle,或墙或障碍物)分别计算

return: 距离向量

def is_intersect(self, other) def ped_repulsive_force(self) # 计算行人与其他行人间的排斥力

使用公式:

f_i = ∑(j)f_ij 结果

f_ij = A * e^((r_ij - d_ij) / B) * n_ij # r_ij = r_i + r_j 半径之和

d_ij = ||r_i - r_j|| 圆心距离

n_ij = (r_i - r_j) / d_ij 单位方向向量

return: 其他行人们对此人的合力f_i

def wall_repulsive_force(s)

```

盒子 :用以描述矩形墙壁与矩形障碍物信息。

```python class Box:

Attributes:

p1:

p2: 矩形对角线上的两个点的坐标。

def init (self, x1, y1, x2, y2) def scale(self, factor) def is_intersect(self, other) def is_in(self, pos) def center(self) def width(self) def height(self) ```

场景 :用以描述场景信息。

3

4.2 仿真主要函数解释

程序依次进行初始化、仿真、输出结果三个步骤,每个步骤中的主要函数解释如下:

初始化场景 :依次向场景中添加墙壁、障碍物、生成不互相重叠且不与墙壁障碍物重叠的若干人

员,构成初始时刻场景,并将其显示在 上,具体代码及解释如下:

```python def get_scene(person_num=10): scene = Scene() Scene.scale_factor = 36 scene.border = Vector2D(15.0, 15.0) # 设置场景大小 scene.boxes = [] scene.boxes.append(Box(0.0, 0.0, 10.0, 1.0)) scene.boxes.append(Box(0.0, 1.0, 1.0, 14.0)) scene.boxes.append(Box(0.0, 14.0, 10.0, 15.0)) scene.boxes.append(Box(10.0, 0.0, 11.0, 7.0)) scene.boxes.append(Box(10.0, 8.0, 11.0, 15.0)) # 设置墙壁 scene.boxes.append(Box(3.0, 2.0, 4.5, 6.0)) scene.boxes.append(Box(6.5, 2.0, 8.0, 6.0)) scene.boxes.append(Box(3.0, 9.5, 4.5, 13.0)) scene.boxes.append(Box(6.5, 9.5, 8.0, 13.0)) # 设置障碍物 scene.peds = [] for i in range(person_num): # 随机生成人员初始位置 ped = None num_tried = 0 while not is_valid(scene, ped): # 判断是否有重叠情况存在 ped = Circle(random.uniform(1, 10), random.uniform(1, 14), 0.5, 0.5, 80) num_tried += 1 if (num_tried >= 100): print("人数太多,找不到空位啦.实际人数: %d" % len(scene.peds)) break if num_tried >= 100: break scene.peds.append(ped) scene.dests = [] scene.dests.append(Box(11.0, 0.0, 15.0, 15.0)) # 设置目的地(即出口) return scene

```

开始仿真 :此函数被绑定到 的开始仿真按钮上,是程序的入口函数,具体代码及解释如下:

```python def begin_simulate(self):

steps_per_frame = 12

steps_cnt = 0

while self.scene.peds_arrived() != len(self.peds): # 循环直至所有人均离开

steps_cnt += 1

self.timeNow = self.timeNow + TIME_STEP # 更新当前仿真时间

self.timeNowStr.set("%.4f" % self.timeNow) # 更新当前剩余人数

self.remainPeople.set(len(self.peds) - self.scene.peds_arrived())

try:

self.scene.update() # 更新场景

except IndexError:

print("IndexError\n\n")

exit(0)

if steps_cnt < steps_per_frame:

continue

steps_cnt = 0

i= 0

for ped in self.peds:

= ped[0].pos.get_x()

= ped[0].pos.get_y()

= ped[0].get_radius()

self.canvas.coords(ped[1], (x - r, y - r, x + r, y + r))

if self.pre_peds:

pre_x = self.pre_pedsi.pos.get_x()

pre_y = self.pre_pedsi.pos.get_y()

self.canvas.create_line(x, y, pre_x, pre_y, fill=self.get_color(i + 10)) # 绘制移动路径

i+= 1

```

记录速度——密度 :在仿真过程中推进时间时记录下特定区域的人数与其中人员的速度,以供仿真 结束后生成速度——密度图。

路径搜索算法 :本实验中采用A 算法作为图论最短路算法,以下给出A 算法具体步骤如下:

算法的具体内容与解释。

​ 算法具体步骤如下:

  • 把起点加入 open list 。
  • 重复如下过程:
  • 遍历 open list ,查找 F 值最小的节点,把它作为当前要处理的节点。
  • 把这个节点移到 close list 。
  • 对当前方格的 8 个相邻方格的每一个方格?
    • 如果它是不可抵达的或者它在 close list 中,忽略它。否则,做如下操作。
    • 如果它不在 open list 中,把它加入 open list ,并且把当前方格设置为它的父亲,记录该方格的 F , G 和 H 值。
    • 如果它已经在 open list 中,检查这条路径 ( 即经由当前方格到达它那里 ) 是否更好,用 G 值作参考。更小的 G 值表示这是更好的路径。如果是这样,把它的父亲设置为当前方格,并重新计算它的 G 和 F 值。如果你的 open list 是按 F 值排序的话,改变后你可能需要重新排序。
  • 停止,当你

    • 把终点加入到了 open list 中,此时路径已经找到了,或者
    • 查找终点失败,并且 open list 是空的,此时没有路径。
  • 保存路径。从终点开始,每个方格沿着父节点移动直至起点,这就是所得的最终路径。

一个用A*算法搜索最短路径的例图如下:

图 2 A*算法寻路过程例图

本实验中,距离主要通过以下式子产生:

​ 其中,表示从起点沿着产生的路径移动到网格上指定方格的移动花费, 表示从网格上当前方格移动到终点的预估移动花费,本实验中 值采用曼哈顿方法,其计算当前格到目标格之间水平与垂 直方格的数量和而忽略对角线方向,是对剩余距离的一个估算。通过这个式子可以选择下一步的方向作 为社会力的驱动力部分。

​ 由于篇幅限制,此部分完整源代码请参见附录 1:路径搜索算法源代码 。

4.3 仿真结果与解释

​ 该程序完成了仿真的基本功能并实现了实时显示房间内剩余人数、实时显示人员具体路径等附加功 能。以初始时刻房间内人数为 的输入条件为例进行仿真,仿真开始前(图 3),仿真进行中(图 4),仿真结束后(图 5),实时显示路径的仿真进行中(图 6),实时显示路径的仿真结束后(图 7)的 程序界面截图分别如下所示:

图 3 仿真开始前

图 4 不带路径的仿真进行中 图 5 不带路径的仿真结束后

图 6 带路径的仿真进行中 图 7 带路径的仿真结束后

​ 图 8 速度—密度表 与 速度—密度图

4

​ 由图中可以看出,区域内人流密度较小时随着人流密度的增加平均速度略微增加,人流密度继续增 大时平均速度开始减小,且减小趋势趋于剧烈,当人流密度到达一定阈值时平均速度趋于稳定在一个较 低的水平。结合社会力模型基本方程,并与现实相联系,图像呈此趋势的可能原因是密度较小时人仅受 驱动力作用,速度达不到最大速度,密度略微增加时并不会阻塞人员前行的路线,而其后的人流会对其 施加一个向前的社会力,造成平均速度略微增加,体现为正向驱动作用,与现实情况也相符。密度继续 增加时若出口处已到达最大通行效率则其后人流会聚集在出口处造成平均速度大幅下降,且这种情况随 密度增加而愈加严重,平均速度大幅减少,直至区域内密度稳定且所有人速度相似且均较低,达到此阈 值后继续增大密度则对平均速度没有太大影响,此时速度很大程度上仅依赖于出口宽度,即出口处通行 效率,与现实情况符合也较好,充分说明了仿真具有良好的现实意义,也从侧面印证了社会力模型的合理性。

5

图 9 多次仿真结果表

将得到的多组数据绘制三维图像,如下所示:

图 10 两种视角下的撤离时间与输入参数的关系图(最大速度为 1m/s)

图 11 两种视角下的撤离时间与输入参数的关系图(最大速度为 2m/s)

分析以上仿真结果和图像的特点并做可能的解释如下:

  • 总体而言,初始时刻房间内人数越少,人员最大移动速度越大,出口宽度越大,撤离所需时间越 短,反之则均越低。
  • 固定人员最大移动速度和出口宽度不变,仅改变初始时刻房间内人数,撤离时间随人数的减少而近 似线性减少,且在人数减少到一定程度时趋于不变。其可能原因是人数较多时效率瓶颈在于出口处 通行效率低,由于出口处通过效率一定,则总撤离时间线性减少,而人数较少时出口不会聚集较大 人流,撤离时间与最远人员从初始点到达出口所需时间强相关。
  • 固定人员最大速度和初始时刻房间内人员数量不变,仅改变出口宽度,撤离时间随出口宽度增加而 近似指数减小,但在出口宽度达到一定长度时趋于不变。其原因可能是出口宽度较小时容易在出口 处积累大量人流,造成通行效率较低,增大出口宽度可以显著减轻此情况的程度,而出口宽度增大 到一定程度后每一时刻到达出口的人员都能直接通过出口,通行效率不再上升,因此总撤离时间趋 于不变。
  • 固定初始时刻房间内人员数量与出口宽度不变,仅改变人员最大移动速度,撤离时间在出口宽度足 够长时随人员速度减少而近似线性增加,在出口宽度较小时严重延长。其原因可能是出口宽度足够 时所有人走过相同路程情况下随速度不同时间近似线性变化,出口宽度较小时容易形成人流在出口 处积累,此时较慢的速度会严重延长出口通过效率,造成总撤离时间大幅延长。
  • 通过观察仿真过程中具体人流分布可以看出,出口宽度越小,越容易出现出口处形成倒三角形人流 并造成通行效率大幅下降的情况,如下图 8 所示,在此基础上若倒三角形两侧人员质量相似则会出 现没有人可以通过出口的情形出现(即互不相让),造成仿真异常,这也是社会力模型仿真的不足 之处之一,如下图 9 所示。

图 12 出口宽度较小时形成的倒三角形人流 图 13 均无法通过出口的情形

五、与现实的联系

由上述仿真结果可以看出,增大出口宽度,增大人员最大速度,减小初始时刻人员数量均可以缩短 总撤离时间,因此从缩短意外情况发生时撤离时间的考虑对博物馆/图书馆单房间的设计提出若干建议 如下:

  • 适当拓宽出口宽度,若出口宽度一定则可以通过开启多个出口的措施实现总出口宽度的扩宽。同 时,需要将出口设置在合理的位置,也可以在特定的地点设置专用出口。
  • 限制人员密度,可以通过施行分批游览的方式将人员密度控制在一个合理的范围内,从而控制总撤 离时间。
  • 优化展品/书架等障碍物摆放位置,优化人员前进路线,使得意外情况发生时能够有序撤离。
  • 关注老年人及残障人士,其较慢的行进速度会影响房间内整体撤离效率,故应增设专门的出口或严 格控制房间内该类人员数量。

附录 1:路径搜索算法源代码

```python 1 from SFM.BasicClasses import * 2 from numpy import source 3 import pandas as pd 4 5 class Node_Elem: 6 def index (self, x, y, dist): 7 self.x = x 8 self.y = y 9 self.dist = dist 10 11 class AStarPathFinder: 12 def init (self): 13 self.open = [[]] 14 self.close = [[]] 15 self.path = [[]] 16 17 @staticmethod 18 def get_direction(scene, source, number): 19 # 寻找路径,获得下一步运动的方向 20 # scene是Scene类型,source是行人(Circle类型) 21 # return: 返回期望方向e,类型为Vector2D,要求e是单位向量e.x^2 + e.y^2 = 1 22 self.number = number 23 self.source = source 24 self.scene = scene 25 point = Node_Elem(self.source.pos.x, self.source.pos.y, 0.0) 26 new_point = self.extend_round(point) 27 return Vector2D(0, 0) 28 29 def find_path(self): 30 point = Node_Elem(self.source.pos.x, self.source.pos.y, 0.0) 31 while True: 32 self.extend_round(point) # 如果这个节点的开放列表为空,不存在路径 33 if not self.open[self.number]: 34 return # 获取F值最小的节点 35 idx ,point = self.get_best() # 找到路径,生成路径,返回 36 if self.is_target(point): 37 print("We have arrived the aim") 38 return point # 找到了下一点,就找到了方向,把此节点压入关闭列表 # 并从开放列表里删除 39 self.close[self.number].append(point) 40 del self.open[self.number][idx] 41 return point 42 43 def is_target(self, i): 44 large_x = self.scene.dests.p1.x if self.scene.dests.p1.x >= self.scene.dests.p2.x else self.scene.dests.p2.x 45 small_x = self.scene.dests.p1.x if self.scene.dests.p1.x <= self.scene.dests.p2.x else self.scene.dests.p2.x 46 large_y = self.scene.dests.p1.y if self.scene.dests.p1.y >= self.scene.dests.p2.y else self.scene.dests.p2.y 47 small_y = self.scene.dests.p1.y if self.scene.dests.p1.y <= self.scene.dests.p2.y else self.scene.dests.p2.y 48 if small_x <= i.x and i.x <= large_x: 49 if small_y <= i.y and i.y <= large_y: 50 return True 51 return False 52
53 def extend_round(self, point): 54 xs = (-1, 0, 1, -1, 1, -1, 0, 1) 55 ys = (-1, -1, -1, 0, 0, 1, 1, 1) 56 for x, y in zip(xs, ys): 57 new_x, new_y = x + point.x , y+ point.y # 表示每次向某个方向移动 58 # 无效或者不可行走区域,则 勿略 59 if not self.is_valid_coord(new_x, new_y): 60 continue 61 new_point = Node_Elem(new_x, new_y, point.dist + self.get_cost(point.x, point.y, new_x, new_y)) # 如果已经在close列表中 62 if self.node_in_close(new_point): 63 continue 64 i = self.node_in_open(new_point) 65 if i != -1: # 新节点在开放表,更新距离 66 if self.open[self.number][i].dist > new_point.dist: 67 self.open[self.number][i].dist = new_point.dist 68 # 现在的路径到比以前到这个节点的路径更好~,则使用现在的 路径 69 # 类似于Dijkstra算法 70 continue 71 self.open[self.number].append(new_point)# 新节点不在表中,加入开放 表 72 return 73
74 def get_best(self): 75 best = None 76 bv = 1000000 77 bi = -1 78 for idx, i in enumerate(self.open[self.number]): 79 value = self.get_dist(i) 80 if value < bv: 81 best = i 82 bv = value 83 bi = idx 84 return bi, best # best即是未选中表中的距离 最近的 85
86 def get_dist(self, i): 87 return i.dist + math.sqrt() 88
89 def get_cost(self, x1, y1, x2, y2): 90 if x1==x2 or y1==y2: 91 return 1.0 92 return 1.4 93
94 def node_in_close(self, node): 95 for i in self.close[self.number]: 96 if node.x == i.x and node.y==i.y: 97 return True 98 return False 99
100 def node_in_open(self, node):

```

参考文献

  • 基于SSH社区事务综合管理系统(江西农业大学·纪美珍)
  • 暂住人口管理系统的设计与实现(电子科技大学·孙建政)
  • 三维数字化社区系统的设计与实现(兰州大学·宋毅)
  • 基于loushang平台的救助资源管理系统的设计与实现(电子科技大学·张珂)
  • 基于SAN的存储管理软件的设计与实现(西北工业大学·可彦)
  • 基于物联网的可视化火灾监测逃生救援系统(重庆大学·罗鑫)
  • 分布式应用系统的研究与开发(武汉理工大学·廖斌)
  • 基于三维扩散模型的火灾仿真与逃生系统设计与实现(华南理工大学·李纯如)
  • 基于SSM应急资源管理系统的设计与实现(华中师范大学·郑强程)
  • 基于物联网的可视化火灾监测逃生救援系统(重庆大学·罗鑫)
  • 基于Spring boot框架的物联网智慧消防系统(武汉工程大学·童学洲)
  • 智能消防联网报警监测平台的设计与实现(重庆大学·李兰逸)
  • 基于.NET的煤矿井下安全生产空间网络分析系统(吉林大学·何颖)
  • 智慧小镇人群行为及疏散仿真平台的研究与验证(北京邮电大学·黄兴彬)
  • 基于J2EE的社区管理平台的设计与实现(厦门大学·咸敏燕)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设客栈 ,原文地址:https://m.bishedaima.com/yuanma/35692.html

相关推荐

  • 新手python简单的飞机游戏

    game 一个新手做的python简单的飞机游戏 参考文献 基于Java EE的个人博客管理系统的设计和实现(内蒙古大学·闫伟光) 深度可定制的工具化爬虫系统的设计与实现(北京邮电大学·李笑语) 航空订票服务器爬虫检测技术研究(杭州电子科技大学·陈万烤) 主题爬虫关键技术研究(哈尔滨工程大学·黄正德) 机票票价预测系统设计与实现(大连理工大学·陈岩松) 深度可定制的工具化爬虫系统的设计与实现(北京邮电大学·李笑语) 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航) 基于B/S架构的酷跑社区系统的设计与实现(内蒙古大学·张晓乐) 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航) 机票票价预测系统设计与实现(大连理工大学·陈岩松) 山东航空货运业务管理系统的设计与实现(山东大学·高辉) 飞行情报资料管理信息系统设计与实现(中国地质大学(北京)·张晓琴) 山东航空货运业务管理系统的设计与实现(山东大学·高辉) 豆玩手机游戏平台的设计与实现(吉林大学·李天明) 面向高职信息技术教育的严肃游戏设计与实施(大连理工大学·王晓姝)
    2024年05月14日
    1 1 1
  • 基于python制作一个打砖块小游戏

    基于 python 制作一个打砖块小游戏 导语 想起来好久没更这个系列的文章了,周末过来补一波好了,本期我们将利用 python 制作一个打砖块小游戏
    2024年05月14日
    1 1 1
  • 基于python实现的电梯调度

    基于python实现的电梯调度 1 项目说明 1,1 项目目的 通过实现电梯调度,体会操作系统调度过程 学习特定环境下多线程编程方法 学习调度算法 1
    2024年05月14日
    5 1 3
  • 基于JSP的校园论坛BBS网站的设计与实现

    基于JSP的校园论坛BBS网站的设计与实现 1 概述 开发校园论坛系统的目的是提供一个供我校学生交流的平台,为我校学生提供交流经验,探讨问题的社区,因此
    2024年05月14日
    21 1 1
  • 基于SSM框架实现的员工信息管理系统

    1,项目简介 这是完整使用SSM框架开发的第一个项目,项目来源于北京动力节点的SSM框架整合教程,其中加入了一些自己的理解,增加了一个搜索功能的页面,这个项目总体来说对于新手是很友好的
    2024年05月14日
    2 1 1
  • 基于JSP的聊天器

    基于JSP的聊天器 1 可行性研究 1,1 技术条件方面的可行性 系统:Windows 8,1 Update 服务器环境:nodejs 0
    2024年05月14日
    7 1 1
  • 基于SpringBoot框架的在线互动学习网站

    这是一套采用Java语言,基于SpringBoot框架构建的在线教育互动平台的源代码,项目采用了SpringBoot和Vue技术栈,开发工具为Idea或Eclipse
    2024年05月23日
    5 1 3
  • 解谜类游戏之Python

    解谜类游戏 一,摘要 作者:霍禹佳,高铭星,朱子仪,梁鞍華 [摘要] 本作融合了企鹅,史诗英雄故事,解谜和游戏这四种元素,创造出一款全新的解谜类游戏,通过对故事
    2024年05月14日
    1 1 1
  • 基于Python制作愤怒的小鸟小游戏

    基于 Python 制作愤怒的小鸟小游戏 导语 小伙伴们周末愉快呀~楼主又好久没更新公众号的样子,为了避免继续被某些小伙伴吐槽,还是上来更新一波吧,既然是周末
    2024年05月14日
    6 1 2
  • 基于SpringBoot框架的网页时装购物系统

    这是一套采用Java语言开发的🔥🔥SpringBoot为核心的电商时装网站项目源代码🔥🔥,该项目运用了SpringBoot框架和Vue技术,支持在Idea或Eclipse开发环境中运行
    2024年05月23日
    10 1 2

发表回复

登录后才能评论