GPSR路由算法的MATLAB实现

GPSR基于节点地理位置路由信息,采用贪婪策略和右手准则的结合在邻居节点中选择下一跳节点进行数据转发。节点在进行路由选择时,只需知道自己、邻居和目标节点的地理位置信息,无需维护全局网络的链路状态,这在很大程度上降低了网络开销。同时,节点在数据转发时总是选择比自己近的且到目标节点距离最近的邻居节点作为下一跳。这不仅减少了所选路径的跳数,而且缩短了数据传输的路径总长度,整体降低了WSNs的能量消耗,能有效提高路径QoS时延性能和延长网络生命周期。

主程序代码如下: 
%% GPSR路由算法改进
%%所有传感器节点分配消息发送到目的地
clear all;close all ;clc;%清除变量
randn('state', sum(100*clock));
%% ------------------参数设置开始------------------------------
area_length = 100;%区域
area_wide = 100;%区域
Range = 20;%节点最大传递范围
node_energy=100;%节点能源
node_down=0.4;%节点能量衰减系数
num_node = 60;  %节点数
node_near=0.3;%节点紧致度,也即节点间距离不能小于0.3*Range
sent_number=20;
%% ------------------参数设置结束------------------------------
%% --------------------坐标设置开始----------------------------
%% 计算出目标节点坐标、源节点坐标、各路由节点几何位置
node=node_position(area_length,area_wide,num_node,node_energy,Range,node_near);

% 计算距离表
Dtable=distance_table(node);
%计算拓扑结构表
Ttable=topo_table(node,Range,Dtable);
x=1:num_node;
Ttable(x).topolopy;
RNG_Ttable=RNG_topology(node,Dtable,Ttable);
%% ----------------------坐标设置结束--------------------------
%% -------------------计算距离表和拓扑关系----------------------

%% -------------------贪婪算法开始-------------
route_length=zeros(sent_number,1);
for k1=1:sent_number
    %随机生成源节点、目标节点
    s1=randperm(num_node);
    v1=find(s1==1);%源节点
    v2=find(s1==2);%目标节点
    %确定源节点、目标节点
    for i=1:num_node
        node(i).class=0;
        if i==v1
            node(i).class=1;
            number_source=i;
        end
        if i==v2
            node(i).class=2;
            number_dem=i;
        end
    end
    %计算距离
    distance_s2d=Dtable(number_source,number_dem);%距离初始化
    route=[number_source];%路径初始化
    Ttable01=Ttable;%临时拓扑赋值,防止搞坏原始拓扑集
    iter_number=0;
    %% GPRS主函数
    while distance_s2d~=0
        %% 判断死链
        if isempty(route)
            disp('能量耗尽,无法产生路由路径');
            break;
        end
        
        curr_node=route(end);%路径当前最后一个节点
        curr_topolopy=Ttable01(curr_node).topolopy;%获取当前拓扑相邻集合
        a03=numel(find(curr_topolopy==number_dem));
        if a03>0%存在
            route=[route number_dem];
            break;
        end
        
        %% ------------------删除curr_topolopy中属于route的节点开始-----
        n=length(route);%计算route长度
        for k=1:n
            v01=find(curr_topolopy==route(k));%route(k)是不是curr_topolopy的成员
            if numel(v01)>0%是成员
                curr_topolopy(v01)=[];%删除该元素
            end
        end
        %% ------------------删除curr_topolopy中属于route的节点结束-----
        %% ------------------删除curr_topolopy中属于比route(end)离目的节点距离远的开始-----
        distance_route_end=Dtable(route(end),number_dem);
        distance_topolopy=Dtable(curr_topolopy,number_dem);
        v4=find(distance_topolopy<distance_route_end);%找出距离小于当前节点的节点
        curr_topolopy=curr_topolopy(v4);%更新拓扑相邻集合
        %% ------------------删除curr_topolopy中属于比route(end)离目的节点距离远的结束-----
        if ~isempty(curr_topolopy)%拓扑相邻集合非空就找下
            curr_distance=Dtable(curr_topolopy,number_dem);%获取当前拓扑相邻集合与目的地节点距离集合
            [dis01,index01]=min(curr_distance);%排序
            
            next_node=curr_topolopy(index01(1));
            route=[route next_node];
            distance_s2d=Dtable(number_source,route(end));%重新计算距离
            
        else%如果是空的,进入 模式
            s4=RNG_Ttable(route(end),:);
            v4=find(s4==1);
            if numel(v4)>0
                s5=randperm(numel(v4));
                v5=find(s5==1);
                next_node=v4(v5);
                route=[route next_node];
                distance_s2d=Dtable(number_source,route(end));%重新计算距离
            else
                %% 从倒数第二个路径点的拓扑相邻集合删除当前这节点
                if length(route)>=2
                    a01=Ttable01(route(end-1)).topolopy;%上一个节点
                    a01(find(a01==curr_node))=[];
                    Ttable01(route(end-1)).topolopy=a01;
                    %% 从当前路径中删除当前路径点
                    route(end)=[];%删掉最后一个
                else
                    disp('能量耗尽,无法产生路由路径');
                    break;
                end
            end
        end
        iter_number=iter_number+1;
    end
    disp('route of GPRS')
    route
    %% 更新节点能量
    [k31,k32]=size(route);
    for i=1:k32
        b01=node_down*node_energy;
        node(route(i)).energy=node(route(i)).energy-b01;
    end
    %% 更新拓扑表
    Ttable=topo_table(node,Range,Dtable);
    %% 更新RNG_topology
    % RNG_Ttable=RNG_topology(node,Dtable,Ttable);%这个太慢,因为有多层嵌套循环,计算距离,运算量太大
    RNG_Ttable=RNG_topology_opt(node,RNG_Ttable);
    %绘图
    s='route of GPRS';
    %绘制路由图
    draw_GPRS_route(node,route,Range,s);
    route_length(k1)=length(route);
