最近再写一个网络仿真器,里面参考了Max-MinFairness算法,这是一种比较理想、公平的带宽分配算法。其思路主要如下:首先是算法的准备,考察某一时刻的网络中所有的flow,由于每条flow都有其各个link,因此可以得到各个link上所有流经的flow,然后开始迭代,各个link都把capacity平均分给所有流经的flow,接着每条flow的速度就等于其最小link分配的带宽,然后每条link的剩余带宽就等于link的capacity减去所有流经的flow的速度的总和,再然后把link的剩余带宽作为capacity重新进行上面的迭代,直至所有flow在迭代中获得的带宽都小于一个阈值时,算法结束,带宽分配完成。

让我们来分析这个算法并考虑如何加速该算法的执行速度。首先,对于一些bottleneck的link,流经其的flow早早就不能分配带宽了,因此如果发现在某个迭代中某条link能够分配的带宽已经小于阈值,那么在下一轮迭代,所有流经其的flow都不再考察,即使某些flow并不是以该link为bottleneck,因此,算法结束的条件可以改为当所有flow都不再考察的时候。这样对不对呢,让我们分析一下。以该link为bottleneck的flow自然不用说了,所谓的bottleneck就是能够获取的带宽最小的link,那么最小的link已经不能分配带宽了,该flow自然不再考察。但不是以该link作为bottleneck的flow呢,它们有更小带宽的link,但是如果该link不是你的bottleneck,已经不能分配带宽了,那就刚不用说更小带宽的link了,所以这些flow也应该不再考察。好,算法的讲解和分析就到这儿了,下面就是算法的实现,笔者采用的Java语言。

