m基于鱼群优化算法的的三维场景下人员疏散系统matlab仿真

news2024/11/28 3:35:25

目录

1.算法描述

2.仿真效果预览

3.MATLAB核心程序

4.完整MATLAB


1.算法描述

        人工鱼群优化算法,模仿鱼群的行为特点而设计的一种寻优策略。人工鱼群算法(Artificial Fish Swarm Algorithm,AFSA)是Li Xiao-lei在2002年提出的(Yazdani, Toosi, & Meybodi, 2010),目的是模仿鱼类捕食、群集、跟随、移动等行为。AFSA是基于鱼类集体向某个目标运动,并受到自然的启发,是一种并行和随机搜索算法。与狮子和猴子不同,在像鱼类这种动物物种中没有领导者,每个成员都有自我组织的行为。鱼对它们的群体和环境一无所知,通过相邻成员之间的数据交换在环境中随意移动,这种交互作用为鱼群优化带来了更多的复杂性。

        在一片水域中,鱼往往能自行或尾随其他鱼找到营养物质多的地方,因而鱼生存数目最多的地方一般就是本水域中营养物质最多的地方,人工鱼群算法就是根据这一特点,通过构造人工鱼来模仿鱼群的觅食、聚群及追尾行为,从而实现寻优。

人工鱼拥有以下几种典型行为:

(1)觅食行为:一般情况下鱼在水中随机地自由游动,当发现食物时,则会向食物逐渐增多的方向快速游去。

(2)聚群行为: 鱼在游动过程中为了保证自身的生存和躲避危害会自然地聚集成群,鱼聚群时所遵守的规则有三条:

分隔规则:尽量避免与临近伙伴过于拥挤;

对准规则:尽量与临近伙伴的平均方向一致;

内聚规则:尽量朝临近伙伴的中心移动。

(3)追尾行为:当鱼群中的一条或几条鱼发现食物时,其临近的伙伴会尾随其快速到达食物点。

(4)随机行为:单独的鱼在水中通常都是随机游动的,这是为了更大范围地寻找食物点或身边的伙伴。

人工鱼有四种基本行为,包括觅食Pray、聚群Swarm、追尾Follow和评价行为bulletin。

3.1 觅食行为

       这是鱼趋向食物的一种活动,一般认为它是通过视觉或味觉来感知水中的食物量或食物浓度来选择行动的方向。

       设置人工鱼当前状态,并在其感知范围内随机选择另一个状态,如果得到的状态的目标函数大于当前的状态,则向新选择得到的状态靠近一步,反之,重新选取新状态,判断是否满足条件。

       选择次数达到一定数量后,如果仍然不满足条件,则随机移动一步。

3.2 聚群行为

       大量或少量的鱼聚集成群,进行集体觅食和躲避敌害,这是它们在进化过程中形成的一种生存方式。

       人工鱼探索当前邻居内的伙伴数量,并计算伙伴的中心位置,然后把新得到的中心位置的目标函数与当前位置的目标函数相比较,如果中心位置的目标函数优于当前位置的目标函数并且不是很拥挤,则当前位置向中心位置移动一步,否则执行觅食行为。

      鱼聚群时会遵守两条规则:一是尽量向邻近伙伴的中心移动,二是避免过分拥挤。

3.3 追尾行为

       当某一条鱼或几条鱼发现食物时,它们附近的鱼会尾随而来,导致更远处的鱼也会尾随过来。

        人工鱼探索周围邻居鱼的最优位置,当最优位置的目标函数值大于当前位置的目标函数值并且不是 很拥挤,则当前位置向最优邻居鱼移动一步,否则执行觅食行为。

3.4 随机行为

       它是觅食行为的一个缺省行为,指人工鱼在视野内随机移动。当发现食物时,会向食物逐渐增多的方向快速的移动。

2.仿真效果预览

matlab2022a仿真结果如下:

 

 

3.MATLAB核心程序

%% 更新所有节点的等待队列
    for i = 1:length(nodes_id)
        node = nodes_id(i);
        people_waitting_in_current_node = cell2mat(p_in_node(node));
        people_node_waitting = [people_node_waitting,people_waitting_in_current_node];
    end
    people_node_waitting = setdiff(people_node_waitting,people_prepare_moving);
    %% 更新正在移动的队列
    people_moving = [people_moving,people_prepare_moving];
    
    %% 判断当前是否有边内等待的人,如果有,先遍历他们,让他们进入目标节点
    people_side_index = [];   %记录从边内等待状态转变为进入节点内的那些人在people_side_waitting中的索引
    people_node_index = [];   %记录进入某个节点的人在people_side_waitting中的索引
    for i = 1:length(people_side_waitting)
        p = people_side_waitting(i);
        path = cell2mat(path_all(p));
        