end

%% -------------------贪婪算法结束-------------
route_length

程序结果: 

参考文献:

1.改进的GPSR模型及其仿真分析,吴三斌,王小明,杨 涛,付 红

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

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

相关文章

高质量简历模板网站,免费、免费、免费

你们在制作简历时&#xff0c;是不是基本只关注两件事&#xff1a;简历模板&#xff0c;还有基本信息的填写。 当你再次坐下来更新你的简历时&#xff0c;可能会发现自己不自觉地选择了那个“看起来最好看的模板”&#xff0c;填写基本信息&#xff0c;却没有深入思考如何使简历…

基于 Docker 部署 Pingvin Share 文件共享平台

一、Pingvin Share 介绍 Pingvin Share 简介 Pingvin Share 是自托管文件共享平台&#xff0c;是 WeTransfer 的替代方案。 Pingvin Share 特点 在 2 分钟内启动您的实例使用可通过链接访问的文件创建共享没有文件大小限制&#xff0c;只有你的磁盘是你的限制设置共享到期时间…

C++11新特性:final/override控制

override关键字 用于显式标识一个成员函数&#xff08;通常是虚函数&#xff09;是在派生类中重写&#xff08;覆盖&#xff09;了基类中的虚函数。这有助于提高代码的可读性&#xff0c;同时在编译时提供了检查&#xff0c;确保派生类中的函数确实是在基类中有对应的虚函数。…

GZ036 区块链技术应用赛项赛题第3套

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;3卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 新能源作为新兴领域&#xff0c;产业呈现碎片化与复杂化的特性&#xff0c;逐渐出现管理困难、供应链金融、可信监管与数…

论文阅读_训练大模型用于角色扮演

英文名称: Character-LLM: A Trainable Agent for Role-Playing 中文名称: 角色-LLM&#xff1a;训练Agent用于角色扮演 文章: [https://arxiv.org/abs/2310.10158](https://arxiv.org/abs/2310.10158) 作者: Yunfan Shao, Linyang Li, Junqi Dai, Xipeng Qiu 机构: 复旦大学…

军事智能中的深度强化学习不同于传统的深度强化学习

在军事智能中&#xff0c;“诡”和“诈”是两个最重要的概念。 “诡”变指的是智能体通过采取一些不可预测或复杂的变化策略来获得优势。诡变可能包括逃避对手的观察或引诱对手采取不利的行动。智能体可以使用诡变来欺骗对手&#xff0c;使其做出错误的决策或暴露其策略。 “诈…

动态规划最后一天(回文串)

目录 647. 回文子串 看到题目的第一想法 看到代码随想录之后的想法 自己实现过程中遇到的困难(看代码) 516.最长回文子序列 看到题目的第一想法 看到代码随想录之后的想法 自己实现过程中遇到的困难(看代码) 647. 回文子串 力扣题目链接…

【第七在线】智能商品计划:重塑服装行业的供应链管理