public Map<Integer, List<TrafficState>> run() {Map<Integer, List<TrafficState>> resultMap = new HashMap<Integer, List<TrafficState>>();int current = 0;// PrintWriter resultWriter = new PrintWriter(resultFileName);while (current < runtime) {List<Integer> runningFlowList = new ArrayList<Integer>();// the first traverse,add the new flows and remove the shopped flowfor (int i = 0; i < graph.traffics.size(); i++) {Traffic currentTraffic = graph.traffics.get(i);int starttime = currentTraffic.start;if (starttime <= current && !currentTraffic.isStopped) {List<Integer> linksList = currentTraffic.links;if (currentTraffic.totlesize == 0) {// start a new flowcurrentTraffic.totlesize = currentTraffic.flowsize;currentTraffic.leftsize = currentTraffic.totlesize;for (Integer linkno : linksList) {graph.links.get(linkno).trafficList.add(currentTraffic);}}// calculate the transfer bytes in a epochcurrentTraffic.epochsize = currentTraffic.speed* ((float) period / 1000);currentTraffic.leftsize -= currentTraffic.epochsize;if (currentTraffic.leftsize <= 0|| currentTraffic.end == current) {// no more flowsize or time is up,stop itcurrentTraffic.isStopped = true;for (Integer linkno : linksList) {graph.links.get(linkno).trafficList.remove(currentTraffic);}} elserunningFlowList.add(i);}}// print the measurementif (printTimeSet.contains(current)) {List<TrafficState> stateList = new ArrayList<TrafficState>();for (Traffic traffic : graph.traffics) {//not the stop flows and the start ones just nowif (!traffic.isStopped && traffic.totlesize != 0&& traffic.speed != 0) {TrafficState state = new TrafficState();state.setBytes(traffic.epochsize);state.setDestination(traffic.destination);state.setSource(traffic.source);state.setThruput(traffic.speed);String pathString = traffic.source;int lastNode = Integer.parseInt(traffic.source);for (Integer linkno : traffic.links) {if (lastNode == graph.links.get(linkno).source) {pathString += ","+ graph.links.get(linkno).target;lastNode = graph.links.get(linkno).target;} else {pathString += ","+ graph.links.get(linkno).source;lastNode = graph.links.get(linkno).source;}// pathString += "," +// graph.links.get(linkno).target;}state.setPathString(pathString);state.setStarttime(traffic.start);state.setFlowsize(traffic.flowsize);state.setEndtime(traffic.end);stateList.add(state);}}resultMap.put(current, stateList);}// initialize all the links and trafficsfor (Link link : graph.links) {link.leftCapacity = link.capacity;}for (Traffic traffic : graph.traffics) {traffic.speed = 0;}Set<Integer> finishedTrafficSet = new HashSet<Integer>();// the second traverse,set the throughput of each flow in next// iterationwhile (finishedTrafficSet.size() < runningFlowList.size()) {for (int i = 0; i < runningFlowList.size(); i++) {if (!finishedTrafficSet.contains(runningFlowList.get(i))) {Traffic currentTraffic = graph.traffics.get(runningFlowList.get(i));currentTraffic.increSpeed = Float.MAX_VALUE;Link minLink = null;for (Integer linkno : currentTraffic.links) {Link currentLink = graph.links.get(linkno);int existFlowNum = 0;// the number of exist flowsfor (Traffic traffic : currentLink.trafficList) {if (traffic.increSpeed != 0|| traffic.speed == 0) {existFlowNum++;}}float currentLinkSpeed = (float) currentLink.leftCapacity/ (float) existFlowNum;if (currentLinkSpeed < currentTraffic.increSpeed) {currentTraffic.increSpeed = currentLinkSpeed;minLink = currentLink;}}if (currentTraffic.increSpeed > 5)currentTraffic.speed += currentTraffic.increSpeed;else {currentTraffic.increSpeed = 0;if (minLink != null) {for (Traffic traffic : minLink.trafficList) {traffic.increSpeed = 0;finishedTrafficSet.add(graph.traffics.indexOf(traffic));}} elsefinishedTrafficSet.add(runningFlowList.get(i));}}}// link left capacity decrease the traffic increase throughputfor (Link link : graph.links) {for (Traffic traffic : link.trafficList) {link.leftCapacity -= traffic.increSpeed;}}}current += period;}// resultWriter.close();return resultMap;}

Max-Min Fairness带宽分配算法相关推荐

  1. Max-Min 带宽公平分配算法

    Max-Min 带宽公平分配算法 算法的核心思想是每条通路平等地享有分配带宽的权利. 通路上的瓶颈线路决定该通路上路径的最大分配带宽.(如果有M条通道经过该通路,则每条通道的带宽为 通路带宽/M) 形 ...

  2. python分配红包程序_Python版微信红包分配算法

    Python版微信红包分配算法 发布于 2015-05-08 10:54:23 | 151 次阅读 | 评论: 0 | 来源: 网友投递 Python编程语言Python 是一种面向对象.解释型计算机 ...

  3. 嵌入式操作系统内核原理和开发(最快、最优、最差内存分配算法)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们说到了基于链表的内存分配算法.但是之前我们也说过,其实内存分配一般有三个原则,最快.最 ...

  4. 弱网优化,GCC 动态带宽评估算法(内附详细公式)

    通过上次的<RTC 系统音视频传输弱网对抗技术概览>,我们知道 RTC 的三大核心指标为实时性.清晰度.流畅度.在整个通话过程中核心表现达标,才能给用户一个基本的良好体验.关注[融云全球互 ...

  5. java红包正态分布_红包分配算法

    微信红包的分配算法,在知乎上已经有人讨论过了,详见<微信红包的随机算法是怎样实现的?>.基本的原则是:红包分配的钱数满足截尾正态随机数分布. 大致为在截尾正态分布中取随机数,并用其求和数除 ...

  6. 操作系统-动态内存分配算法

    内存分配算法 1.首次适应算法(FF) 2.循环首次适应算法(NF) 3.最佳适应算法(BF) 4.最坏适应算法(WF) 本程序使用前端技术实现(html+css+JavaScript) 新建以下文件 ...

  7. WebRTC的带宽分配(1): 流级别分配

    今天来聊一聊WebRTC的带宽分配(BWA,Bandwidth Allocation),带宽分配是将带宽估计(BWE,Bandwidth Estimation)的结果分配到不同的流上面. 因此带宽分配 ...

  8. 【频谱分配】基于频谱空洞预留算法的频谱分配算法的matlab仿真

    1.软件版本 MATLAB2013a 2.本算法理论知识 基于概率切换和最小化概率切换的频谱切换算法,由于过多的考虑了资源的合理利用,使得次用户的不切换概率并大于等于的情况,从而导致对应的次用户的服务 ...

  9. 基于顺序搜索的动态分区分配算法模拟内存动态分配--最佳适应算法(best fit,BF)

    BF算法.男朋友算法,哈哈 要实现动态分区分配,需要考虑三个方面的问题.分别是数据结构.分区分配算法.分区的分配与回收操作. 首数据结构 这里我们使用的是空闲分区链,采用双向链表表示空闲分区. 具体实 ...

最新文章

  1. 七基于Fourinone实现MQ demo
  2. Deploying Windows Mobile 6 with Exchange Server 2007 白皮书
  3. 虚拟主机6大骗术,站长朋友小心了
  4. VSS2005 添加文件夹方法!
  5. lambda 序列化_Lambda,会序列化吗?
  6. 浅谈 MySQL 的存储引擎(表类型)
  7. 问号在c语言中运算符,C# 运算符 ?、??、?: 各种问号的用法和说明
  8. Cow Contest【最短路-floyd】
  9. java 监控对象是什么_多线程-Java中的对象监视器是什么意思? 为什么要使用这个词?...
  10. 希尔排序法(插入排序的改进版本)
  11. arcengine中测量两个geometry的距离
  12. 使用WireShark抓包对方QQ的ip地址(通过QQ电话)
  13. android 任务管理器
  14. OpenCv图像处理之Mat类使用
  15. 本地颁发 SSL 证书,并开启 https 服务调试
  16. 基于NeRF的APP上架苹果商店!照片转3D只需一部手机,网友们玩疯了
  17. linux系统查看进程
  18. 两种方法编写圆的周长和面积
  19. 利用动网论坛dvBBS漏洞上传webshell
  20. Nvidia显卡命名的各部分的含义

热门文章

  1. 苹果电脑与xcode的快捷键
  2. “no source“: Error: command-line: #564: cannot open embedded assembler outpu
  3. 目标检测, 实例分割, 图像分类, panoptic segmentation文献
  4. flyway最佳生产实践
  5. 图片加水印怎么加,快速图片加水印?
  6. python中的matplotlib绘图
  7. php相册排版,照片拼图在线制作 自带多种照片拼图模板,自由排版将多张照片合成一张...
  8. 数据结构 插入排序(InsertionSort Sort) 详解 附C++代码实现:
  9. 黑马头条项目-Vue-day9-文章详情模块、关注与取消关注,点赞和喜欢功能
  10. 利用Nginxcp为cPanel/WHM服务器开启nginx支持