%         from_node = path(end-1);
%         to_node = path(end);
        if length(path)>1
           from_node = path(end-1);
           to_node   = path(end);
        else
           from_node = path(end);
           to_node   = path(end);
        end
        
        %如果到达的是终点,则记录
        if ismember(to_node,destination_nodes)
            people_side_index = [people_side_index,i];
            people_node_index = [people_node_index,i];
            arrival_exit_people = [arrival_exit_people,p];
            
            Sum_node(to_node) = Sum_node(to_node)+1;
            diff = setdiff(p,cell2mat(p_in_node(to_node)));
            p_in_node(to_node) = { [cell2mat(p_in_node(to_node)) , diff]};
    
            people_in_side = cell2mat(p_in_side(from_node,to_node));
            people_in_side = setdiff(people_in_side,p);
            p_in_side(from_node,to_node) = {people_in_side};
            p_in_side(to_node,from_node) = {people_in_side};
            Sum_side(from_node,to_node) = Sum_side(from_node,to_node) -1;
            Sum_side(to_node,from_node) = Sum_side(from_node,to_node);

            t_left(p) = NaN;
            t(p) = t(p) + t_move(p) + t_wait_node(p) + t_wait_side(p); 
            % 进入后,该人的移动时间、节点内等待时间、边内等待时间均置零
            t_move(p) = 0;
            t_wait_node(p) = 0;
            t_wait_side(p) = 0;
            exit_num = exit_num + 1;
        elseif Sum_node(to_node)<nodes_capacity(to_node)
            %% 如果所到达的节点没有超过容量限制,就进入
            people_side_index = [people_side_index,i];
            people_node_index = [people_node_index,i];

            Sum_node(to_node) = Sum_node(to_node)+1;
            diff = setdiff(p,cell2mat(p_in_node(to_node)));
            p_in_node(to_node) = { [cell2mat(p_in_node(to_node)) , diff]};

            people_in_side = cell2mat(p_in_side(from_node,to_node));
            people_in_side = setdiff(people_in_side,p);
            p_in_side(from_node,to_node) = {people_in_side};
            p_in_side(to_node,from_node) = {people_in_side};
            Sum_side(from_node,to_node) = Sum_side(from_node,to_node) -1;
            Sum_side(to_node,from_node) = Sum_side(from_node,to_node);
            if i>=length(first_people)
               exit_num  = exit_num + 1;
            end
        else
            %% 如果超过了容量限制,则继续等待,不需要做任何操作
            if i>=length(first_people)
               exit_num  = exit_num + 1;
            end
        end
    end
    if ~isempty(people_side_waitting)
       %% 更新进入节点后,节点和人的属性
        in_node_people = people_side_waitting(people_node_index);
        t(in_node_people) = t(in_node_people) + t_move(in_node_people) + t_wait_node(in_node_people) + t_wait_side(in_node_people); 
        % 进入后,该人的移动时间、节点内等待时间、边内等待时间均置零
        t_move(in_node_people) = 0;
        t_wait_node(in_node_people) = 0;
        t_wait_side(in_node_people) = 0;
        %% 更新边内等待队列
        people_side_waitting(people_side_index) = [];
    end


    %% 遍历所有边,获取边上 正在移动的 人群的移动速度和剩余到达时间
    v([people_prepare_moving,people_node_waitting,people_side_waitting]) = 0;   %除了到达终点和正在移动的人的人,其他人的速度都置零
    t_left(people_prepare_moving) = 0;  % 准备移动的人,剩余时间置0
    t_left([people_node_waitting,people_side_waitting]) = -1;   % 正在等待的人,剩余时间置-1