在当今快速变化的市场环境中&#xff0c;供应链管理已成为企业成功的关键因素之一。尤其在服装行业&#xff0c;供应链的效率、灵活性和透明度直接影响着企业的竞争力和盈利能力。随着技术的发展&#xff0c;智能商品计划正逐渐成为重塑供应链管理的强大工具。 一、智能商品计划…

什么是JMeter?我们为什么要用JMeter做性能测试

什么是JMeter&#xff1f;我们为什么要用JMeter做性能测试 什么是JMeter&#xff1f;为什么选择JMeterJMeter的优点JMeter是如何工作的 什么是JMeter&#xff1f; Apache JMeter TM是纯Java开源软件&#xff0c;最初由Apache软件基金会的Stefano Mazzocchi开发&#xff0c;旨在…

使用Transformers微调基于BERT模型做中文命名实体识别任务

注意版本!! python == 3.8.6 torch == 1.10.0 transformers == 4.36.2 datasets == 2.15.0 import json # 数据集下载地址:https://www.cluebenchmarks.com/introduce.html # 细粒度命名实体识别->下载# 将数据转为 BIO 标注形式 def dimension_label(path, save_p…

linux 之 ln 命令

linux 之 ln 命令 在Linux中&#xff0c;ln 命令用于创建文件或目录的链接。它有两种主要类型的链接。 硬链接&#xff08;Hard Links&#xff09; 硬链接实际上是原始文件的另一个引用&#xff0c;指向同一个inode&#xff08;索引节点&#xff09;&#xff0c;这意味着它们共…

如何在Linux上部署Docker容器

一、什么是docker&#xff1f; Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不…

方法调用(java)

方法调用的基本内存原理&#xff1a;先进后出 基本数据类型&#xff1a;整数类型、浮点数类型、布尔类型、字符类型&#xff1b;数据类型存储在自己的空间 引用数据类型&#xff1a;除了以上数据类型都是&#xff1b;数据值是存储在其他空间中&#xff0c;变量中存储的是地址…

sprignboot电商书城源码

运行环境: jdk1.8,maven,mysql 项目技术: 后台主要是springbootmybatisshirojsp&#xff0c;前端界面主要使用bootstrap框架搭建&#xff0c;并使用了ueditor富文本编辑器、highcharts图表库。 有需要的可以联系我。 功能介绍&#xff1a; 该系统分为前台展示和后台管理两…

[docker] Docker 网络

一、Docker 网络 1.1 Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认…

【量化交易】股市舞者:小明的撮合交易之旅

马西森AES撮合交易系统 在繁华的都市中&#xff0c;小明&#xff0c;一个普通的青年&#xff0c;刚刚赚到了人生的第一桶金——20万。这笔意外的财富&#xff0c;点燃了他对股市的强烈兴趣。他开始如饥似渴地学习金融知识&#xff0c;钻研各种交易策略。 一天&#xff0c;小…

C#使用IsLeapYear方法判断指定年份是否为闰年

目录 一、判断指定年是否为闰年的2个方法 1.使用IsLeapYear方法判断指定年份是否为闰年 2.使用自定义的算法计算指定年份是否为闰年 二、示例 1.方法1的实例 2.方法2的实例 一、判断指定年是否为闰年的2个方法 1.使用IsLeapYear方法判断指定年份是否为闰年 使用IsLeapY…

Android小工具:利用解构来简化Cursor内容的读取

Cursor这个类是Android开发者难以避免的&#xff0c;比如数据库、ContentResolver内容的读取&#xff0c;但通过这个类读取内容非常的繁琐&#xff0c;针对要读取的每一个字段都会有这样一段代码&#xff1a; int idIndex cursor.getColumnIndex("id"); //获取字段…

Vue+OpenLayers7:OpenLayers地图默认使用什么投影? 要如何更改OpenLayers地图的投影?

返回目录:Vue+OpenLayers7 OpenLayers地图默认使用什么投影? 在回答这个问题之前,我们需要了解什么是地图投影。 什么是地图投影? 地图投影是将球面地图上的三维地理坐标系(经纬度)转换成平面地图上的二维坐标系的过程。由于地球是一个近似的椭球体,而平面地图是一个…

Linux的奇妙冒险———vim的用法和本地配置

vim的用法和本地配置 一.vim的组成和功能。1.什么是vim2.vim的多种模式 二.文本编辑&#xff08;普通模式&#xff09;的快捷使用1.快速复制&#xff0c;粘贴&#xff0c;剪切。2.撤销&#xff0c;返回上一步操作3.光标的控制4.文本快捷变换5.批量化操作和注释 三.底行模式四.v…