近期再写一个网络仿真器,里面參考了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. 将一个类写成WebService服务的形式

    WebService是一种跨编程语言和跨操作系统平台的远程调用技术,主要解决不同语言写的应用程序之间.不同平台(linux/windows/andrid)之间的通信,即异构系统之间的通信. 常用的天气 ...

  2. Loadrunner--参数化知识点及参数池策略

    一.为何进行脚本参数化? 脚本在录制的时候,记录的参数都是常量值,这样,虚拟用户在执行同一个脚本,向服务器发送请求时,使用的都是同一个参数值,与实际不符.所以使用参数化技术. 二.参数化的逻辑? 对脚 ...

  3. IDEACould not autowire. No beans of 'xxxMapper' type found.

    作为一名刚开始使用idea的新手,最近在使用maven+springMVC框架时遇到了这样一个问题:Could not autowire. No beans of 'xxxMapper' type f ...

  4. [求助]linux同一目录可否挂载多个数据盘?

    https://bbs.aliyun.com/read/281222.html?pos=20

  5. AUC(Area Under roc Curve )计算及其与ROC的关系

    转载: http://blog.csdn.net/chjjunking/article/details/5933105 让我们从头说起,首先AUC是一种用来度量分类模型好坏的一个标准.这样的标准其实有 ...

  6. swift Reflection(字典转模型)变量继承本类类名解决办法

    class IWStatus: Reflect { var source: NSString! var created_at: NSString! var idstr: NSString! var u ...

  7. vue2.0 踩坑记录之组件

    - did you register the component correctly? For recursive components, make sure to provide the " ...

  8. Python代码优化及技巧笔记(一)

    前言 这里是记录一些本人在开发过程中遇到的一些细节问题.与君共勉. 版权说明 著作权归作者全部.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Coding-Naga链接:http://bl ...

  9. 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【四】使用CUBLAS加速计算人脸向量的余弦距离

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  10. POJ 2642 The Brick Stops Here 0-1背包

    poj: http://poj.org/problem?id=2642 大意: 给出n(n<=200)块黄铜合金,还有它们的浓度和价钱.给出若干个个询问使它们在n块中取 M 块 使得这M块合金的 ...