%     d_left([people_node_waitting,people_side_waitting]) = 0;   % 正在等待的人,剩余距离置0
    index = find(d_left < 1e-3);
    d_left(index) = 0;
    side_visited_flag = zeros(length(start));
    for i = 1:nodes_number
        for j = 1:nodes_number
            %% 如果没有访问过这条边,则访问
            if side_visited_flag(i,j) == 0
                people_in_side = cell2mat(p_in_side(i,j));
                people_prepare_moving_cur = people_in_side(find(t_left(people_in_side)==0));    %当前边上准备移动的人
                people_moving_cur = people_in_side(find(t_left(people_in_side)>0)); %当前边上正在移动的人
                %%
                if(~isempty([people_prepare_moving_cur,people_moving_cur]))
                     %% 非空代表该边上有人准备移动或者正在移动,可以计算他们的移动速度和剩余到达时间,对边上的人进行遍历
                     for k = 1:length(people_in_side)
                         p = people_in_side(k);
                         path = cell2mat(path_all(people_in_side(1)));
                         from_node = path(end-1);
                         to_node = path(end);
                         side_visited_flag(from_node,to_node) = 1;
                         side_visited_flag(to_node,from_node) = 1;
                         delta_sides(from_node,to_node) = Sum_side(from_node,to_node)/sides_capacity(node,next_node);
                         if ismember(p,people_moving_cur) %如果是正在移动的人
                             d_left(p) = d_left(p) - v(p)*min_t_move;    %用之前的速度和时间,计算正在移动的人剩余的距离,用于下面t_left的计算
                             v(p) = v0 * exp(-delta_sides(from_node,to_node) * gamma1 * gamma2);    %速度更新
                             t_left(p) = d_left(p) ./ v(p);      %用正在移动的人的剩余距离和新的移动速度,计算剩余移动时间
                         else %如果是准备移动的人
                             d_left(p) = distance(from_node,to_node);
                             v(p) = v0 * exp(-delta_sides(from_node,to_node) * gamma1 * gamma2);    %速度更新
                             t_left(p) = distance(from_node,to_node) ./ v(p);
                         end
                     end
                end
            end
        end
    end

02_116m

4.完整MATLAB

V

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91910.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全网惟一面向软件测试人员的Python基础教程-在Python中怎么干倒字符串?

全网惟一面向软件测试人员的Python基础教程 起点&#xff1a;《python软件测试实战宝典》介绍 第一章 为什么软件测试人员要学习Python 第二章 学Python之前要搞懂的道理 第三章 你知道Python代码是怎样运行的吗&#xff1f; 第四章 Python数据类型中有那些故事呢&#xff1f;…

邂逅Vue3和Vue3开发体验

文章目录01-邂逅Vue3和Vue3开发体验Vue3带来的变化如何使用Vue方式一&#xff1a;CDN引入方式二——下载和引入计数器案例原生实现Vue实现MVVMtemplate写法一写法二datamethod其他属性01-邂逅Vue3和Vue3开发体验 Vue3带来的变化 如何使用Vue 方式一&#xff1a;CDN引入 <d…

Hadoop 综合实训(编写ing)

文章目录一&#xff0c;显示文件内容&#xff08;一&#xff09;启动hadoop服务&#xff08;二&#xff09;创建并上传本地文件&#xff08;1&#xff09;创建students.txt文件&#xff08;2&#xff09;上传文件到HDFS&#xff08;三&#xff09;创建Maven项目&#xff1a;Dis…

windows11执行python没有任何反应或拉起应用商店的解决办法

1 是什么&#xff08;现象&#xff09; 高高兴兴的用上新电脑&#xff0c;系统Windows11&#xff0c;结果发现用power shell执行python姿势不对。 python bioParser.py 点击Enter&#xff0c;结果秒结束&#xff01;而我的python脚本明明有很多打印&#xff01; 如果只执行py…

服务机器人“大战”进入下半场,竞争焦点变了

对于机器人企业而言&#xff0c;“卖出去”是商业本质。 如何“卖出去”&#xff0c;往往是企业之间的竞争焦点&#xff0c;它也许是技术&#xff0c;也许是营销&#xff0c;但随着服务机器人大战进入下半场&#xff0c;服务机器人的竞争焦点正在发生根本上的改变。 竞争焦点…

Docker:基于Docker对中间件进行配置、安装和使用操作合集

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、rabbitmq启动rabbitmq设置rabbitmq用户进入rabbitmq容器内部设置外界访问用户二、mongodb安装mongo启动mongodb配置及使用mongodb三、Redis1.安装redis2.启动…

同一台服务器上多版本PHP切换(apache2 php8.2 php7.2)

我们有时会在同一台服务器上搭建多个版本的PHP&#xff0c;用来测试不同的程序。可是如何在多个版本之间切换呢&#xff1f;本文以ubuntu1804Server为例给大家进行讲解示范。 环境 ubuntu1804server 4.15.0-200-genericapache2php 7.4php 8.2 1.安装apche2 apache2的安装非…

【项目管理】项目中的进度管理,你知道多少?

有效实施项目进度计划&#xff0c;是项目成功的重要保障&#xff0c;项目进度管理也是每位项目经理都非常重视的问题。 项目中的进度管理可以帮助您了解项目当前进度&#xff0c;估计项目是否能顺利完成。 项目管理就是通过的对知识、技能、工具的运用对项目活动进行管理&am…

星环数据云平台 TDC 3.1 发布,新增滚动重启、存储回收站等八大核心功能

近日&#xff0c;星环数据云平台 Transwarp Data Cloud &#xff08;以下简称 TDC&#xff09;正式推出 3.1 版本。TDC 是采用云原生技术&#xff0c;融合星环科技全系产品打造的统一 PaaS 平台&#xff0c;可以为企业提供数据流通交易平台、企业湖仓一体数据湖、企业数据中台、…

