近期再写一个网络仿真器,里面參考了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 flow
for (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 flow
currentTraffic.totlesize = currentTraffic.flowsize;
currentTraffic.leftsize = currentTraffic.totlesize;
for (Integer linkno : linksList) {
graph.links.get(linkno).trafficList
.add(currentTraffic);
}
}
// calculate the transfer bytes in a epoch
currentTraffic.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 it
currentTraffic.isStopped = true;
for (Integer linkno : linksList) {
graph.links.get(linkno).trafficList
.remove(currentTraffic);
}
} else
runningFlowList.add(i);
}
}
// print the measurement
if (printTimeSet.contains(current)) {
List<TrafficState> stateList = new ArrayList<TrafficState>();
for (Traffic traffic : graph.traffics) {
//not the stop flows and the start ones just now
if (!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 traffics
for (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
// iteration
while (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 flows
for (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));
}
} else
finishedTrafficSet.add(runningFlowList.get(i));
}
}
}
// link left capacity decrease the traffic increase throughput
for (Link link : graph.links) {
for (Traffic traffic : link.trafficList) {
link.leftCapacity -= traffic.increSpeed;
}
}
}
current += period;
}
// resultWriter.close();
return resultMap;
}

Max-Min Fairness带宽分配算法的更多相关文章

  1. 关于STL库中的max min swap

    嗯...   不得不说c++中的STL库是一个神奇的东西   可以使你的代码显得更加简洁....   今天就只讲STL中的三个鬼畜:   max       min       swap   具体操作 ...

  2. TLFS 内存分配算法详解

    文章目录 1. DSA 背景介绍 1.1 mmheap 1.2 mmblk 2. TLFS 原理 2.1 存储结构 2.2 内存池初始化 2.3 free 2.4 malloc 参考资料 1. DSA ...

  3. webrtc中的带宽自适应算法

    转自:http://www.xuebuyuan.com/1248366.html webrtc中的带宽自适应算法分为两种: 1, 发端带宽控制, 原理是由rtcp中的丢包统计来动态的增加或减少带宽,在 ...

  4. 6.组函数(avg(),sum(),max(),min(),count())、多行函数,分组数据(group by,求各部门的平均工资),分组过滤(having和where),sql优化

     1组函数 avg(),sum(),max(),min(),count()案例: selectavg(sal),sum(sal),max(sal),min(sal),count(sal) from ...

  5. 从集合中查找最值得方法——max(),min(),nlargest(),nsmallest()

    从集合中查找最值得方法有很多,常用的方法有max(),min(),nlargest(),nsmallest()等. 一.max()和min() 1.1 入门用法 直接使用max(),min(),返回可 ...

  6. day12 max min zip 用法

    max min ,查看最大值,最小值 基础玩法 l = [1,2,3,4,5] print(max(l)) print(min(l)) 高端玩法 默认字典的取值是key的比较 age_dic={'al ...

  7. max,min,Zip函数(十一)

    zip函数,拉链,传两个有序的参数,将他们一一对应为元祖形式 max,min比较默认比较一个元素,处理的是可迭代对象,相当于for循环取出每个元素进行比较,注意:不同类型之间不可比较 #!/usr/b ...

  8. group by与avg(),max(),min(),sum()函数的关系

    数据库表: create table pay_report(     rdate varchar(8),     --日期     region_id varchar(4),    --地市      ...

  9. Kafka集群副本分配算法解析

    副本分配算法如下: 将所有N Broker和待分配的i个Partition排序. 将第i个Partition分配到第(i mod n)个Broker上. 将第i个Partition的第j个副本分配到第 ...

随机推荐

  1. Docker---(9)Docker中容器无法停止无法删除

    原文:Docker---(9)Docker中容器无法停止无法删除 版权声明:欢迎转载,请标明出处,如有问题,欢迎指正!谢谢!微信:w1186355422 https://blog.csdn.net/w ...

  2. maven的pom.xml配置文件讲解

    <project xmlns="http://maven.apache.org/POM/4.0.0 "     xmlns:xsi="http://www.w3.o ...

  3. PatentTips - Use of multiple virtual machine monitors to handle privileged events

    BACKGROUND OF THE INVENTION A conventional virtual-machine monitor (VMM) typically runs on a compute ...

  4. 多校连萌15-8-12#A

    #include <cstdio> #include <iostream> #include <algorithm> #include <queue> ...

  5. swift 利用 Reflect(字典转模型)

    1.  导入Reflect(字典转模型)框架 2. 让它继承Reflect这个类,如下代码所示: class IWUser: Reflect { /** *  用户的ID */ var idstr:N ...

  6. finish() OnDestroy() system.exit()

    1 finish()方法:activity动作完成的时候, 或者Activity需要关闭的时候, 调用此方法. 2 当你调用此方法的时候,系统只是将最上面的Activity移出了栈,并没有及时的调用o ...

  7. [PReact] Reduce the Size of a React App in Two Lines with preact-compat

    Not every app is greenfield, and it would be a shame if existing React apps could not benefit from t ...

  8. js课程 2-7 for-in循环怎么使用

    js课程 2-7 for-in循环怎么使用 一.总结 一句话总结:用的是in的作用加上for的作用,相当于一个组合技. 1.js中in运算符的作用是什么? 判断一个元素是否在一个集合或者对象中 1.a ...

  9. [AngularFire2] Building an Authentication Observable Data Service

    After successfully login, we want something help to check whether user has already login or not. And ...

  10. ios开发图层layer与核心动画二:CATransform3D,CAlayear和UIView区别,layer的position和anchorpoint

    一:CATransform3D #import "ViewController.h" @interface ViewController () @property (weak, n ...