Redis框架(十四):大众点评项目 基于Redis实现点赞功能实现

大众点评项目 基于Redis的点赞功能实现需求&#xff1a;基于Redis实现点赞功能实现业务实战总体代码展示总结SpringCloud章节复习已经过去&#xff0c;新的章节Redis开始了&#xff0c;这个章节中将会回顾Redis实战项目 大众点评 主要依照以下几个原则 基础实战的Demo和Coding…

解读一个四路组相联cache代码

解读一个四路组相联cache代码 在《计算机组成原理&#xff0c;软硬件接口》中&#xff0c;第五章便是cache的学习。本人初学cache&#xff0c;难免有疏漏之处&#xff0c;源代码github地址&#xff1a;https://github.com/airin711/Verilog-caches 1、四路组相联cache主要特征…

Milvus 2.1.x 到 Milvus 2.2.x 升级实践

近日&#xff0c;Milvus 2.2.0 发布&#xff0c;新版本里支持了许多激动人心的功能&#xff0c;包括&#xff1a;磁盘索引&#xff08;DiskANN&#xff09;、从文件中批量导入数据&#xff08;bulk_insert&#xff09;、基于角色的访问控制&#xff08;RBAC&#xff09;、集合生…

Linux | 网络概念理解 | 对网络的初始

文章目录重新看待计算机体系结构软件分层的思想网络中的分层协议的理解局域网的理解MAC地址 && IP地址报头的作用端口号&#xff08;port&#xff09;重新看待计算机体系结构 计算机由硬件组成&#xff0c;而不同硬件之间要怎么通信&#xff0c;或者说要怎么进行数据的…

MySQL——count(*)的底层实现以及相关优化

在开发系统的时候&#xff0c;可能需要需要计算一个表的行数这时候你可能会想&#xff0c;一条 select count(*) from t 语句不就解决了吗&#xff1f; 但是&#xff0c;会发现随着系统中记录数越来越多&#xff0c;这条语句执行得也会越来越慢。然后可能就想了&#xff0c;My…

盘点2022企业网络安全的七大成功要素

网络安全弹性已成为企业的重中之重&#xff0c;高达62%的受访企业在过去两年中经历了影响业务的安全事件。 最流行的四大攻击事件类型是&#xff1a; 1)网络或数据泄露&#xff08;51.5%&#xff09; 2)网络或系统中断&#xff08;51.1%&#xff09; 3)勒索软件事件&#x…

openpnp - 软件调试环境搭建

文章目录openpnp - 软件调试环境搭建概述笔记openpnp官方站点将openpnp工程克隆到本地将openpnp的wiki工程克隆到本地查看openpnp开发指南根据openpnp开发指南搭建openpnp开发环境IDE的选择IntelliJ IDEA学习版的安装引入openpnp工程在IDEA中, 运行openpnp主程序配置IntelliJ I…

工业手持终端并非“单兵作战”,5G智能模组时刻在线赋能

随着智能终端技术的不断演进&#xff0c;稳定性、实时性和续航能力强的工业手持终端为移动通信、消费电子、工业信息采集等领域提供便捷、高效的数据采集、存储、传输等功能服务。在智慧物流、智慧零售、智能制造、智慧医疗等领域&#xff0c;工业手持终端仍表现出需求激增、功…

Neuron 2.3.0 发布:更轻松地接入和管理海量工业设备

Neuron 2.3.0 版本现已正式发布&#xff01; 除了新增数据统计、模糊搜索、页面下载日志等功能提升产品易用性外&#xff0c;Neuron 2.3.0 版本还新增了 CIP Ethernet/IP、Mitsubishi Melsec 1E frame E71 和 Fanuc Focas 三个协议驱动&#xff0c;以更强大的能力帮助工业用户…

chatgpt使用教程

** 使用门槛&#xff1a;需要自行准备能开全局代理的科学上网工具 好评赠送免费科学上网工具&#xff0c;也可以自己准备科学工具。 ** 下单以后&#xff0c;我们会发送一串账号密码给您。如图&#xff1a; 其中卡号就是chatgpt的账号&#xff0c;密码就是chatgpt密码。 第…

数据结构---优先队列

优先队列实现方式入队出队JAVA实现总结二叉堆是实现优先队列的基础&#xff0c;上一篇二叉堆博文&#xff1a; 二叉堆队列的特点是先进先出&#xff08;FIFO&#xff09;。 优先队列不再遵循先入先出的原则&#xff0c;而是分为两种情况。 最大优先队列&#xff0c;无论入队顺…